## gskdns

gskdns

## Synopsis

    #define             GSK_DNS_PORT
                        GskDnsMessage;
                        GskDnsResourceRecord;
                        GskDnsQuestion;
    enum                GskDnsResourceRecordType;
    enum                GskDnsResourceClass;
    #define             GSK_DNS_SERIAL_LESS_THAN            (serial_1, serial_2)
    GskDnsResourceRecord * gsk_dns_rr_new_generic           (GskDnsMessage *allocator,
                                                             const char *owner,
                                                             guint32 ttl);
    GskDnsResourceRecord * gsk_dns_rr_new_a                 (const char *owner,
                                                             guint32 ttl,
                                                             const guint8 *ip_address,
                                                             GskDnsMessage *allocator);
    GskDnsResourceRecord * gsk_dns_rr_new_aaaa              (const char *owner,
                                                             guint32 ttl,
                                                             const guint8 *address,
                                                             GskDnsMessage *allocator);
    GskDnsResourceRecord * gsk_dns_rr_new_ns                (const char *owner,
                                                             guint32 ttl,
                                                             const char *name_server,
                                                             GskDnsMessage *allocator);
    GskDnsResourceRecord * gsk_dns_rr_new_cname             (const char *owner,
                                                             guint32 ttl,
                                                             const char *canonical_name,
                                                             GskDnsMessage *allocator);
    GskDnsResourceRecord * gsk_dns_rr_new_ptr               (const char *owner,
                                                             guint32 ttl,
                                                             const char *ptr,
                                                             GskDnsMessage *allocator);
    GskDnsResourceRecord * gsk_dns_rr_new_mx                (const char *owner,
                                                             guint32 ttl,
                                                             int preference,
                                                             const char *mail_host,
                                                             GskDnsMessage *allocator);
    GskDnsResourceRecord * gsk_dns_rr_new_hinfo             (const char *owner,
                                                             guint32 ttl,
                                                             const char *cpu,
                                                             const char *os,
                                                             GskDnsMessage *allocator);
    GskDnsResourceRecord * gsk_dns_rr_new_soa               (const char *owner,
                                                             guint32 ttl,
                                                             const char *mname,
                                                             const char *rname,
                                                             guint32 serial,
                                                             guint32 refresh_time,
                                                             guint32 retry_time,
                                                             guint32 expire_time,
                                                             guint32 minimum_time,
                                                             GskDnsMessage *allocator);
    GskDnsResourceRecord * gsk_dns_rr_new_txt               (const char *owner,
                                                             guint32 ttl,
                                                             const char *text,
                                                             GskDnsMessage *allocator);
    void                gsk_dns_rr_free                     (GskDnsResourceRecord *record);
    GskDnsResourceRecord * gsk_dns_rr_copy                  (GskDnsResourceRecord *record,
                                                             GskDnsMessage *allocator);
    GskDnsResourceRecord * gsk_dns_rr_new_wildcard          (const char *owner,
                                                             guint ttl,
                                                             GskDnsMessage *allocator);
    GskDnsQuestion *    gsk_dns_question_new                (const char *query_name,
                                                             GskDnsResourceRecordType query_type,
                                                             GskDnsResourceClass query_class,
                                                             GskDnsMessage *allocator);
    GskDnsQuestion *    gsk_dns_question_copy               (GskDnsQuestion *question,
                                                             GskDnsMessage *allocator);
    void                gsk_dns_question_free               (GskDnsQuestion *question);
    GskDnsResourceRecord * gsk_dns_rr_text_parse            (const char *record,
                                                             const char *last_owner,
                                                             const char *origin,
                                                             char **err_msg,
                                                             GskDnsMessage *allocator);
    char *              gsk_dns_rr_text_to_str              (GskDnsResourceRecord *rr,
                                                             const char *last_owner);
    char *              gsk_dns_question_text_to_str        (GskDnsQuestion *question);
    void                gsk_dns_rr_text_write               (GskDnsResourceRecord *rr,
                                                             GskBuffer *out_buffer,
                                                             const char *last_owner);
    enum                GskDnsResponseCode;
    GskDnsMessage *     gsk_dns_message_new                 (guint16 id,
                                                             gboolean is_request);
    GskDnsMessage *     gsk_dns_message_parse_buffer        (GskBuffer *buffer);
    GskDnsMessage *     gsk_dns_message_parse_data          (const guint8 *data,
                                                             guint length,
                                                             guint *bytes_used_out);
    void                gsk_dns_message_write_buffer        (GskDnsMessage *message,
                                                             GskBuffer *buffer,
                                                             gboolean compress);
    GskPacket *         gsk_dns_message_to_packet           (GskDnsMessage *message);
    void                gsk_dns_message_append_question     (GskDnsMessage *message,
                                                             GskDnsQuestion *question);
    void                gsk_dns_message_append_answer       (GskDnsMessage *message,
                                                             GskDnsResourceRecord *answer);
    void                gsk_dns_message_append_auth         (GskDnsMessage *message,
                                                             GskDnsResourceRecord *auth);
    void                gsk_dns_message_append_addl         (GskDnsMessage *message,
                                                             GskDnsResourceRecord *addl);
    void                gsk_dns_message_remove_question     (GskDnsMessage *message,
                                                             GskDnsQuestion *question);
    void                gsk_dns_message_remove_answer       (GskDnsMessage *message,
                                                             GskDnsResourceRecord *answer);
    void                gsk_dns_message_remove_auth         (GskDnsMessage *message,
                                                             GskDnsResourceRecord *auth);
    void                gsk_dns_message_remove_addl         (GskDnsMessage *message,
                                                             GskDnsResourceRecord *addl);
    void                gsk_dns_message_unref               (GskDnsMessage *message);
    void                gsk_dns_message_ref                 (GskDnsMessage *message);
    void                gsk_dns_dump_message_fp             (GskDnsMessage *message,
                                                             FILE *fp);
    void                gsk_dns_dump_question_fp            (GskDnsQuestion *question,
                                                             FILE *fp);
    gboolean            gsk_dns_parse_ip_address            (const char **pat,
                                                             guint8 *ip_addr_out);
    gboolean            gsk_test_domain_name_validity       (const char *domain_name);

## Description

## Details

### GSK_DNS_PORT

    #define             GSK_DNS_PORT

The default TCP and UDP port on this DNS is transacted. Nameservers, unlike mots servers, basically must be on this port, since the protocol has no way to specify which port of a nameserver to try.

### GskDnsMessage

    typedef struct {
      /* Header: fixed data about all queries */
      guint16       id;       /* used by requestor to match queries and replies */

      /* Is this a query or a response? */
      guint16       is_query : 1;

      guint16       is_authoritative : 1;
      guint16       is_truncated : 1;

      /* [Responses only] the `RA bit': whether the server is willing to provide
       *                                recursive services. (cf 1034, 4.3.1)
       */
      guint16       recursion_available : 1;

      /* [Queries only] the `RD bit': whether the requester wants recursive
       *                              service for this queries. (cf 1034, 4.3.1)
       */
      guint16       recursion_desired : 1;

      /* Question: Carries the query name and other query parameters. */
      /* `qtype' (names are from RFC 1034, section 3.7.1): the query type */
      GSList       *questions;	/* of GskDnsQuestion */

      /* Answer: Carries RRs which directly answer the query. */
      GskDnsResponseCode error_code;
      GSList       *answers;	/* of GskDnsResourceRecord */

      /* Authority: Carries RRs which describe other authoritative servers.
       *            May optionally carry the SOA RR for the authoritative
       *            data in the answer section.
       */
      GSList       *authority;	/* of GskDnsResourceRecord */

      /* Additional: Carries RRs which may be helpful in using the RRs in the
       *             other sections.
       */
      GSList       *additional;	/* of GskDnsResourceRecord */
    } GskDnsMessage;

This structure encapsulates a DNS packet, either a query or a response.

Many of the field descriptions are taken from RFC 1035, Section 4.1.1.

guint16 `id`; | this number is used by the client to match together queries and responses. So a server's responses must set this to the same value as for the query.
guint16 `is_query` : 1; | whether the Message is a query. Otherwise, it is a response.
guint16 `is_authoritative` : 1; | only for responses. Whether the DNS server sending the message is the authority for the first entry in the answer section which matches the query name, ie the owner of the first entry in the question section.
guint16 `is_truncated` : 1; | specifies that this message was truncated due to length greater than that permitted on the transmission channel.
guint16 `recursion_available` : 1; | Recursion Available - this be is set or cleared in a response, and denotes whether recursive query support is available in the name server.
guint16 `recursion_desired` : 1; | Recursion Desired - this bit may be set in a query and is copied into the response. If RD is set, it directs the name server to pursue the query recursively. Recursive query support is optional.
GSList *`questions`; | List of GskDnsQuestion For a query, this is the most important section. Questions are often found in a response; they should just be copies of questions from the corresponding query.
GskDnsResponseCode `error_code`; | in a response, this is a GskDnsResponseCode telling what went wrong, if anything. 0 means "no error".
GSList *`answers`; | In a response, this is a list of GskDnsResourceRecord's. They should lead toward answering the question in the query.
GSList *`authority`; | resource records which give information about authority nameservers relevant to the `answers`.
GSList *`additional`; | resource records which give auxilliary useful information. For example, it is typical to give an address (an A record) for any nameservers (NS records) given in prior sections.

### GskDnsResourceRecord

    typedef struct {
      GskDnsResourceRecordType  type;
      char                     *owner;     /* where the resource_record is found */
      guint32                   time_to_live;
      GskDnsResourceClass       record_class;

      /* rdata: record type specific data */
      union
      {
        /* For GSK_DNS_RR_HOST_ADDRESS and GSK_DNS_CLASS_INTERNET */
        struct
        {
          guint8 ip_address[4];
        } a;

    		/* unsupported */
        /* For GSK_DNS_RR_HOST_ADDRESS and GSK_DNS_CLASS_CHAOS */
        struct
        {
          char *chaos_name;
          guint16 chaos_address;
        } a_chaos;

        /* For GSK_DNS_RR_CNAME, GSK_DNS_RR_POINTER, GSK_DNS_RR_NAME_SERVER */
        char *domain_name;

        /* For GSK_DNS_RR_MAIL_EXCHANGE */
        struct
        {
          guint preference_value; /* "lower is better" */

          char *mail_exchange_host_name;
        } mx;

        /* For GSK_DNS_RR_TEXT */
        char *txt;

        /* For GSK_DNS_RR_HOST_INFO */
        struct
        {
          char *cpu;
          char *os;
        } hinfo;

        /* SOA: Start Of a zone of Authority.
         *
         * Comments cut-n-pasted from RFC 1035, 3.3.13.
         */
        struct
        {
          /* The domain-name of the name server that was the
    	 original or primary source of data for this zone. */
          char *mname;

          /* specifies the mailbox of the
    	 person responsible for this zone. */
          char *rname;

          /* The unsigned 32 bit version number of the original copy
    	 of the zone.  Zone transfers preserve this value.  This
    	 value wraps and should be compared using sequence space
    	 arithmetic. */
          guint32 serial;

          /* A 32 bit time interval before the zone should be
    	 refreshed. (cf 1034, 4.3.5) [in seconds] */
          guint32 refresh_time;

          /* A 32 bit time interval that should elapse before a
    	 failed refresh should be retried. [in seconds] */
          guint32 retry_time;

          /* A 32 bit time value that specifies the upper limit on
    	 the time interval that can elapse before the zone is no
    	 longer authoritative. [in seconds] */
          guint32 expire_time;

          /* The unsigned 32 bit minimum TTL field that should be
    	 exported with any RR from this zone. [in seconds] */
          guint32 minimum_time;
        } soa;

        struct {
          guint8 address[16];
        } aaaa;
    } GskDnsResourceRecord;

An atom of information about a host in the DNS system. The exact type of information depends on `type`, but it may be a pointer to another name (CNAME, PTR), a pointer to another nameserver to query (NS), information about the authoritativeness and timeouts of the response (SOA), or a host's address (A). There are other, rarely used, types of record, too.

GskDnsResourceRecordType `type`; | what type of information this record contains.
char *`owner`; | what host or domain name this record pertains to.
guint32 `time_to_live`; | how long this record should be retained, in seconds.
GskDnsResourceClass `record_class`; | what address domain this record applies to. Almost always 'IN' meaning the internet, or IPv4. (Other systems are now obsolete).
char *`domain_name`; |
char *`txt`; |

### GskDnsQuestion

    typedef struct {
      /* The domain name for which information is being requested. */
      char                     *query_name;

      /* The type of query we are asking. */
      GskDnsResourceRecordType  query_type;

      /* The domain where the query applies. */
      GskDnsResourceClass       query_class;
    } GskDnsQuestion;

A question, asked by a client resolver of a server.

char *`query_name`; | what hostname or domainname is desired.
GskDnsResourceRecordType `query_type`; | what information about the host is wanted.
GskDnsResourceClass `query_class`; | which address namespace this question is about.

### enum GskDnsResourceRecordType

    typedef enum
    {
      /* An `A' record:  the ip address of a host. */
      GSK_DNS_RR_HOST_ADDRESS = 1,

      /* A `NS' record:  the authoritative name server for the domain */
      GSK_DNS_RR_NAME_SERVER = 2,

      /* A `CNAME' record:  indicate another name for an alias. */
      GSK_DNS_RR_CANONICAL_NAME = 5,

      /* A `HINFO' record: identifies the CPU and OS used by a host */
      GSK_DNS_RR_HOST_INFO = 13,

      /* A `MX' record */
      GSK_DNS_RR_MAIL_EXCHANGE = 15,

      /* A `PTR' record:  a pointer to another part of the domain name space */
      GSK_DNS_RR_POINTER = 12,

      /* A `SOA' record:  identifies the start of a zone of authority [???] */
      GSK_DNS_RR_START_OF_AUTHORITY = 6,

      /* A `TXT' record:  miscellaneous text */
      GSK_DNS_RR_TEXT = 16,

      /* A `WKS' record:  description of a well-known service */
      GSK_DNS_RR_WELL_KNOWN_SERVICE = 11,

      /* A `AAAA' record: for IPv6 (see RFC 1886) */
      GSK_DNS_RR_HOST_ADDRESS_IPV6 = 28,

      /* --- only allowed for queries --- */

      /* A `AXFR' record: `special zone transfer QTYPE' */
      GSK_DNS_RR_ZONE_TRANSFER = 252,

      /* A `MAILB' record: matches all mail box related RRs (e.g. MB and MG). */
      GSK_DNS_RR_ZONE_MAILB = 253,

      /* A `*' record:  matches anything. */
      GSK_DNS_RR_WILDCARD = 255

    } GskDnsResourceRecordType;

This is a list of types of information that may be available about some domain names.

This is the list of types of resource-records, and it doubles as a list of types of questions that can be asked. (See GskDnsResourceRecord::type and GskDnsQuestion::query_type)

`GSK_DNS_RR_HOST_ADDRESS` | The numeric address of the host of the given name.
`GSK_DNS_RR_NAME_SERVER` | A nameserver which can be used to find more information about the name.
`GSK_DNS_RR_CANONICAL_NAME` | Another name for the domain. The canonical name given by this record should be the preferred name.
`GSK_DNS_RR_HOST_INFO` | Host data, like CPU and OS. Never used.
`GSK_DNS_RR_MAIL_EXCHANGE` | A host which is responsible for mail for this domain.
`GSK_DNS_RR_POINTER` | A pointer to another name. This is almost always used for reverse dns lookups. See `gsk_dns_rr_new_ptr()`.
`GSK_DNS_RR_START_OF_AUTHORITY` | Information about how quickly to time out records from this domain.
`GSK_DNS_RR_TEXT` | Free form information about the domain.
`GSK_DNS_RR_WELL_KNOWN_SERVICE` | XXX
`GSK_DNS_RR_HOST_ADDRESS_IPV6` |
`GSK_DNS_RR_ZONE_TRANSFER` | XXX
`GSK_DNS_RR_ZONE_MAILB` | XXX
`GSK_DNS_RR_WILDCARD` | If reforming a query, this can be used to obtain records of any type about the domain name.

### enum GskDnsResourceClass

    typedef enum
    {
      /* `IN': the Internet system */
      GSK_DNS_CLASS_INTERNET = 1,

      /* `CH': the Chaos system (rare) */
      GSK_DNS_CLASS_CHAOS = 3,

      /* `HS': Hesiod (rare) */
      GSK_DNS_CLASS_HESIOD = 4,

      /* --- only for queries --- */

      /* `*': any system */
      GSK_DNS_CLASS_WILDCARD = 255
    } GskDnsResourceClass;

What type of addresses are we considering. Almost always GSK_DNS_CLASS_INTERNET.

`GSK_DNS_CLASS_INTERNET` | the internet (IPv4).
`GSK_DNS_CLASS_CHAOS` | obsolete network.
`GSK_DNS_CLASS_HESIOD` | obsolete network.
`GSK_DNS_CLASS_WILDCARD` | when performing a query, this can be used to find records for any class.

### GSK_DNS_SERIAL_LESS_THAN()

    #define             GSK_DNS_SERIAL_LESS_THAN(serial_1, serial_2)

Test whether `serial_1` is less that `serial_2`. See RFC 1982.

`serial_1` : | the first serial number.
`serial_2` : | the second serial number.

### gsk_dns_rr_new_generic ()

    GskDnsResourceRecord * gsk_dns_rr_new_generic           (GskDnsMessage *allocator,
                                                             const char *owner,
                                                             guint32 ttl);

Allocate a new blank record of the given type.

The returned resource-record will probably not be valid, since most records have non-optional type-specific fields that the caller must initialize.

`allocator` : | a message from which to draw the resource-records memory.
`owner` : | the owner field, which is common to all types of resource-records.
`ttl` : | the time-to-live for this record.
Returns : | the newly allocated Resource Record.

### gsk_dns_rr_new_a ()

    GskDnsResourceRecord * gsk_dns_rr_new_a                 (const char *owner,
                                                             guint32 ttl,
                                                             const guint8 *ip_address,
                                                             GskDnsMessage *allocator);

Allocate a new A record. It is a mapping from domain name to IP address.

`owner` : | hostname whose ip address is given.
`ttl` : | the time-to-live for this record. This is maximum time for this record to be stored on a remote host, in seconds.
`ip_address` : | 4-byte IP address to contact `owner`.
`allocator` : | an optional message to get memory from; this can prevent you from having to destroy the record: it will automatically get freed as part of the GskDnsMessage.
Returns : | the newly allocated Resource Record.

### gsk_dns_rr_new_aaaa ()

    GskDnsResourceRecord * gsk_dns_rr_new_aaaa              (const char *owner,
                                                             guint32 ttl,
                                                             const guint8 *address,
                                                             GskDnsMessage *allocator);

Allocate a new AAAA record. It is a mapping from domain name to IP address.

`owner` : | hostname whose IPv6 address is given.
`ttl` : | the time-to-live for this record. This is maximum time for this record to be stored on a remote host, in seconds.
`address` : |
`allocator` : | an optional message to get memory from; this can prevent you from having to destroy the record: it will automatically get freed as part of the GskDnsMessage.
Returns : | the newly allocated Resource Record.

### gsk_dns_rr_new_ns ()

    GskDnsResourceRecord * gsk_dns_rr_new_ns                (const char *owner,
                                                             guint32 ttl,
                                                             const char *name_server,
                                                             GskDnsMessage *allocator);

Allocate a new NS record. It gives the name of a nameserver that can provide information about `owner`.

If you are encountering this in response to a query, you typically also get the address of a nameserver is given in an Additional record of the message as an A record; otherwise, you'd probably have to look up the nameserver in a separate query.

`owner` : | hostname or domain name whose nameserver is given by this record.
`ttl` : | the time-to-live for this record. This is maximum time for this record to be stored on a remote host, in seconds.
`name_server` : | the name of a nameserver responsible for this hostname or domainname.
`allocator` : | an optional message to get memory from; this can prevent you from having to destroy the record: it will automatically get freed as part of the GskDnsMessage.
Returns : | the newly allocated Resource Record.

### gsk_dns_rr_new_cname ()

    GskDnsResourceRecord * gsk_dns_rr_new_cname             (const char *owner,
                                                             guint32 ttl,
                                                             const char *canonical_name,
                                                             GskDnsMessage *allocator);

Allocate a new CNAME record. It gives the canonical name of a record. `owner`.

Information about the canonical host may be given in the Additional section.

`owner` : | hostname or domain name whose canonical name is given by this record.
`ttl` : | the time-to-live for this record. This is maximum time for this record to be stored on a remote host, in seconds.
`canonical_name` : | the canonical name of `owner`. The canonical name in some sense should be the most preferred name for this host, but in practice it's no different than a way to alias one name for another.
`allocator` : | an optional message to get memory from; this can prevent you from having to destroy the record: it will automatically get freed as part of the GskDnsMessage.
Returns : | the newly allocated Resource Record.

### gsk_dns_rr_new_ptr ()

    GskDnsResourceRecord * gsk_dns_rr_new_ptr               (const char *owner,
                                                             guint32 ttl,
                                                             const char *ptr,
                                                             GskDnsMessage *allocator);

Allocate a new PTR record. It gives ``a pointer to another part of the domain name space'' according to [RFC 1034, Section 3.6]

In practice, it is almost always used to do reverse-DNS. That is because, by RFC 1034 and 1035, if you have an IP address aa.bb.cc.dd, then looking up a PTR record for dd.cc.bb.aa.IN-ADDR.ARPA should give the name for the host.

Of course, reverse DNS is a bit flaky, and is principally for debugging information.

`owner` : | hostname or domain name whose PTR record is being looked up. In practice, this name is almost always in the .arpa domain.
`ttl` : | the time-to-live for this record. This is maximum time for this record to be stored on a remote host, in seconds.
`ptr` : | a hostname which `owner` points to.
`allocator` : | an optional message to get memory from; this can prevent you from having to destroy the record: it will automatically get freed as part of the GskDnsMessage.
Returns : | the newly allocated Resource Record.

### gsk_dns_rr_new_mx ()

    GskDnsResourceRecord * gsk_dns_rr_new_mx                (const char *owner,
                                                             guint32 ttl,
                                                             int preference,
                                                             const char *mail_host,
                                                             GskDnsMessage *allocator);

Allocate a mail-exchange record. This gives a hostname which is responsible for main for the `owner` of this record.

`owner` : | hostname or domain name whose PTR record is being looked up.
`ttl` : | the time-to-live for this record.
`preference` : | ???
`mail_host` : | host responsible for mail for this domain.
`allocator` : | an optional message to get memory from; this can prevent you
Returns : | the newly allocated Resource Record.

### gsk_dns_rr_new_hinfo ()

    GskDnsResourceRecord * gsk_dns_rr_new_hinfo             (const char *owner,
                                                             guint32 ttl,
                                                             const char *cpu,
                                                             const char *os,
                                                             GskDnsMessage *allocator);

Allocate a new HINFO record. It ``identifies the CPU and OS used by a host'', see [RFC 1034, Section 3.6]

In practice, it is never used. It is provided for completeness, and also for experimental use.

`owner` : | hostname or domain name whose PTR record is being looked up. In practice, this name is almost always in the .arpa domain.
`ttl` : | the time-to-live for this record. This is maximum time for this record to be stored on a remote host, in seconds.
`cpu` : | CPU name for the host.
`os` : | OS for the host.
`allocator` : | an optional message to get memory from; this can prevent you from having to destroy the record: it will automatically get freed as part of the GskDnsMessage.
Returns : | the newly allocated Resource Record.

### gsk_dns_rr_new_soa ()

    GskDnsResourceRecord * gsk_dns_rr_new_soa               (const char *owner,
                                                             guint32 ttl,
                                                             const char *mname,
                                                             const char *rname,
                                                             guint32 serial,
                                                             guint32 refresh_time,
                                                             guint32 retry_time,
                                                             guint32 expire_time,
                                                             guint32 minimum_time,
                                                             GskDnsMessage *allocator);

Allocate a new SOA record. It ``identifies the start of a zone of authority'', see [RFC 1034, Section 3.6]

[The field descriptions come from RFC 1035, section 3.3.13]

`owner` : | hostname or domain name whose authority is being stated.
`ttl` : | the time-to-live for this record. This is maximum time for this record to be stored on a remote host, in seconds.
`mname` : | The domain-name of the name server that was the original or primary source of data for this zone.
`rname` : | A domain-name which specifies the mailbox of the person responsible for this zone.
`serial` : | The unsigned 32 bit version number of the original copy of the zone. Zone transfers preserve this value. This value wraps and should be compared using sequence space arithmetic.
`refresh_time` : | A 32 bit time interval before the zone should be refreshed.
`retry_time` : | A 32 bit time interval that should elapse before a failed refresh should be retried.
`expire_time` : | A 32 bit time value that specifies the upper limit on the time interval that can elapse before the zone is no longer authoritative.
`minimum_time` : | The unsigned 32 bit minimum TTL field that should be exported with any RR from this zone.
`allocator` : | an optional message to get memory from; this can prevent you from having to destroy the record: it will automatically get freed as part of the GskDnsMessage.
Returns : | the newly allocated Resource Record.

### gsk_dns_rr_new_txt ()

    GskDnsResourceRecord * gsk_dns_rr_new_txt               (const char *owner,
                                                             guint32 ttl,
                                                             const char *text,
                                                             GskDnsMessage *allocator);

TXT RRs are used to hold descriptive text. The semantics of the text depends on the domain where it is found.

`owner` : | hostname or domain name whose authority is being stated.
`ttl` : | the time-to-live for this record. This is maximum time for this record to be stored on a remote host, in seconds.
`text` : | text about the owner.
`allocator` : | an optional message to get memory from; this can prevent you from having to destroy the record: it will automatically get freed as part of the GskDnsMessage.
Returns : | the newly allocated Resource Record.

### gsk_dns_rr_free ()

    void                gsk_dns_rr_free                     (GskDnsResourceRecord *record);

De-allocate memory associated with a resource record.

`record` : | the record to free.

### gsk_dns_rr_copy ()

    GskDnsResourceRecord * gsk_dns_rr_copy                  (GskDnsResourceRecord *record,
                                                             GskDnsMessage *allocator);

Make a copy of a resource record, possibly coming from a given GskDnsMessage's allocator.

`record` : | the record to copy.
`allocator` : | an optional message to get memory from; this can prevent you from having to destroy the record: it will automatically get freed as part of the GskDnsMessage.
Returns : | the new copy of the resource record.

### gsk_dns_rr_new_wildcard ()

    GskDnsResourceRecord * gsk_dns_rr_new_wildcard          (const char *owner,
                                                             guint ttl,
                                                             GskDnsMessage *allocator);

Create a new wildcard ("*") record. This should never need to be done, I guess.

TODO: delete this function

`owner` : | hostname or domain name whose information is given by this record.
`ttl` : | the time-to-live for this record.
`allocator` : | an optional message to get memory from; this can prevent you from having to destroy the record: it will automatically get freed as part of the GskDnsMessage.
Returns : | the newly allocated Resource Record.

### gsk_dns_question_new ()

    GskDnsQuestion *    gsk_dns_question_new                (const char *query_name,
                                                             GskDnsResourceRecordType query_type,
                                                             GskDnsResourceClass query_class,
                                                             GskDnsMessage *allocator);

Allocate a new question.

`query_name` : | the name for which information is being saught.
`query_type` : | the type of resource-record that is saught.
`query_class` : | the address namespace for the query.
`allocator` : | an optional message to get memory from; this can prevent you from having to destroy the question: it will automatically get freed as part of the GskDnsMessage.
Returns : | the new question.

### gsk_dns_question_copy ()

    GskDnsQuestion *    gsk_dns_question_copy               (GskDnsQuestion *question,
                                                             GskDnsMessage *allocator);

Make a copy of a question, optionally drawing its memory from the given message's pool.

`question` : | the question to make a copy of.
`allocator` : | an optional message to get memory from.
Returns : | the new question.

### gsk_dns_question_free ()

    void                gsk_dns_question_free               (GskDnsQuestion *question);

Deallocate a question (unless it was drawn from a GskDnsMessage, in which case it will be destroyed automatically when the message is destroyed.

`question` : | the question to deallocate.

### gsk_dns_rr_text_parse ()

    GskDnsResourceRecord * gsk_dns_rr_text_parse            (const char *record,
                                                             const char *last_owner,
                                                             const char *origin,
                                                             char **err_msg,
                                                             GskDnsMessage *allocator);

Parse a text representation of a message, as from a zone file or 'dig'.

`record` : | the record as a string.
`last_owner` : | the last parsed resource-record's "owner" field. Spaces at the beginning of the line are taken to represent the same owner.
`origin` : | the origin server for this record.
`err_msg` : | optional place to put an allocated error message.
`allocator` : | a message from which to draw the resource-records memory.
Returns : | the new resource-record, or NULL if an error occurred.

### gsk_dns_rr_text_to_str ()

    char *              gsk_dns_rr_text_to_str              (GskDnsResourceRecord *rr,
                                                             const char *last_owner);

Convert the resource record into a format which would be appropriate for a zone file.

`rr` : | the resource record to convert to a text string.
`last_owner` : | if non-NULL, then this should be the owner of the last resource record printed out. For human-readability, zone files merely indent subsequent lines that refer to the same owner.
Returns : | a newly allocated string. The text of the resource-record.

### gsk_dns_question_text_to_str ()

    char *              gsk_dns_question_text_to_str        (GskDnsQuestion *question);

Convert a question to a newly allocated string containing the question roughly as it would be printed by the unix program 'dig'.

`question` : | question to convert to text.
Returns : | the newly allocated string.

### gsk_dns_rr_text_write ()

    void                gsk_dns_rr_text_write               (GskDnsResourceRecord *rr,
                                                             GskBuffer *out_buffer,
                                                             const char *last_owner);

Print a resource-record to a buffer as text. This will look similar to a zone file.

`rr` : | the resource record to write as text into the buffer.
`out_buffer` : | the buffer to which the text resource-record should be appended.
`last_owner` : | if non-NULL, then spaces will be printed instead of `rr`->owner, if it is the same as last_owner.

### enum GskDnsResponseCode

    typedef enum
    {
      GSK_DNS_RESPONSE_ERROR_NONE             =0,
      GSK_DNS_RESPONSE_ERROR_FORMAT           =1,
      GSK_DNS_RESPONSE_ERROR_SERVER_FAILURE   =2,
      GSK_DNS_RESPONSE_ERROR_NAME_ERROR       =3,
      GSK_DNS_RESPONSE_ERROR_NOT_IMPLEMENTED  =4,
      GSK_DNS_RESPONSE_ERROR_REFUSED          =5
    } GskDnsResponseCode;

Types of errors that can be encountered from the DNS server. (From RFC 1035 Section 4.1.1) All other values are reserved for future use.

`GSK_DNS_RESPONSE_ERROR_NONE` | No error condition
`GSK_DNS_RESPONSE_ERROR_FORMAT` | Format error - The name server was unable to interpret the query.
`GSK_DNS_RESPONSE_ERROR_SERVER_FAILURE` | Server failure - The name server was unable to process this query due to a problem with the name server.
`GSK_DNS_RESPONSE_ERROR_NAME_ERROR` | Name Error - Meaningful only for responses from an authoritative name server, this code signifies that the domain name referenced in the query does not exist.
`GSK_DNS_RESPONSE_ERROR_NOT_IMPLEMENTED` | Not Implemented - The name server does not support the requested kind of query.
`GSK_DNS_RESPONSE_ERROR_REFUSED` | Refused - The name server refuses to perform the specified operation for policy reasons. For example, a name server may not wish to provide the information to the particular requester, or a name server may not wish to perform a particular operation (e.g., zone transfer) for particular data.

### gsk_dns_message_new ()

    GskDnsMessage *     gsk_dns_message_new                 (guint16 id,
                                                             gboolean is_request);

Allocate a new blank GskDnsMessage.

`id` : | the identifier used to match client requests to server responses.
`is_request` : | whether the message is a client request. If FALSE, then the message is a server response.
Returns : | the new message.

### gsk_dns_message_parse_buffer ()

    GskDnsMessage *     gsk_dns_message_parse_buffer        (GskBuffer *buffer);

Parse a GskDnsMessage from a buffer, removing the binary data from the buffer.

`buffer` : | the buffer to parse to get a binary DNS message.
Returns : | the new DNS message, or NULL if a parse error occurs.

### gsk_dns_message_parse_data ()

    GskDnsMessage *     gsk_dns_message_parse_data          (const guint8 *data,
                                                             guint length,
                                                             guint *bytes_used_out);

Parse a GskDnsMessage from a buffer.

`data` : | binary data to parse into a DNS message.
`length` : | length of `data` in bytes.
`bytes_used_out` : | number of bytes of `data` actually used to make the returned message, or NULL if you don't care.
Returns : | the new DNS message, or NULL if a parse error occurs.

### gsk_dns_message_write_buffer ()

    void                gsk_dns_message_write_buffer        (GskDnsMessage *message,
                                                             GskBuffer *buffer,
                                                             gboolean compress);

Create a serialized message to send in a packet, or whatever transport.

XXX: technically, DNS is supposed to support really crappy transport media, which only allow a very short message. We have no real control over how long the message will be, a priori, and we just ignore the problem... We casually try to send whatever packet a caller wants, even if it probably won't work in the transport layer.

`message` : | the DNS message to serialize.
`buffer` : | where to write the message.
`compress` : | whether to use compression. always specify TRUE!

### gsk_dns_message_to_packet ()

    GskPacket *         gsk_dns_message_to_packet           (GskDnsMessage *message);

Convert a DNS message into a packet. Typically then the packet will be added to a packet queue.

`message` : | a DNS message which is going to be sent out.
Returns : | the new packet containing the binary data.

### gsk_dns_message_append_question ()

    void                gsk_dns_message_append_question     (GskDnsMessage *message,
                                                             GskDnsQuestion *question);

Add a question to the QUESTION section of a GskDnsMessage. For client requests, the message usually consists of just questions. For server responses, the message will have copies the questions that the message deals with.

The question will be free'd by the message.

`message` : | the message to affect.
`question` : | a question to add to the message.

### gsk_dns_message_append_answer ()

    void                gsk_dns_message_append_answer       (GskDnsMessage *message,
                                                             GskDnsResourceRecord *answer);

Add an answer to the DNS message. This is done by servers when they have a direct answer to a question (either a real answer or a reference to a nameserver which can answer it).

`answer` will be freed when `message` is freed.

`message` : | the message to affect.
`answer` : | a resource-record to add to the answer section of the message.

### gsk_dns_message_append_auth ()

    void                gsk_dns_message_append_auth         (GskDnsMessage *message,
                                                             GskDnsResourceRecord *auth);

Add an authority-record to the DNS message. This is done by servers to indicate who is in charge of certain names and caching information.

`auth` will be freed when `message` is freed.

`message` : | the message to affect.
`auth` : | a resource-record to add to the authority section of the message.

### gsk_dns_message_append_addl ()

    void                gsk_dns_message_append_addl         (GskDnsMessage *message,
                                                             GskDnsResourceRecord *addl);

Add an additional record to the DNS message. This may be done by servers as a courtesy and optimization. The most common use is to give the numeric IP address when a nameserver referenced in the answers section.

`auth` will be freed when `message` is freed.

`message` : | the message to affect.
`addl` : | a resource-record to add to the additional section of the message.

### gsk_dns_message_remove_question ()

    void                gsk_dns_message_remove_question     (GskDnsMessage *message,
                                                             GskDnsQuestion *question);

Remove the question from the message's list, and delete the question.

`message` : | a DNS message.
`question` : | a question in the message.

### gsk_dns_message_remove_answer ()

    void                gsk_dns_message_remove_answer       (GskDnsMessage *message,
                                                             GskDnsResourceRecord *answer);

Remove the record from the message's answer list. This frees the record.

`message` : | a DNS message.
`answer` : | an answer in the message.

### gsk_dns_message_remove_auth ()

    void                gsk_dns_message_remove_auth         (GskDnsMessage *message,
                                                             GskDnsResourceRecord *auth);

Remove the record from the message's authority list. This frees the record.

`message` : | a DNS message.
`auth` : | an authority record in the message.

### gsk_dns_message_remove_addl ()

    void                gsk_dns_message_remove_addl         (GskDnsMessage *message,
                                                             GskDnsResourceRecord *addl);

Remove the record from the message's additional list. This frees the record.

`message` : | a DNS message.
`addl` : | an additional record in the message.

### gsk_dns_message_unref ()

    void                gsk_dns_message_unref               (GskDnsMessage *message);

Decrease the reference-count on the message. The message will be destroyed once its ref-count gets to 0.

`message` : | the message to stop referencing.

### gsk_dns_message_ref ()

    void                gsk_dns_message_ref                 (GskDnsMessage *message);

Increase the reference count on the message by one. The message will not be destroyed until its ref-count gets to 0.

`message` : | the message to add a reference to.

### gsk_dns_dump_message_fp ()

    void                gsk_dns_dump_message_fp             (GskDnsMessage *message,
                                                             FILE *fp);

Dump a message to a FILE*, for debugging. This output format is modelled after the somewhat obscure unix utility 'dig'.

`message` : | the message to print out.
`fp` : | the file to write the message out to.

### gsk_dns_dump_question_fp ()

    void                gsk_dns_dump_question_fp            (GskDnsQuestion *question,
                                                             FILE *fp);

`question` : |
`fp` : |

### gsk_dns_parse_ip_address ()

    gboolean            gsk_dns_parse_ip_address            (const char **pat,
                                                             guint8 *ip_addr_out);

Parse a numeric IP address, in the standard fashion (RFC 1034, 3.6.1).

`pat` : | pointer which starts at a numeric IP address. *`pat` will be updated to past the IP address.
`ip_addr_out` : | the 4-byte IP address.
Returns : | whether the address was parsed successfully.

### gsk_test_domain_name_validity ()

    gboolean            gsk_test_domain_name_validity       (const char *domain_name);

Verify that the domain_name meets certain required to be a hostname on the internet. In particular, all domain names MUST have <= 128 parts each with <= 63 characters.

`domain_name` : | a name which is supposed to be a domain name to test for validity.
Returns : | whether the domain name was valid.