libs6dns
s6-dns
Software
skarnet.org

The s6dns_resolve library interface

The following functions are declared in the s6-dns/s6dns-resolve.h header, and implemented in the libs6dns.a or libs6dns.so library.

General information

s6dns_resolve provides functions and macros - mostly macros - to perform high level synchronous DNS resolution.

All the functions declared here make synchronous calls to the network, so they can block for a non-negligible amount of time. To avoid unbounded waiting times, they always take 2 arguments at the end, deadline and stamp. deadline is the read-only address of a tain_t containing an absolute time which is the deadline for the function, and stamp is the read-write address of a tain_t being an accurate enough representation of the current absolute time. If the function has not returned by *deadline, then it immediately returns with a failure code and errno set to ETIMEDOUT. In every case, *stamp is automatically updated so it always represents the absolute time accurately enough.

In a single-threaded program, the STAMP global variable can be used to store the current time. Macros ending with _g use this variable automatically so you don't have to provide the stamp argument everytime. Additionally, several resolution functions make implicit use of global variables such as:

Reentrant, non-global-using functions are also provided, with the _r suffix. In other words, if foobarfunc is a resolution function, the following prototypes are generally provided, from the simplest to the most complex:

For each set of four functions, only one is documented here. The other prototypes can be found in the s6-dns/s6dns-resolve.h file.

Some errno codes reported by these functions do not have exactly the system meaning given by strerror(). To get a user-friendly error message, use s6dns_constants_error_str(errno) instead. The s6dns_constants_error_str function is declared in the s6dns-constants.h header.

Functions

Single query resolution

These functions are ordered from the lowest level to the highest level.

Basic wrapper around s6dns_engine

int s6dns_resolve_loop_r_g (s6dns_engine_t *dt, tain_t const *deadline)
Resolves the query stored in dt. Returns 1 on success or 0 on failure.

Generic resolution functions

int s6dns_resolve_core_g (s6dns_domain_t const *d, uint16_t qtype, tain_t const *deadline)
Resolves the query on domain *d (in packet form), of type qtype. Returns 0 on failure, or 1 on success, in which case s6dns_engine_here contains the answer.

int s6dns_resolve_parse_g (s6dns_domain_t const *d, uint16_t qtype, s6dns_message_rr_func_t *f, void *data, tain_t const *deadline)
Resolves the query on domain *d (in packet form), of type qtype, then parses the answer with function f and stores the result into data. Returns 1 if it succeeds, 0 if no data can be extracted from the answer, or -1 if an error occurs. Sets errno in the last two cases.

Note that the function can return 1 without appending anything to data. This means that the servers confirmed that the domain exists, but f has not been able to find any data relevant to the query in the answer. This is very different from NXDOMAIN, which means that the servers deny the actual existence of the domain, and which is reported here as a return code of 0 with errno set to ENOENT.

int s6dns_resolvenoq_g (char const *name, size_t len, uint16_t qtype, s6dns_message_rr_func_t *f, void *data, tain_t const *deadline)
Performs a query of type qtype on name name of length len, without qualifying it. Parses the answer with function f and stores the result into data. Returns 1 if it succeeds, 0 if no data can be extracted, or -1 if an error occurs. Sets errno in the last two cases.

int s6dns_resolveq_g (char const *name, size_t len, uint16_t qtype, s6dns_message_rr_func_t *f, void *data, tain_t const *deadline)
Performs a query of type qtype on name name of length len, qualifying it first. Parses the answer with function f and stores the result into data. Returns 1 if it succeeds, 0 if none of the FQDNs can get a positive answer, or -1 if an error occurs. Sets errno in the last two cases.

int s6dns_resolve_g (char const *name, size_t len, uint16_t qtype, s6dns_message_rr_func_t *f, void *data, int qualif, tain_t const *deadline)
Performs a query of type qtype on name name of length len. Qualifies name first if qualif is nonzero; else, does not qualify it. Parses the answer with function f and stores the result into data. Returns 1 if it succeeds, 0 if none of the FQDNs can get a positive answer, or -1 if an error occurs. Sets errno in the last two cases.

High-level type-specific functions

int s6dns_resolve_a_g (stralloc *ips, char const *name, size_t len, int qualif, tain_t const *deadline)
Performs an A query on name name of length len, qualifying it iff qualif is nonzero. Returns -1 if an error occurs, or 0 if no answer can be obtained from servers, or 1 if it succeeds, in which case the IPs are appended to the stralloc *ips, using 4 bytes per answer.

int s6dns_resolve_aaaa_g (stralloc *ips, char const *name, size_t len, int qualif, tain_t const *deadline)
Performs an AAAA query on name name of length len, qualifying it iff qualif is nonzero. Returns -1 if an error occurs, or 0 if no answer can be obtained from servers, or 1 if it succeeds, in which case the IPs are appended to the stralloc *ips, using 16 bytes per answer.

int s6dns_resolve_aaaaa_g (genalloc *ips, char const *name, size_t len, int qualif, tain_t const *deadline)
Performs an AAAA query and an A query at the same time on name name of length len, qualifying it first iff qualif is nonzero. Returns -1 if an error occurs, or 0 if no answer can be obtained from servers, or a positive number if it succeeds: 1 if IPv4 addresses were found, 2 if IPv6 addresses were found, and 3 if both were found. The IPs are appended to the genalloc *ips, which contains an array of ip46full_t, the skalibs structure used to store IPv4 and IPv6 addresses indiscriminately.

int s6dns_resolve_ptr_g (genalloc *ds, char const *name, size_t len, int qualif, tain_t const *deadline)
Performs a PTR query on name name of length len, qualifying it iff qualif is nonzero. Returns -1 if an error occurs, or 0 if no answer can be obtained from servers, or 1 if it succeeds, in which case the domains are appended to the genalloc *ds, which contains an array of s6dns_domain_t.

int s6dns_resolve_name4_g (genalloc *ds, char const *ip, tain_t const *deadline)
Performs a PTR query on the in-addr.arpa. name representing the IPv4 address ip (4 network-order bytes). Returns -1 if an error occurs, or 0 if no answer can be obtained from servers, or 1 if it succeeds, in which case the domains are appended to the genalloc *ds, which contains an array of s6dns_domain_t.

int s6dns_resolve_name6_g (genalloc *ds, char const *ip, tain_t const *deadline)
Performs a PTR query on the ip6.arpa. name representing the IPv6 address ip (16 network-order bytes). Returns -1 if an error occurs, or 0 if no answer can be obtained from servers, or 1 if it succeeds, in which case the domains are appended to the genalloc *ds, which contains an array of s6dns_domain_t.

int s6dns_resolve_name46_g (genalloc *ds, ip46full_t const *ip, tain_t const *deadline)
Calls s6dns_resolve_name6_g() or s6dns_resolve_name4_g() depending on which ip is an IPv6 or IPv4 address.

int s6dns_resolve_ns_g (genalloc *ds, char const *name, size_t len, int qualif, tain_t const *deadline)
Performs a NS query on name name of length len, qualifying it iff qualif is nonzero. Returns -1 if an error occurs, or 0 if no answer can be obtained from servers, or 1 if it succeeds, in which case the domains are appended to the genalloc *ds, which contains an array of s6dns_domain_t.

int s6dns_resolve_cname_g (genalloc *ds, char const *name, size_t len, int qualif, tain_t const *deadline)
Performs a CNAME query on name name of length len, qualifying it iff qualif is nonzero. Returns -1 if an error occurs, or 0 if no answer can be obtained from servers, or 1 if it succeeds, in which case the domains are appended to the genalloc *ds, which contains an array of s6dns_domain_t.

int s6dns_resolve_hinfo_g (genalloc *hinfos, char const *name, size_t len, int qualif, tain_t const *deadline)
Performs an HINFO query on name name of length len, qualifying it iff qualif is nonzero. Returns -1 if an error occurs, or 0 if no answer can be obtained from servers, or 1 if it succeeds, in which case the domains are appended to the genalloc *hinfos, which contains an array of s6dns_message_rr_hinfo_t.

int s6dns_resolve_mx_g (genalloc *mxs, char const *name, size_t len, int qualif, tain_t const *deadline)
Performs an MX query on name name of length len, qualifying it iff qualif is nonzero. Returns -1 if an error occurs, or 0 if no answer can be obtained from servers, or 1 if it succeeds, in which case the domains are appended to the genalloc *mxs, which contains an array of s6dns_message_rr_mx_t.

int s6dns_resolve_soa_g (genalloc *soas, char const *name, size_t len, int qualif, tain_t const *deadline)
Performs an SOA query on name name of length len, qualifying it iff qualif is nonzero. Returns -1 if an error occurs, or 0 if no answer can be obtained from servers, or 1 if it succeeds, in which case the domains are appended to the genalloc *soas, which contains an array of s6dns_message_rr_soa_t.

int s6dns_resolve_srv_g (genalloc *srvs, char const *name, size_t len, int qualif, tain_t const *deadline)
Performs an SRV query on name name of length len, qualifying it iff qualif is nonzero. Returns -1 if an error occurs, or 0 if no answer can be obtained from servers, or 1 if it succeeds, in which case the domains are appended to the genalloc *srvs, which contains an array of s6dns_message_rr_srv_t.

int s6dns_resolve_caa_g (genalloc *caas, char const *name, size_t len, int qualif, tain_t const *deadline)
Performs a CAA query on name name of length len, qualifying it iff qualif is nonzero. Returns -1 if an error occurs, or 0 if no answer can be obtained from servers, or 1 if it succeeds, in which case the domains are appended to the genalloc *caas, which contains an array of s6dns_message_rr_caa_t.

int s6dns_resolve_txt_g (stralloc *sa, genalloc *offsets, char const *name, unsigned int len, int qualif, tain_t const *deadline)
Performs an TXT query on name name of length len, qualifying it iff qualif is nonzero. Returns -1 if an error occurs, or 0 if no answer can be obtained from servers, or 1 if it succeeds, in which case:

Parallel resolution

int s6dns_resolven_loop_g (s6dns_engine_t *dtl, unsigned int n, unsigned int or, tain_t const *deadline)
Resolves the n queries stored in the array pointed to by dtl, in parallel. If or is zero, it does not return before all answers have arrived. If or is 1, it returns when an answer arrives, but does not return if a query generates an error (unless all queries do so). If or is 2, it returns when an answer arrives or an error occurs. Other values of or are unspecified yet.

The return code is as follows:

If or is 1, a return code of -1 with errno set to ENOENT means that all the queries failed.

After the function returns, the status field of each s6dns_engine_t contains the error code relative to the query. A status of 0 means that an answer has properly arrived; EAGAIN means that the query is still pending (and the s6dns_engine_t has not been recycled); ECONNABORTED means that the query has not been properly initialized. Other codes report various network problems.

int s6dns_resolven_parse_g (s6dns_resolve_t const *list, unsigned int n, tain_t const *deadline)
Performs n complete resolutions in parallel, parsing the results. Returns 1 in case of success or 0 if a global error occurred.

list is a pointer to an array of n s6dns_resolve_t, which is a structure containing at least the following fields:

The s6dns_resolven_parse() function is a simple, convenient way to perform several resolutions in parallel to avoid the waiting time incurred by serial resolutions. However, it is still a synchronous function, and cannot replace a real asynchronous DNS library: for more complex parallel resolution needs, use the skadns library.