bglibs
dns: DNS Resolver Library

Data Structures

struct  dns_transmit
struct  dns_mx
union  dns_result_rrs
struct  dns_result

Macros

#define DNS_C_IN   1
#define DNS_C_ANY   255
#define DNS_T_A   1
#define DNS_T_NS   2
#define DNS_T_CNAME   5
#define DNS_T_SOA   6
#define DNS_T_PTR   12
#define DNS_T_HINFO   13
#define DNS_T_MX   15
#define DNS_T_TXT   16
#define DNS_T_RP   17
#define DNS_T_SIG   24
#define DNS_T_KEY   25
#define DNS_T_AAAA   28
#define DNS_T_AXFR   252
#define DNS_T_ANY   255
#define DNS_RANDOM_SEED   (32*4)
#define DNS_MAX_IPS   16
#define DNS_NAME4_DOMAIN   (4*4+14)
#define DNS_NAME6_DOMAIN   (32*2+10)
#define DNS_R_FN_WRAP(NAME, TYPE)

Functions

int dns_result_alloc (struct dns_result *d, int type, int count, int size)
void dns_result_free (struct dns_result *d)
void dns_random_init (const char[DNS_RANDOM_SEED])
unsigned int dns_random (unsigned int)
void dns_rotate (unsigned char *, unsigned int n, unsigned int shift)
void dns_rotateipv4 (ipv4addr *, unsigned int)
void dns_rotateipv6 (ipv6addr *, unsigned int)
void dns_sort_mx (struct dns_mx *mxs, int count)
void dns_domain_free (char **)
int dns_domain_copy (char **, const char *)
unsigned int dns_domain_length (const char *)
int dns_domain_equal (const char *, const char *)
int dns_domain_suffix (const char *, const char *)
unsigned int dns_domain_suffixpos (const char *, const char *)
int dns_domain_fromdot (char **, const char *, unsigned int)
int dns_domain_todot_cat (str *, const char *)
unsigned int dns_packet_copy (const char *, unsigned int, unsigned int, unsigned char *, unsigned int)
unsigned int dns_packet_getname (const char *, unsigned int, unsigned int, char **)
unsigned int dns_packet_skipname (const char *, unsigned int, unsigned int)
int dns_packet_extract (struct dns_result *out, const char *buf, unsigned int len, uint16 rrtype, uint16 rrclass, int(*sizefn)(const char *buf, unsigned int len, unsigned int pos, uint16 datalen), int(*copy)(struct dns_result *out, unsigned int index, unsigned int offset, const char *buf, unsigned int len, unsigned int pos, uint16 datalen))
int dns_transmit_start (struct dns_transmit *, const ipv4addr[DNS_MAX_IPS], int, const char *, uint16, const ipv4addr *)
void dns_transmit_free (struct dns_transmit *)
void dns_transmit_io (const struct dns_transmit *, iopoll_fd *, struct timeval *)
int dns_transmit_get (struct dns_transmit *, const iopoll_fd *, const struct timeval *)
int dns_read_resolvconf (str *out)
int dns_resolvconfip (ipv4addr[DNS_MAX_IPS])
int dns_resolve (struct dns_transmit *, const char *, uint16)
int dns_ip4_packet (struct dns_result *, const char *, unsigned int)
int dns_ip4_r (struct dns_transmit *, struct dns_result *, const char *)
int dns_ip4 (struct dns_result *, const char *)
int dns_ip6_packet (struct dns_result *, const char *, unsigned int)
int dns_ip6_r (struct dns_transmit *, struct dns_result *, const char *)
int dns_ip6 (struct dns_result *, const char *)
int dns_name_packet (struct dns_result *, const char *, unsigned int)
void dns_name4_domain (char[DNS_NAME4_DOMAIN], const ipv4addr *)
void dns_name6_domain (char[DNS_NAME6_DOMAIN], const ipv6addr *)
int dns_name4_r (struct dns_transmit *, struct dns_result *, const ipv4addr *)
int dns_name4 (struct dns_result *, const ipv4addr *)
int dns_name6_r (struct dns_transmit *, struct dns_result *, const ipv6addr *)
int dns_name6 (struct dns_result *, const ipv6addr *)
int dns_txt_packet (struct dns_result *, const char *, unsigned int)
int dns_txt_r (struct dns_transmit *, struct dns_result *, const char *)
int dns_txt (struct dns_result *, const char *)
int dns_mx_packet (struct dns_result *, const char *, unsigned int)
int dns_mx_r (struct dns_transmit *, struct dns_result *, const char *)
int dns_mx (struct dns_result *, const char *)
int dns_resolvconfrewrite (str *)
int dns_qualify_rules (struct dns_result *, str *, const char *, const str *, int(*)(struct dns_transmit *, struct dns_result *, const char *))
int dns_qualify (struct dns_result *, str *, const char *, int(*)(struct dns_transmit *, struct dns_result *, const char *))
unsigned fmt_dns_domain (char *, const char *)

Detailed Description

The DNS resolver library is a modified copy of the public domain library used in djbdns (http://cr.yp.to/djbdns.html). Many modifications have been made, both to make it fit within the bglibs library and to extend the functionality.

Notable enhancements are:

Returns
Functions that return an int return -1 on error and set errno.

Macro Definition Documentation

◆ DNS_C_ANY

#define DNS_C_ANY   255

Record class: Any

◆ DNS_C_IN

#define DNS_C_IN   1

◆ DNS_MAX_IPS

#define DNS_MAX_IPS   16

Maximum number of IPs returned by dns_resolvconfip or used by dns_transmit_start

Referenced by dns_resolvconfip(), dns_resolve(), and dns_transmit_start().

◆ DNS_NAME4_DOMAIN

#define DNS_NAME4_DOMAIN   (4*4+14)

Maximum output size of dns_name4_domain

Referenced by dns_ip6(), dns_name4_domain(), and dns_name4_r().

◆ DNS_NAME6_DOMAIN

#define DNS_NAME6_DOMAIN   (32*2+10)

Maximum output size of dns_name6_domain

Referenced by dns_ip6(), dns_name6_domain(), and dns_name6_r().

◆ DNS_R_FN_WRAP

#define DNS_R_FN_WRAP ( NAME,
TYPE )
Value:
int dns_##NAME(struct dns_result* out,TYPE in) \
{ \
struct dns_transmit tx = {0}; \
int r = dns_##NAME##_r(&tx,out,in); \
dns_transmit_free(&tx); \
return r; \
}
Definition dns.h:138
Definition dns.h:79

Wrapper macro to create a non-reentrant function from a dns_*_r function.

◆ DNS_RANDOM_SEED

#define DNS_RANDOM_SEED   (32*4)

Size of data used by dns_random_init

◆ DNS_T_A

#define DNS_T_A   1

Record type: Address (IPv4)

Referenced by dns_ip4_packet(), dns_ip4_r(), and dns_result_alloc().

◆ DNS_T_AAAA

#define DNS_T_AAAA   28

Record type: Address (IPv6)

Referenced by dns_ip6_packet(), dns_ip6_r(), and dns_result_alloc().

◆ DNS_T_ANY

#define DNS_T_ANY   255

Record type: Any (all known records)

◆ DNS_T_AXFR

#define DNS_T_AXFR   252

Record type: Authoritative zone transfer

◆ DNS_T_CNAME

#define DNS_T_CNAME   5

Record type: Canonical name (alias)

◆ DNS_T_HINFO

#define DNS_T_HINFO   13

Record type: Host information

◆ DNS_T_KEY

#define DNS_T_KEY   25

Record type: Key record

◆ DNS_T_MX

#define DNS_T_MX   15

Record type: Mail exchanger

Referenced by dns_mx_packet(), dns_mx_r(), and dns_result_alloc().

◆ DNS_T_NS

#define DNS_T_NS   2

Record type: Name server

◆ DNS_T_PTR

#define DNS_T_PTR   12

Record type: Pointer

Referenced by dns_name4_r(), dns_name6_r(), dns_name_packet(), and dns_result_alloc().

◆ DNS_T_RP

#define DNS_T_RP   17

Record type: Responsible person

◆ DNS_T_SIG

#define DNS_T_SIG   24

Record type: Signature

◆ DNS_T_SOA

#define DNS_T_SOA   6

Record type: Start of authority

◆ DNS_T_TXT

#define DNS_T_TXT   16

Record type: Text

Referenced by dns_result_alloc(), dns_txt_packet(), and dns_txt_r().

Function Documentation

◆ dns_domain_copy()

int dns_domain_copy ( char ** out,
const char * in )
extern

Copy an encoded domain name to a new pointer.

References dns_domain_length().

Referenced by dns_packet_getname().

◆ dns_domain_equal()

int dns_domain_equal ( const char * dn1,
const char * dn2 )
extern

Compare two domain names for equality.

References dns_domain_length().

Referenced by dns_domain_suffix(), and dns_domain_suffixpos().

◆ dns_domain_free()

void dns_domain_free ( char ** out)
extern

Free a pointer to a domain name.

◆ dns_domain_fromdot()

int dns_domain_fromdot ( char ** out,
const char * buf,
unsigned int n )
extern

Generate a DNS encoded domain name into out from the dotted string in buf.

Referenced by dns_ip4_r(), dns_ip6_r(), dns_mx_r(), and dns_txt_r().

◆ dns_domain_length()

unsigned int dns_domain_length ( const char * dn)
extern

Return the length of an encoded domain name.

Referenced by dns_domain_copy(), dns_domain_equal(), and dns_transmit_start().

◆ dns_domain_suffix()

int dns_domain_suffix ( const char * big,
const char * little )
extern

Test if the domain name big ends with little.

References dns_domain_equal().

◆ dns_domain_suffixpos()

unsigned int dns_domain_suffixpos ( const char * big,
const char * little )
extern

Determine the location of the suffix little within big .

References dns_domain_equal().

◆ dns_domain_todot_cat()

int dns_domain_todot_cat ( str * out,
const char * d )
extern

Translate the domain name in d to a dotted text string in out.

References fmt_dns_domain(), str::len, str::s, and str_realloc.

◆ dns_ip4()

int dns_ip4 ( struct dns_result * ,
const char *  )
extern

Request the IPv4 address (A) records for a domain name.

◆ dns_ip4_packet()

int dns_ip4_packet ( struct dns_result * out,
const char * buf,
unsigned int len )
extern

Extract IPv4 address (A) records from a DNS response packet.

References dns_result::count, DNS_C_IN, dns_packet_extract(), dns_rotateipv4(), DNS_T_A, and dns_result::rr.

Referenced by dns_ip4_r().

◆ dns_ip4_r()

int dns_ip4_r ( struct dns_transmit * tx,
struct dns_result * out,
const char * fqdn )
extern

◆ dns_ip6()

int dns_ip6 ( struct dns_result * ,
const char *  )
extern

Request the IPv6 address (AAAA) records for a domain name.

References DNS_NAME4_DOMAIN, and DNS_NAME6_DOMAIN.

◆ dns_ip6_packet()

int dns_ip6_packet ( struct dns_result * out,
const char * buf,
unsigned int len )
extern

Extract IPv6 address (AAAA) records from a DNS response packet.

References dns_result::count, DNS_C_IN, dns_packet_extract(), dns_rotateipv6(), DNS_T_AAAA, and dns_result::rr.

Referenced by dns_ip6_r().

◆ dns_ip6_r()

int dns_ip6_r ( struct dns_transmit * tx,
struct dns_result * out,
const char * fqdn )
extern

◆ dns_mx()

int dns_mx ( struct dns_result * ,
const char *  )
extern

Request the mail exchanger (MX) records for a domain name.

◆ dns_mx_packet()

int dns_mx_packet ( struct dns_result * out,
const char * buf,
unsigned int len )
extern

Extract mail exchanger (MX) records from a DNS response packet.

References DNS_C_IN, dns_packet_extract(), and DNS_T_MX.

Referenced by dns_mx_r().

◆ dns_mx_r()

int dns_mx_r ( struct dns_transmit * tx,
struct dns_result * out,
const char * fqdn )
extern

Request the mail exchanger (MX) records for a domain name.

References dns_domain_fromdot(), dns_mx_packet(), dns_resolve(), DNS_T_MX, dns_transmit_free(), dns_transmit::packet, and dns_transmit::packetlen.

◆ dns_name4()

int dns_name4 ( struct dns_result * ,
const ipv4addr *  )
extern

Request the name (PTR) record for an IPv4 address.

◆ dns_name4_domain()

void dns_name4_domain ( char name[DNS_NAME4_DOMAIN],
const ipv4addr * ip )
extern

Generate the reverse domain name for an IPv4 address.

References DNS_NAME4_DOMAIN, and fmt_udec().

Referenced by dns_name4_r().

◆ dns_name4_r()

int dns_name4_r ( struct dns_transmit * tx,
struct dns_result * out,
const ipv4addr * ip )
extern

Request the name (PTR) record for an IPv4 address.

References DNS_NAME4_DOMAIN, dns_name4_domain(), dns_name_packet(), dns_resolve(), DNS_T_PTR, dns_transmit_free(), dns_transmit::packet, and dns_transmit::packetlen.

Referenced by dns_name6_r().

◆ dns_name6()

int dns_name6 ( struct dns_result * ,
const ipv6addr *  )
extern

Request the name (PTR) record for an IPv6 address.

◆ dns_name6_domain()

void dns_name6_domain ( char name[DNS_NAME6_DOMAIN],
const ipv6addr * addr )
extern

Generate the reverse domain name for an IPv6 address.

References ipv6addr::addr, DNS_NAME6_DOMAIN, and fmt_lcase_digits.

Referenced by dns_name6_r().

◆ dns_name6_r()

int dns_name6_r ( struct dns_transmit * tx,
struct dns_result * out,
const ipv6addr * ip )
extern

◆ dns_name_packet()

int dns_name_packet ( struct dns_result * out,
const char * buf,
unsigned int len )
extern

Extract name (PTR) records from a DNS response packet.

References DNS_C_IN, dns_packet_extract(), and DNS_T_PTR.

Referenced by dns_name4_r(), and dns_name6_r().

◆ dns_packet_copy()

unsigned int dns_packet_copy ( const char * buf,
unsigned int len,
unsigned int pos,
unsigned char * out,
unsigned int outlen )
extern

Copy a block of data out of a packet.

Returns
the offset of the next byte of data, or 0 if the packet was too short.

Referenced by dns_packet_extract().

◆ dns_packet_extract()

int dns_packet_extract ( struct dns_result * out,
const char * buf,
unsigned int len,
uint16 rrtype,
uint16 rrclass,
int(* sizefn )(const char *buf, unsigned int len, unsigned int pos, uint16 datalen),
int(* copy )(struct dns_result *out, unsigned int index, unsigned int offset, const char *buf, unsigned int len, unsigned int pos, uint16 datalen) )
extern

Extract a series of records from a packet.

Parameters
outThe result buffer into which to put the output.
bufThe packet buffer to parse.
lenThe length of buf .
rrtypeThe resource record type, one of DNS_T_*.
rrclassThe resource record class, one of DNS_C_*.
sizefnThe function to call to determine the required buffer size for each record.
copyThe function to call to copy each record into the result.

References dns_packet_copy(), dns_packet_skipname(), and dns_result_alloc().

Referenced by dns_ip4_packet(), dns_ip6_packet(), dns_mx_packet(), dns_name_packet(), and dns_txt_packet().

◆ dns_packet_getname()

unsigned int dns_packet_getname ( const char * buf,
unsigned int len,
unsigned int pos,
char ** d )
extern

Extract a domain name out of a packet, handling name compression.

References dns_domain_copy().

◆ dns_packet_skipname()

unsigned int dns_packet_skipname ( const char * buf,
unsigned int len,
unsigned int pos )
extern

Skip over a domain name within a packet.

Referenced by dns_packet_extract().

◆ dns_qualify()

int dns_qualify ( struct dns_result * out,
str * fqdn,
const char * in,
int(* fn )(struct dns_transmit *, struct dns_result *, const char *) )
extern

Qualify a domain name through DNS requests.

Calls dns_resolvconfrewrite and dns_qualify_rules.

Parameters
outOutput storage for the DNS record results.
fqdnOutput storage for the fully qualified domain name.
inDomain name (full or partial) to qualify.
fnFunction to call (such as dns_ip4) to determine if a qualified domain name exists.

References dns_qualify_rules(), and dns_resolvconfrewrite().

Referenced by resolve_qualdns().

◆ dns_qualify_rules()

int dns_qualify_rules ( struct dns_result * out,
str * fqdn,
const char * in,
const str * rules,
int(* fn )(struct dns_transmit *, struct dns_result *, const char *) )
extern

Qualify a domain name through DNS requests.

This function is used to qualify what may be a partial domain name into a fully qualified domain name through a set of rules and a resolver function. The resolution rules are read by dns_resolvconfrewrite. For each possible qualification of the domain name, the resolver function is called to test if the qualified domain name exists.

Parameters
outOutput storage for the DNS record results.
fqdnOutput storage for the fully qualified domain name.
rulesThe list of rules to use to qualify the domain name.
inDomain name (full or partial) to qualify.
fnFunction to call (such as dns_ip4) to determine if a qualified domain name exists.

References dns_result::count, str::len, str::s, str_copys(), and str_truncate().

Referenced by dns_qualify().

◆ dns_random()

unsigned int dns_random ( unsigned int n)
extern

Generate a random number less than n.

References surfrand_uniform().

Referenced by dns_rotate().

◆ dns_read_resolvconf()

int dns_read_resolvconf ( str * out)
extern

Read the /etc/resolv.conf file. If $DNSRESOLVCONF is set, it names a file to read instead of /etc/resolv.conf .

References ibuf_openreadclose().

◆ dns_resolvconfip()

int dns_resolvconfip ( ipv4addr s[DNS_MAX_IPS])
extern

Parse /etc/resolv.conf for a list of nameserver IPs.

References DNS_MAX_IPS.

Referenced by dns_resolve().

◆ dns_resolvconfrewrite()

int dns_resolvconfrewrite ( str * out)
extern

Load the domain name qualification rules.

The rules are loaded from the file named by $DNSREWRITEFILE (defaults to "/etc/dnsrewrite").

For compatibility, if the rewriting rules file is not present, the qualification procedure looks for a local domain name in three places:

  1. The value of the $LOCALDOMAIN environment variable, if it is set.
  2. The first domain or search line in /etc/resolv.conf (if any).
  3. Everything after the first period in the system's hostname.

It translate these into instructions that add the local domain name to any name without dots or brackets.

See http://cr.yp.to/djbdns/qualify.html for complete details.

References str_copy().

Referenced by dns_qualify().

◆ dns_resolve()

int dns_resolve ( struct dns_transmit * tx,
const char * q,
uint16 qtype )
extern

Resolve a DNS query.

This is the base query handler of the DNS library. It takes a domain name and query type, sends it to all configured nameservers, and handles reading the response packet. Callers are responsible for parsing the desired records out of the resulting packet.

References DNS_MAX_IPS, dns_resolvconfip(), dns_transmit_get(), dns_transmit_io(), and dns_transmit_start().

Referenced by dns_ip4_r(), dns_ip6_r(), dns_mx_r(), dns_name4_r(), dns_name6_r(), and dns_txt_r().

◆ dns_result_alloc()

int dns_result_alloc ( struct dns_result * d,
int type,
int count,
int bufsize )
extern

Allocate a DNS result structure.

References dns_result_free(), DNS_T_A, DNS_T_AAAA, DNS_T_MX, DNS_T_PTR, and DNS_T_TXT.

Referenced by dns_ip4_r(), dns_ip6_r(), and dns_packet_extract().

◆ dns_result_free()

void dns_result_free ( struct dns_result * d)
extern

Free a DNS result structure.

Referenced by dns_result_alloc().

◆ dns_rotate()

void dns_rotate ( unsigned char * s,
unsigned int n,
unsigned int shift )
extern

Rotate (shuffle) a block of fixed-length addresses.

Parameters
sThe array of memory to shuffle.
nThe number of elements of the array.
shiftThe size of each element, expressed as a power-of-two

References dns_random().

Referenced by dns_rotateipv4(), and dns_rotateipv6().

◆ dns_rotateipv4()

void dns_rotateipv4 ( ipv4addr * addrs,
unsigned int n )
extern

Rotate (shuffle) a block of IPv4 addresses.

References dns_rotate().

Referenced by dns_ip4_packet().

◆ dns_rotateipv6()

void dns_rotateipv6 ( ipv6addr * addrs,
unsigned int n )
extern

Rotate (shuffle) a block of IPv6 addresses.

References dns_rotate().

Referenced by dns_ip6_packet().

◆ dns_transmit_free()

void dns_transmit_free ( struct dns_transmit * d)
extern

Free all allocated resources in a dns_transmit structure.

Referenced by dns_ip4_r(), dns_ip6_r(), dns_mx_r(), dns_name4_r(), dns_name6_r(), dns_transmit_get(), and dns_transmit_start().

◆ dns_transmit_get()

int dns_transmit_get ( struct dns_transmit * d,
const iopoll_fd * x,
const struct timeval * when )
extern

Complete I/O on a DNS query.

Returns
1 when the query is completed.

References dns_transmit_free(), and socket_connected().

Referenced by dns_resolve().

◆ dns_transmit_io()

void dns_transmit_io ( const struct dns_transmit * d,
iopoll_fd * x,
struct timeval * deadline )
extern

Fill in the iopoll_fd structure from a dns_transmit structure.

Referenced by dns_resolve().

◆ dns_transmit_start()

int dns_transmit_start ( struct dns_transmit * d,
const ipv4addr servers[DNS_MAX_IPS],
int flagrecursive,
const char * q,
uint16 qtype,
const ipv4addr * localip )
extern

Start the transmission of a DNS query.

Parameters
dThe record of the transmission state.
serversThe list of servers to contact, typically filled by dns_resolvconfip.
flagrecursiveUse recursive queries (ie querying a cache).
qThe domain name to query, in DNS format.
qtypeThe query type number.
localipThe local IP from which to send the query, may be NULL.

References DNS_C_IN, dns_domain_length(), DNS_MAX_IPS, and dns_transmit_free().

Referenced by dns_resolve().

◆ dns_txt()

int dns_txt ( struct dns_result * ,
const char *  )
extern

Request the text (TXT) records for a domain name.

◆ dns_txt_packet()

int dns_txt_packet ( struct dns_result * out,
const char * buf,
unsigned int len )
extern

Extract text (TXT) records from a DNS response packet.

References DNS_C_IN, dns_packet_extract(), and DNS_T_TXT.

Referenced by dns_txt_r().

◆ dns_txt_r()

int dns_txt_r ( struct dns_transmit * tx,
struct dns_result * out,
const char * fqdn )
extern

Request the text (TXT) records for a domain name.

References dns_domain_fromdot(), dns_resolve(), DNS_T_TXT, dns_txt_packet(), dns_transmit::packet, and dns_transmit::packetlen.

◆ fmt_dns_domain()

unsigned fmt_dns_domain ( char * out,
const char * domain )
extern

Format a DNS domain name as a dotted name.

Referenced by dns_domain_todot_cat().