bglibs
Data Structures | Macros | Functions
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_read_resolvconf(), dns_resolvconfip(), dns_resolve(), and dns_transmit_free().

◆ DNS_NAME4_DOMAIN

#define DNS_NAME4_DOMAIN   (4*4+14)

Maximum output size of dns_name4_domain

Referenced by dns_name4_r().

◆ DNS_NAME6_DOMAIN

#define DNS_NAME6_DOMAIN   (32*2+10)

Maximum output size of dns_name6_domain

Referenced by 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:79
Definition: dns.h:137

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

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

◆ 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(), dns_result_alloc(), and resolve_ipv4name_n().

◆ 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

Referenced by dns_name4_r(), dns_name6_r(), and resolve_ipv4name_n().

◆ 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 
)

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 
)

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)

Free a pointer to a domain name.

◆ dns_domain_fromdot()

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

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

References obuf_endl(), obuf_putc(), obuf_putf(), and outbuf.

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)

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 
)

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 
)

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 
)

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()

dns_ip4 ( struct dns_result ,
const char *   
)

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

Referenced by dns_ip4_r().

◆ dns_ip4_packet()

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

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 
)

◆ dns_ip6()

dns_ip6 ( struct dns_result ,
const char *   
)

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

Referenced by dns_ip6_r().

◆ dns_ip6_packet()

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

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 
)

◆ dns_mx()

dns_mx ( struct dns_result ,
const char *   
)

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 
)

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 
)

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

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

◆ dns_name4()

dns_name4 ( struct dns_result ,
const ipv4addr  
)

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

Referenced by dns_name4_r(), and resolve_ipv4addr().

◆ dns_name4_domain()

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

Generate the reverse domain name for an IPv4 address.

References ipv4addr::addr, 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 
)

◆ dns_name6()

dns_name6 ( struct dns_result ,
const ipv6addr  
)

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

Referenced by dns_name6_r().

◆ dns_name6_domain()

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

Generate the reverse domain name for an IPv6 address.

References ipv6addr::addr, 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 
)

◆ dns_name_packet()

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

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 
)

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(*)(const char *buf, unsigned int len, unsigned int pos, uint16 datalen)  sizefn,
int(*)(struct dns_result *out, unsigned int index, unsigned int offset, const char *buf, unsigned int len, unsigned int pos, uint16 datalen)  copy 
)

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 
)

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 
)

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(*)(struct dns_transmit *, struct dns_result *, const char *)  fn 
)

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_result::count, dns_qualify_rules(), dns_resolvconfrewrite(), obuf_putf(), outbuf, and str::s.

Referenced by resolve_qualdns().

◆ dns_qualify_rules()

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

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)

Generate a random number less than n.

References surfrand_uniform().

Referenced by dns_rotate(), and dns_transmit_free().

◆ dns_read_resolvconf()

int dns_read_resolvconf ( str out)

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

References DNS_MAX_IPS, ibuf_openreadclose(), ipv4_scan(), str::s, striter::start, striter::startptr, str_catc(), and striter_loop.

◆ dns_resolvconfip()

int dns_resolvconfip ( ipv4addr  s[DNS_MAX_IPS])

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

References DNS_MAX_IPS, ipv4_format(), obuf_puts, outbuf, and str::s.

Referenced by dns_resolve().

◆ dns_resolvconfrewrite()

int dns_resolvconfrewrite ( str out)

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::len, str::s, and str_copy().

Referenced by dns_qualify().

◆ dns_resolve()

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

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 
)

◆ dns_result_free()

void dns_result_free ( struct dns_result d)

Free a DNS result structure.

References dns_result::__buffer, and dns_result::rr.

Referenced by dns_result_alloc().

◆ dns_rotate()

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

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 
)

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 
)

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)

◆ dns_transmit_get()

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

◆ dns_transmit_io()

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

Fill in the iopoll_fd structure from a dns_transmit structure.

References dns_transmit::deadline, dns_transmit::s1, and dns_transmit::tcpstate.

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 
)

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_transmit_free(), dns_transmit::localip, dns_transmit::qtype, dns_transmit::query, dns_transmit::querylen, dns_transmit::servers, and dns_transmit::udploop.

Referenced by dns_resolve().

◆ dns_txt()

dns_txt ( struct dns_result ,
const char *   
)

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

Referenced by dns_txt_r().

◆ dns_txt_packet()

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

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 
)

◆ fmt_dns_domain()

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

Format a DNS domain name as a dotted name.

Referenced by dns_domain_todot_cat().