diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2014-12-10 03:05:47 +0000 |
---|---|---|
committer | Laurent Bercot <ska-skaware@skarnet.org> | 2014-12-10 03:05:47 +0000 |
commit | 416ef5e2bf59bb2e45066a1d5d91ac677c0f48e5 (patch) | |
tree | 1c746d673dcec7a8488c6ac51db8245411034376 /doc/libs6dns | |
download | s6-dns-416ef5e2bf59bb2e45066a1d5d91ac677c0f48e5.tar.xz |
Initial commit
Diffstat (limited to 'doc/libs6dns')
-rw-r--r-- | doc/libs6dns/index.html | 104 | ||||
-rw-r--r-- | doc/libs6dns/s6dns-domain.html | 137 | ||||
-rw-r--r-- | doc/libs6dns/s6dns-engine.html | 255 | ||||
-rw-r--r-- | doc/libs6dns/s6dns-fmt.html | 92 | ||||
-rw-r--r-- | doc/libs6dns/s6dns-ip46.html | 69 | ||||
-rw-r--r-- | doc/libs6dns/s6dns-message.html | 261 | ||||
-rw-r--r-- | doc/libs6dns/s6dns-rci.html | 109 | ||||
-rw-r--r-- | doc/libs6dns/s6dns-resolve.html | 387 |
8 files changed, 1414 insertions, 0 deletions
diff --git a/doc/libs6dns/index.html b/doc/libs6dns/index.html new file mode 100644 index 0000000..db7ee35 --- /dev/null +++ b/doc/libs6dns/index.html @@ -0,0 +1,104 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns: the s6dns library interface</title> + <meta name="Description" content="s6-dns: the s6dns library interface" /> + <meta name="Keywords" content="s6-dns dns s6dns library libs6dns" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="../">s6-dns</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The <tt>s6dns</tt> library interface </h1> + +<h2> General information </h2> + +<p> + <tt>libs6dns</tt> is a DNS client library, designed for clarity +and simplicity - which translates into smallness of the code. +</p> + +<p> + A major focus of <tt>libs6dns</tt> is to avoid unnecessary use +of heap memory. Memory is only allocated in the heap to store +queries and response packets during a DNS resolution process, and +to store the final answers into a user-provided +<a href="http://skarnet.org/software/skalibs/libstddjb/stralloc.html"> +stralloc</a>; all the other operations use stack memory, and perform +as few copies as possible. +</p> + +<h2> Compiling </h2> + +<ul> + <li> Make sure the s6-dns headers, as well as the skalibs headers, +are visible in your header search path. </li> + <li> Use <tt>#include <s6-dns/s6dns.h></tt> </li> +</ul> + +<h2> Linking </h2> + +<ul> + <li> Make sure the s6-dns libraries, as well as the skalibs libraries, +are visible in your library search path. </li> + <li> Link against <tt>-ls6dns</tt>, <tt>-lskarnet</tt>, </li> +<tt>`cat $SYSDEPS/socket.lib`</tt> and +<tt>`cat $SYSDEPS/tainnow.lib`</tt>, $SYSDEPS being your skalibs +sysdeps directory. </li> +</ul> + +<h2> Programming </h2> + +<p> + The <tt>s6dns.h</tt> header is actually a concatenation of other headers: +the libs6dns is separated into several modules, each of them with its +own header. +</p> + +<ul> + <li> The <tt>s6dns-constants.h</tt> header provides constants used in +other parts of the library. </li> + <li> The <a href="s6dns-ip46.html">s6dns-ip46.h</a> header provides an +abstraction for IPv4 and IPv6 transports. </li> + <li> The <a href="s6dns-domain.html">s6dns-domain.h</a> header provides +basic string manipulation primitives for domain names. </li> + <li> The <a href="s6dns-message.html">s6dns-message.h</a> header provides +function to parse a message following the DNS protocol. </li> + <li> The <a href="s6dns-engine.html">s6dns-engine.h</a> header provides +the low-level asynchronous networking functions. </li> + <li> The <a href="s6dns-rci.html">s6dns-rci.h</a> header provides an +interface to <tt>resolv.conf</tt> reading. </li> + <li> The <a href="s6dns-resolve.html">s6dns-resolve.h</a> header provides +the user-level synchronous resolution functions. </li> + <li> The <a href="s6dns-fmt.html">s6dns-fmt.h</a> header provides +formatting primitives to display RR contents. </li> +</ul> + +<p> + (User-level asynchronous resolution functions are provided in the +<a href="../skadns/">skadns</a> library.) +</p> + +<p> + Two functional macros are actually directly declared in the <tt>s6dns.h</tt> +header: +</p> + +<ul> + <li> Call <tt>s6dns_init()</tt> before all your s6dns operations. +s6dns_init() calls <a href="s6dns-rci.html">s6dns_rci_init()</a>, +extracting <tt>resolv.conf</tt> information to an internal global +variable. The function returns 1 on success, and 0 (and sets errno) +on failure. </li> + <li> Call <tt>s6dns_finish()</tt> when you're done with the libs6dns. +It frees the resources used. </li> +</ul> + +</body> +</html> diff --git a/doc/libs6dns/s6dns-domain.html b/doc/libs6dns/s6dns-domain.html new file mode 100644 index 0000000..b1492c3 --- /dev/null +++ b/doc/libs6dns/s6dns-domain.html @@ -0,0 +1,137 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns: the s6dns_domain library interface</title> + <meta name="Description" content="s6-dns: the s6dns_domain library interface" /> + <meta name="Keywords" content="s6-dns dns s6dns_domain library libs6dns" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">libs6dns</a><br /> +<a href="../">s6-dns</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The <tt>s6dns_domain</tt> library interface </h1> + +<p> + The following functions and structures are declared in the <tt>s6-dns/s6dns-domain.h</tt> header, +and implemented in the <tt>libs6dns.a</tt> or <tt>libs6dns.so</tt> library. +</p> + +<h2> General information </h2> + +<p> + <tt>s6dns_domain</tt> provides primitives to perform basic operations +on domain names. +</p> + +<h2> Data structures </h2> + +<p> + A <tt>s6dns_domain_t</tt> is a structure that s6dns uses internally to +represent a domain name. It can be in <em>string form</em> (or +<em>decoded form</em>), which is close to the printable form seen +by users, or in <em>packet form</em> (or <em>encoded form</em>), which +is the format used in the DNS protocol. +</p> + +<p> + A <tt>s6dns_domain_t</tt> is a flat structure and can be declared +on the stack. +</p> + +<h2> Functions </h2> + +<p> +<code> int s6dns_domain_fromstring (s6dns_domain_t *d, char const *s, unsigned int len) </code> <br /> +Makes a (string form) domain from string <em>s</em> of length <em>len</em>, +and stores it into *<em>d</em>. Returns 1 if it succeeds, otherwise it +returns 0 and sets errno appropriately - most likely ENAMETOOLONG, i.e. +the name in <em>s</em> is not a well-formed domain name. +</p> + +<p> +<code> unsigned int s6dns_domain_tostring (char *s, unsigned int max, s6dns_domain_t const *d) </code> <br /> +Writes into string <em>s</em> the domain contained in *<em>d</em> (in string +form). Returns the number of bytes written, or 0 in case of failure. If +the output would be more than <em>max</em> bytes, 0 ENAMETOOLONG is returned. +</p> + +<p> +<code> int s6dns_domain_noqualify (s6dns_domain_t *d) </code> <br /> +Makes sure that *<em>d</em> is fully qualified. This is done without using +qualification: a trailing dot is simply appended if the domain +doesn't already have one. Returns 1 if it succeeds, or 0 if it fails. +</p> + +<p> +<code> unsigned int s6dns_domain_qualify (s6dns_domain_t *list, s6dns_domain_t const *d, char const *rules, unsigned int rulesnum) </code> <br /> +Performs qualification on domain *<em>d</em> according to the first +<em>rulesnum</em> rules stored in string <em>rules</em>. Stores the output +(at most <em>rulesnum</em> domains) into the array pointed to by <em>list</em>. +Returns 0 on failure, or the number of written domains if it succeeds. This +number can be lesser than <em>rulesnum</em>, for instance if *<em>d</em> is +already fully qualified. <br /> +Valid <em>rules</em> and <em>rulesnum</em> can be obtained via functions +declared in <a href="s6dns-rci.html">s6dns-rci.h</a>. +</p> + +<p> +<code> int s6dns_domain_encode (s6dns_domain_t *d) </code> <br /> +Encodes domain *<em>d</em> from string form to packet form. Returns 1 +if it succeeds or 0 if it fails - for instance, *<em>d</em> is not a +valid string form (EINVAL). +</p> + +<p> +<code> unsigned int s6dns_domain_encodelist (s6dns_domain_t *list, unsigned int n) </code> <br /> +Encodes <em>n</em> domains pointed to by <em>list</em> from string form to packet form, +stopping at the first failure. +Returns the number of successfully encoded domains, normally <em>n</em>. +</p> + +<p> +<code> int s6dns_domain_decode (s6dns_domain_t *d) </code> <br /> +Decodes domain *<em>d</em> from packet form to string form. Returns 1 +if it succeeds or 0 if it fails - for instance, *<em>d</em> is not a +valid packet form (EPROTO). +</p> + +<p> +<code> int s6dns_domain_fromstring_noqualify_encode (s6dns_domain_t *d, char const *s, unsigned int len) </code> <br /> +Higher-level function wrapping some of the above. Makes an encoded, fully qualified +(without resorting to qualification) domain from string <em>s</em> of +length <em>len</em>. Returns 1 if it succeeds and 0 if it fails. +</p> + +<p> +<code> unsigned int s6dns_domain_fromstring_qualify_encode (s6dns_domain_t *list, char const *s, unsigned int len, char const *rules, unsigned int rulesnum) </code> <br /> +Another wrapping function. It makes a list of encoded, fully qualified domains, +from string <em>s</em> of length <em>len</em> using <em>rulesnum</em> qualification +rules in <em>rules</em>. It writes at most <em>rulesnum</em> domains into the array +pointed to by <em>list</em> and returns the number of written domains, or 0 on an +error. +</p> + +<p> +<code> void s6dns_domain_arpafromip4 (s6dns_domain_t *d, char const *ip) </code> <br /> +Writes into <em>d</em> the <tt>in-addr.arpa.</tt> domain corresponding to IPv4 address +<em>ip</em> (4 bytes, in network byte order), in string form. +</p> + +<p> +<code> void s6dns_domain_arpafromip6 (s6dns_domain_t *d, char const *ip, unsigned int mask) </code> <br /> +Writes into <em>d</em> the <tt>ip6.arpa.</tt> domain corresponding to the first +<em>mask</em> bits of IPv6 address <em>ip</em> (16 bytes, in network byte order), +in string form. +Only multiples of 4 count for <em>mask</em>, i.e. the output will be the same +if mask is (for instance) 125, 126, 127 or 128. +</p> + +</body> +</html> diff --git a/doc/libs6dns/s6dns-engine.html b/doc/libs6dns/s6dns-engine.html new file mode 100644 index 0000000..f0f9573 --- /dev/null +++ b/doc/libs6dns/s6dns-engine.html @@ -0,0 +1,255 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns: the s6dns_engine library interface</title> + <meta name="Description" content="s6-dns: the s6dns_engine library interface" /> + <meta name="Keywords" content="s6-dns dns s6dns_engine library libs6dns" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">libs6dns</a><br /> +<a href="../">s6-dns</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The <tt>s6dns_engine</tt> library interface </h1> + +<p> + The following functions are declared in the <tt>s6-dns/s6dns-engine.h</tt> header, +and implemented in the <tt>libs6dns.a</tt> or <tt>libs6dns.so</tt> library. +</p> + +<h2> General information </h2> + +<p> + <tt>s6dns_engine</tt> is the nitty-gritty of DNS query management. These +are the low-level asynchronous primitives sending DNS queries over the +network, and getting answers. +</p> + +<p> + <tt>s6dns_engine</tt> has been inspired by Dan J. Bernstein's +<a href="http://cr.yp.to/djbdns/dns_transmit.html">dns_transmit</a> +library, but does not borrow any code from it. Unlike +<tt>dns_transmit</tt>, <tt>s6dns_engine</tt> does not assume that +network send operations are instant successes; <tt>s6dns_engine</tt> +descriptors can be selected for writing as well as for reading. +Also, if the underlying <a href="http://skarnet.org/software/skalibs"> +skalibs</a> has been compiled with IPv6 support, <tt>s6dns_engine</tt> +supports native IPv6 transport. +</p> + +<p> + The <tt>s6dns_engine</tt> functions are used in the implementation of the +<tt>s6dns_resolven_loop</tt> function - which is nothing more than a +simple event loop around the <tt>s6dns_engine</tt> primitives - and the +<a href="../skadns/skadnsd.html">skadnsd</a> daemon. Both pieces of code are +good examples of how to use <tt>s6dns_engine</tt>. +</p> + +<p> + However, unless you're implementing a DNS cache, you probably should +not call the +<tt>s6dns_engine</tt> functions directly: they are very low-level. If you +need synchronous resolution, use the +<a href="s6dns-resolve.html">s6dns_resolve</a> functions. If you need +asynchronous DNS operations, use the +<a href="../skadns/index.html">skadns</a> functions, which are +designed to provide a higher level interface to multiple asynchronous +DNS queries. +</p> + +<h2> Data structures </h2> + +<p> + A <tt>s6dns_engine_t</tt> structure holds all the data necessary to +manage a DNS query (and response). It must be initialized to S6DNS_ENGINE_ZERO +when first declared, and recycled with <tt>s6dns_engine_recycle()</tt> +after each use. It contains a stralloc, so it must be freed with +<tt>s6dns_engine_free()</tt> before being discarded, to avoid memory leaks. +</p> + +<h2> Functions </h2> + +<h3> <tt>s6dns_engine_t</tt> life cycle </h3> + +<p> +<code> int s6dns_engine_init (s6dns_engine_t *dt, s6dns_ip46list_t const *servers, uint32 options, char const *q, unsigned int qlen, uint16 qtype, struct taia const *deadline, struct taia const *stamp) </code> +</p> + +<p> +Initializes <em>dt</em> with query <em>q</em> of length <em>qlen</em> +and type <em>qtype</em>. If <tt>d</tt> is an +encoded <tt>s6dns_domain_t</tt>, then <tt>d.s</tt> and <tt>d.len</tt> +are appropriate candidates for arguments <em>q</em> and <em>qlen</em> +respectively. +</p> + +<p> +<em>options</em> can be 0 or an OR'ed +combination of the following, defined in <tt>s6-dns/s6dns-constants.h</tt>: +</p> + +<ul> + <li> S6DNS_O_RECURSIVE: the query will be recursive and assuming it is +sent to a DNS cache, instead of iterative and assuming it is sent to a +DNS server. </li> + <li> S6DNS_O_STRICT: the library will only accept authoritative answers +to iterative queries. This is normally the sane behaviour, but badly +configured DNS software around the world - notably, <a href="../bind.html"> +BIND</a> when it's configured to be both a cache and a server - often +serve <em>non-</em>authoritative data even when they could, so it +breaks things, hence why the option isn't set by default. </li> +</ul> + +<p> +<em>servers</em> must point to a list of IP addresses as defined in +<a href="s6dns-ip46.html">s6-dns/s6dns-ip46.h</a>. Such a list can be +obtained from the <tt>/etc/resolv.conf</tt> file via the +<a href="s6dns-rci.html">s6dns_rci_fill()</a> call when performing a +recursive query, or it must be constructed from a list of relevant +NS addresses when performing an iterative query. +</p> + +<p> +<em>stamp</em> must be an accurate enough timestamp. <em>deadline</em> +sets up a deadline for the query: if the query hasn't been +satisfactorily answered by <em>deadline</em> - no matter how many +round-trips to network servers the library performs internally - then +it will be considered failed, and a timeout will be reported. +</p> + +<p> +The function returns 1 if all went well, and 0 if an error occurred. +It returns instantly; it <em>does not</em> perform any network operation, +it just prepares <em>dt</em> to send a query. The actual data sending +will take place on the next <tt>s6dns_engine_event()</tt> call. +</p> + +<p> +<code> void s6dns_engine_recycle (s6dns_engine_t *dt) </code> +</p> + +<p> +Recycles <tt>dt</tt>, making it ready for another use. This function +does not deallocate the heap memory used by dt, so it's faster than +<tt>s6dns_engine_free()</tt> and does not cause heap fragmentation. +</p> + +<p> +<code> void s6dns_engine_free (s6dns_engine_t *dt) </code> +</p> + +<p> +Frees the heap memory used by <tt>dt</tt>. Also makes <tt>dt</tt> +ready for another use. It's advised to only use this function when +certain that <em>dt</em> will not be reused. +</p> + +<h3> Before the <tt>iopause()</tt> </h3> + +<p> + The descriptor to select on is available as the <tt>fd</tt> field in +the <tt>s6dns_engine_t</tt> structure. +<em>dt</em>→fd should be read every iteration, because it can +change between iterations even if no event or timeout is reported +for <em>dt</em>. +</p> + +<p> +<code> void s6dns_engine_nextdeadline (s6dns_engine_t const *dt, struct taia *a) </code> +</p> + +<p> +If <em>dt</em> needs handling before the absolute date *<em>a</em>, +then *<em>a</em> is updated +so it contains the earlier date. This is useful to compute the next +deadline in an <tt>iopause()</tt> loop. +</p> + +<p> +<code> int s6dns_engine_isreadable (s6dns_engine_t const *dt) </code> +</p> + +<p> +Returns nonzero iff <em>dt</em>→fd is to be selected for reading. +Should be called in every iteration. +</p> + +<p> +<code> int s6dns_engine_iswritable (s6dns_engine_t const *dt) </code> +</p> + +<p> +Returns nonzero iff <em>dt</em>→fd is to be selected for writing. +Should be called in every iteration. +</p> + +<h3> After the <tt>iopause()</tt> </h3> + +<p> +<code> int s6dns_engine_timeout (s6dns_engine_t *dt, struct taia const *stamp) </code> +</p> + +<p> +This function should be called if your selecting function returned 0, which +means that an event timed out. +<em>stamp</em> should contain the current time. The function returns -1 if +an error occurred, 1 if <em>dt</em> actually timed out, and 0 if nothing +special happened to <em>dt</em> (and your iopause timeout was caused by +something else). If the return value is not 0, <em>dt</em> is automatically +recycled. +</p> + +<p> +<code> int s6dns_engine_event (s6dns_engine_t *dt, struct taia const *stamp) </code> +</p> + +<p> +This function should be called if your selecting function returned a positive +number, which means that some event got triggered. +<em>stamp</em> should contain the current time. The function returns +-1 if an error occurred (and <em>dt</em> is automatically recycled). It +returns 0 if no answer has arrived yet, and 1 if an answer is available. +</p> + +<p> +The <tt>s6dns_engine_timeout()</tt> and <tt>s6dns_engine_event()</tt> functions, +when returning -1, make use of the following error codes: +</p> +<ul> + <li> EINVAL: Invalid <em>dt</em>. + <li> ENETUNREACH: All the servers in the <em>servers</em> list have been +unsuccessfully tried. </li> + <li> EPROTO: An answer arrived, but it didn't follow the DNS protocol. </li> + <li> Other error codes reporting socket or system failures. </li> +</ul> + +<p> +<code> char *s6dns_engine_packet (s6dns_engine_t const *dt) </code> +</p> + +<p> +Points to the response packet received from the network, +if <tt>s6dns_engine_event()</tt> returned 1. +</p> + +<p> +<code> unsigned int s6dns_engine_packetlen (s6dns_engine_t const *dt) </code> +</p> + +<p> +Gives the length of the response packet, +if <tt>s6dns_engine_event()</tt> returned 1. +</p> + +<p> + You should recycle or free <em>dt</em> after reading the response packet. +</p> + +</body> +</html> diff --git a/doc/libs6dns/s6dns-fmt.html b/doc/libs6dns/s6dns-fmt.html new file mode 100644 index 0000000..a586846 --- /dev/null +++ b/doc/libs6dns/s6dns-fmt.html @@ -0,0 +1,92 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns: the s6dns_fmt library interface</title> + <meta name="Description" content="s6-dns: the s6dns_fmt library interface" /> + <meta name="Keywords" content="s6-dns dns s6dns_fmt library libs6dns" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">libs6dns</a><br /> +<a href="../">s6-dns</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The <tt>s6dns_fmt</tt> library interface </h1> + +<p> + The following functions and structures are declared in the <tt>s6-dns/s6dns-fmt.h</tt> header, +and implemented in the <tt>libs6dns.a</tt> or <tt>libs6dns.so</tt> library. +</p> + +<h2> General information </h2> + +<p> + <tt>s6dns_fmt</tt> provides primitives to format RR contents into +printable strings. +</p> + +<h2> Functions </h2> + +<p> +<code> unsigned int s6dns_fmt_domain (char *s, unsigned int max, s6dns_domain_t const *d) </code> <br /> +Writes into string <em>s</em> the domain contained in *<em>d</em> (in string +form). Returns the number of bytes written, or 0 in case of failure. If +the output would be more than <em>max</em> bytes, 0 ENAMETOOLONG is returned. +To avoid that, S6DNS_FMT_DOMAIN is a suitable number of bytes to preallocate <em>s</em>. +This function is actually an alias to <tt>s6dns_domain_tostring</tt>. +</p> + +<p> +<code> unsigned int s6dns_fmt_domainlist (char *s, unsigned int max, s6dns_domain_t const *list, unsigned int n, char const *delin, unsigned int delimlen) </code> <br /> +Writes into string <em>s</em> the list of <em>n</em> domains (in string form) +pointed to by <em>list</em>. Between each domain (and not after the last one), +string <em>delim</em> of length <em>delimlen</em> is appended. +The function returns the number of bytes written, or 0 in case of failure. If +the output would be more than <em>max</em> bytes, 0 ENAMETOOLONG is returned. +To avoid that, S6DNS_FMT_DOMAINLIST(n) is a suitable number of bytes to preallocate <em>s</em>. +</p> + +<p> +<code> unsigned int s6dns_fmt_hinfo (char *s, unsigned int max, s6dns_message_rr_hinfo_t const *p) </code> <br /> +Writes into string <em>s</em> the HINFO contained in *<em>p</em>: cpu, then os, +separated by a space. +Returns the number of bytes written, or 0 in case of failure. If +the output would be more than <em>max</em> bytes, 0 ENAMETOOLONG is returned. +To avoid that, S6DNS_FMT_HINFO is a suitable number of bytes to preallocate <em>s</em>. +</p> + +<p> +<code> unsigned int s6dns_fmt_mx (char *s, unsigned int max, s6dns_message_rr_mx_t const *p) </code> <br /> +Writes into string <em>s</em> the MX contained in *<em>p</em>: preference, then +exchanger name, separated by a space. +Returns the number of bytes written, or 0 in case of failure. If +the output would be more than <em>max</em> bytes, 0 ENAMETOOLONG is returned. +To avoid that, S6DNS_FMT_MX is a suitable number of bytes to preallocate <em>s</em>. +</p> + +<p> +<code> unsigned int s6dns_fmt_soa (char *s, unsigned int max, s6dns_message_rr_soa_t const *p) </code> <br /> +Writes into string <em>s</em> the SOA contained in *<em>p</em>: +mname, then rname, then serial number, refresh time, retry time, expiration time +and minimum time, separated by spaces. +Returns the number of bytes written, or 0 in case of failure. If +the output would be more than <em>max</em> bytes, 0 ENAMETOOLONG is returned. +To avoid that, S6DNS_FMT_SOA is a suitable number of bytes to preallocate <em>s</em>. +</p> + +<p> +<code> unsigned int s6dns_fmt_srv (char *s, unsigned int max, s6dns_message_rr_srv_t const *p) </code> <br /> +Writes into string <em>s</em> the SRV contained in *<em>p</em>: priority, +then weight, then port, then target, separated by spaces. +Returns the number of bytes written, or 0 in case of failure. If +the output would be more than <em>max</em> bytes, 0 ENAMETOOLONG is returned. +To avoid that, S6DNS_FMT_SRV is a suitable number of bytes to preallocate <em>s</em>. +</p> + +</body> +</html> diff --git a/doc/libs6dns/s6dns-ip46.html b/doc/libs6dns/s6dns-ip46.html new file mode 100644 index 0000000..27cbe2c --- /dev/null +++ b/doc/libs6dns/s6dns-ip46.html @@ -0,0 +1,69 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns: the s6dns_ip46 library interface</title> + <meta name="Description" content="s6-dns: the s6dns_ip46 library interface" /> + <meta name="Keywords" content="s6-dns dns s6dns_ip46 library libs6dns" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">libs6dns</a><br /> +<a href="../">s6-dns</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The <tt>s6dns_ip46</tt> library interface </h1> + +<p> + The following functions are declared in the <tt>s6-dns/s6dns-ip46.h</tt> header, +and implemented as macros. +</p> + +<h2> General information </h2> + +<p> + <tt>s6dns_ip46</tt> is the transport abstraction layer. It allows +the functions declared in <a href="s6dns-engine.html">s6-dns/s6dns-engine.h</a> +and <a href="s6dns-rci.html">s6-dns/s6dns-rci.h</a> to be transport-agnostic, +i.e. to be able to work with both IPv4 and IPv6. +</p> + +<p> + If the underlying <a href="http://skarnet.org/software/skalibs/">skalibs</a> +has been compiled with + <a href="http://skarnet.org/software/skalibs/flags.html#noipv6">flag-noipv6</a>, +or if it has detected at build time that the target host does not support +IPv6, then the s6dns-ip46 abstraction will be totally transparent and use +no resources at all. +</p> + +<h2> Data structures </h2> + +<p> + A <tt>s6dns_ip46list_t</tt> structure holds a list of S6DNS_MAX_SERVERS (16) +IPv4 <em>or</em> IPv6 addresses. Such a mixed list can be constructed, for +instance, if the <tt>/etc/resolv.conf</tt> file contains both v4 and v6 +<tt>nameserver</tt> lines. +</p> + +<h2> Functions </h2> + +<p> + If <em>list</em> is a <tt>s6dns_ip46list_t</tt> and <em>i</em> an integer +between 0 and DNS_MAX_SERVERS-1, then +</p> + +<ul> + <li> <code>s6dns_ip46list_is6(&list, i)</code> is 1 if the <em>i</em>th +address in <em>list</em> is IPv6 and 0 if it is IPv4. </li> + <li> <code>s6dns_ip46list_ip(&list, i)</code> is a <tt>char *</tt> pointer to +16 (if IPv6) or 4 (IPv4) bytes representing the <em>i</em>th address in +<em>list</em>, in network byte order. </li> +</ul> + +</body> +</html> diff --git a/doc/libs6dns/s6dns-message.html b/doc/libs6dns/s6dns-message.html new file mode 100644 index 0000000..e06aa91 --- /dev/null +++ b/doc/libs6dns/s6dns-message.html @@ -0,0 +1,261 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns: the s6dns_message library interface</title> + <meta name="Description" content="s6-dns: the s6dns_message library interface" /> + <meta name="Keywords" content="s6-dns dns s6dns_message library libs6dns" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">libs6dns</a><br /> +<a href="../">s6-dns</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The <tt>s6dns_message</tt> library interface </h1> + +<p> + The following functions are declared in the <tt>s6-dns/s6dns-message.h</tt> header, +and implemented in the <tt>libs6dns.a</tt> or <tt>libs6dns.so</tt> library. +</p> + +<h2> General information </h2> + +<p> + <tt>s6dns_message</tt> provides functions to read and parse DNS messages +sent by servers and caches and containing answers to queries. +</p> + +<h2> Data structures </h2> + +<p> + A <tt>s6dns_message_header_t</tt> is a structure containing the header +of a received DNS packet, broken down for easy access to the bits. +</p> + +<p> + A <tt>s6dns_message_rr_t</tt> is a structure containing the information +about a resource record given by an answer packet - all of it, except the +value of the answer itself, which is rtype-specific and has to be decoded +by rtype-specific functions. +</p> + +<p> + A <tt>s6dns_message_rr_func_t</tt> is the type of such a function. The +prototype is <br /> +<code> int f (s6dns_message_rr_t const *rr, char const *packet, unsigned int packetlen, unsigned int pos, unsigned int section, void *data) </code> <br /> +</p> + +<ul> + <li> *<em>rr</em> contains the header information of the resource record, +including the domain to which it applies, the rtype, and the ttl. </li> + <li> <em>packet</em> points to the <strong>whole DNS packet</strong> the RR +is a part of. </li> + <li> <em>packetlen</em> is the total length of said packet. </li> + <li> <em>pos</em> is the offset of the RR in the DNS packet, i.e. <em>f</em> +should start parsing at <em>packet + pos</em>. </li> + <li> <em>section</em> is the section the RR belongs to: 2 for answer, 3 for +authority, 4 for additional. </li> + <li> <em>data</em> is a user-specified pointer; it is typically used to +write the decoded output, in a rtype-specific way. </li> + <li> <em>f</em> must return 1 or more if it succeeds in decoding the packet. +Else it must set errno appropriately, and return -1 if the error is local, +unrelated to the packet - for instance, it has run out of memory - or 0 if it +cannot decode the RR because of the packet contents. </li> +</ul> + +<p> + Various structures designed to store specific resource record types are +also provided. The list includes: +</p> + +<ul> + <li> <tt>s6dns_message_rr_hinfo</tt> for HINFO RRs </li> + <li> <tt>s6dns_message_rr_mx</tt> for MX RRs </li> + <li> <tt>s6dns_message_rr_soa</tt> for SOA RRs </li> + <li> <tt>s6dns_message_rr_srv</tt> for SRV RRs </li> +</ul> + +<h2> Functions </h2> + +<h3> Header management </h3> + +<p> +<code> void s6dns_message_header_pack (char *s, s6dns_message_header_t const *h) </code> <br /> +Packs the header *<em>h</em> into the 12 bytes pointed to by <em>s</em>. +</p> + +<p> +<code> void s6dns_message_header_unpack (char const *s, s6dns_message_header_t *h) </code> <br /> +Unpacks the 12 bytes pointed to by <em>s</em> into the structure *<em>h</em>. +</p> + +<h3> Low-level RR decoding </h3> + +<p> + The following primitives are used in the implementation of +<tt>s6dns_message_rr_func_t</tt>-typed functions, to read and decode information +stored in a DNS packet. Their arguments are: +</p> + +<ol> + <li> A pointer to the structure where the information is going to be stored </li> + <li> A read-only pointer to the beginning of the DNS packet </li> + <li> The length of the DNS packet </li> + <li> A pointer to an integer containing the current position in the +DNS packet, i.e. where the information is going to be read. If the functions +succeed, they automatically update the position so information can be read +sequentially. </li> +</ol> + +<p> +<code> int s6dns_message_get_string (s6dns_domain_t *d, char const *packet, unsigned int packetlen, unsigned int *pos) </code> <br /> +Reads a character-string and stores it into *<em>d</em>. Returns 1 on success +and 0 on failure. Note that *<em>d</em> does not contain a domain, but the +<tt>s6dns_domain_t</tt> structure is adapted to store strings that do not +exceed 255 characters. <em>d</em>→s can be used to access the string, +and <em>d</em>→len its length. +</p> + +<p> +<code> int s6dns_message_get_strings (char *s, unsigned int rdlength, char const *packet, unsigned int packetlen, unsigned int *pos </code> <br /> +This function takes an additional parameter <em>rdlength</em>. It reads a series of +character-strings and stores their concatenation into the string <em>s</em>, which +must be preallocated; it can never store more than <em>rdlength</em> bytes. It returns +-1 if it fails; on success, it returns the number of bytes written. The +<em>rdlength</em> parameter must be the length of the resource record containing +the series of character-strings. +</p> + +<p> +<code> unsigned int s6dns_message_get_domain (s6dns_domain_t *d, char const *packet, unsigned int packetlen, unsigned int *pos) </code> <br /> +Reads a domain and stores it, in string form, into *<em>d</em>. +Returns 1 on success and 0 on failure, and sets errno: +</p> + +<ul> + <li> EPROTO: there is no proper domain to be read in position *<em>pos</em> of +<em>packet</em>. Either the packet is malformed or the function is being +misused. </li> + <li> EPROTONOSUPPORT: the domain encoding uses an extension that the function +does not recognize. </li> +</ul> + +<p> +<code> int s6dns_message_get_hinfo (s6dns_message_rr_hinfo_t *p, char const *packet, unsigned int packetlen, unsigned int *pos) </code> <br /> +Reads a HINFO RR and stores it into *<em>p</em>. Returns 1 on success or 0 +on failure. +</p> + +<p> +<code> int s6dns_message_get_mx (s6dns_message_rr_mx_t *p, char const *packet, unsigned int packetlen, unsigned int *pos) </code> <br /> +Reads a MX RR and stores it into *<em>p</em>. Returns 1 on success or 0 on failure. +</p> + +<p> +<code> int s6dns_message_get_soa (s6dns_message_rr_soa_t *p, char const *packet, unsigned int packetlen, unsigned int *pos) </code> <br /> +Reads a SOA RR and stores it into *<em>p</em>. Returns 1 on success or 0 on failure. +</p> + +<p> +<code> int s6dns_message_get_srv (s6dns_message_rr_srv_t *p, char const *packet, unsigned int packetlen, unsigned int *pos) </code> <br /> +Reads a SRV RR and stores it into *<em>p</em>. Returns 1 on success or 0 on failure. +</p> + +<h3> High-level RR-specific parsing functions </h3> + +<p> +<code> s6dns_message_func_t s6dns_message_parse_answer_strings </code> <br /> +Parses character-strings located in the answer section of the packet. The +<em>data</em> argument is interpreted as a pointer to a <tt>s6dns_mpag_t</tt>, +which is a structure defined in the <tt>s6-dns/s6dns-message.h</tt> header +and used to store multiple character-strings. +</p> + +<p> +<code> s6dns_message_func_t s6dns_message_parse_answer_domain </code> <br /> +Parses domains located in the answer section of the packet. The +<em>data</em> argument is interpreted as a pointer to a <tt>s6dns_dpag_t</tt>, +which is a structure defined in the <tt>s6-dns/s6dns-message.h</tt> header +and used to store multiple domains. +</p> + +<p> +<code> s6dns_message_func_t s6dns_message_parse_answer_a </code> <br /> +Parses A RRs located in the answer section of the packet. The +<em>data</em> argument is interpreted as a pointer to a +<a href="http://skarnet.org/software/skalibs/libstddjb/stralloc.html">stralloc</a>, +and 4 bytes are appended to this stralloc for every IPv4 address found. +</p> + + +<code> s6dns_message_func_t s6dns_message_parse_answer_aaaa </code> <br /> +Parses AAAA RRs located in the answer section of the packet. The +<em>data</em> argument is interpreted as a pointer to a +<a href="http://skarnet.org/software/skalibs/libstddjb/stralloc.html">stralloc</a>, +and 16 bytes are appended to this stralloc for every IPv6 address found. +</p> + +<p> +<code> s6dns_message_func_t s6dns_message_parse_answer_hinfo </code> <br /> +Parses HINFO RRs located in the answer section of the packet. The +<em>data</em> argument is interpreted as a pointer to a +<a href="http://skarnet.org/software/skalibs/libstddjb/genalloc.html">genalloc</a> +containing <tt>s6dns_message_rr_hinfo_t</tt> structures. +</p> + +<p> +<code> s6dns_message_func_t s6dns_message_parse_answer_mx </code> <br /> +Parses MX RRs located in the answer section of the packet. The +<em>data</em> argument is interpreted as a pointer to a +<a href="http://skarnet.org/software/skalibs/libstddjb/genalloc.html">genalloc</a> +containing <tt>s6dns_message_rr_mx_t</tt> structures. +</p> + +<p> +<code> s6dns_message_func_t s6dns_message_parse_answer_soa </code> <br /> +Parses SOA RRs located in the answer section of the packet. The +<em>data</em> argument is interpreted as a pointer to a +<a href="http://skarnet.org/software/skalibs/libstddjb/genalloc.html">genalloc</a> +containing <tt>s6dns_message_rr_soa_t</tt> structures. +</p> + +<p> +<code> s6dns_message_func_t s6dns_message_parse_answer_srv </code> <br /> +Parses SRV RRs located in the answer section of the packet. The +<em>data</em> argument is interpreted as a pointer to a +<a href="http://skarnet.org/software/skalibs/libstddjb/genalloc.html">genalloc</a> +containing <tt>s6dns_message_rr_srv_t</tt> structures. +</p> + +<h3> High-level packet parsing </h3> + +<p> +<code> int s6dns_message_parse (s6dns_message_header_t *h, char const *packet, unsigned int packetlen, s6dns_message_rr_func_t *f, void *data) </code> <br /> + This function parses the DNS packet <em>packet</em> of length <em>packetlen</em>. +It stores the packet header into *<em>h</em>. Then, for every RR in the answer, +authority or additional section of the packet, it calls <em>f</em> with the +relevant parameters. <em>data</em> is the extra pointer given to <em>f</em> to +store information. The function returns 1 if the parsing succeeds. Otherwise it +returns -1 if there is a local error unrelated to the packet, or 0 if no +appropriate answer can be decoded from the packet. errno then contains one +of the following values: +</p> + +<ul> + <li> EPROTO: the packet is malformed, syntax error </li> + <li> EBADMSG: rcode 1, query format error </li> + <li> EBUSY: rcode 2, server failure </li> + <li> ENOENT: rcode 3, nxdomain </li> + <li> ENOTSUP: rcode 4, query type not implemented </li> + <li> ECONNREFUSED: rcode 5, operation refused by server </li> + <li> EIO: unknown rcode </li> + <li> any other value being set by <em>f</em> if it returns a failure code. </li> +</ul> + +</body> +</html> diff --git a/doc/libs6dns/s6dns-rci.html b/doc/libs6dns/s6dns-rci.html new file mode 100644 index 0000000..1cf8a0e --- /dev/null +++ b/doc/libs6dns/s6dns-rci.html @@ -0,0 +1,109 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns: the s6dns_rci library interface</title> + <meta name="Description" content="s6-dns: the s6dns_rci library interface" /> + <meta name="Keywords" content="s6-dns dns s6dns_rci resolv.conf library libs6dns" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">libs6dns</a><br /> +<a href="../">s6-dns</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The <tt>s6dns_rci</tt> library interface </h1> + +<p> + The following functions and structures are declared in the <tt>s6-dns/s6dns-rci.h</tt> header, +and implemented in the <tt>libs6dns.a</tt> or <tt>libs6dns.so</tt> library. +</p> + +<h2> General information </h2> + +<p> + <tt>s6dns_rci</tt> provides functions to get information from +the <tt>/etc/resolv.conf</tt> file. +</p> + +<h2> Data structures </h2> + +<p> + A <tt>s6dns_rci_t</tt> is a structure storing information +provided by the <tt>/etc/resolv.conf</tt> file, i.e. +</p> + +<ul> + <li> The list of "nameserver" addresses, i.e. IP addresses of DNS caches +contacted by clients for recursive queries </li> + <li> The list of qualification rules provided by "domain" or "search" +lines </li> +</ul> + +<p> + Nameserver addresses are stored in a +<a href="s6dns-ip46.html">s6dns_ip46list_t</a>. Qualification rules are +stored in a <a href="http://skarnet.org/software/skalibs/libstddjb/stralloc.html">stralloc</a> +with an additional integer storing the number of rules. +</p> + +<p> + Most programs won't need more than one <tt>s6dns_rci_t</tt>, so +the library provides the global variable <tt>s6dns_rci_here</tt>, used +by default in simple resolution macros. +</p> + +<h2> Functions </h2> + +<p> +<code> int s6dns_rci_init (s6dns_rci_t *rci, char const *file) </code> <br /> +Extracts information from <em>file</em>, which must be in <tt>/etc/resolv.conf</tt> +format, and stores it into *<em>rci</em>. <em>rci</em> must be previously +initialized to the <tt>S6DNS_RCI_ZERO</tt> constant. The function returns 1 if +it succeeds, or 0 (and sets errno) if it fails. +</p> + +<p> + If the DNSCACHEIP environment variable is set, and contains a list of +IP addresses separated by commas, semicolons, spaces, tabs, newlines or +carriage returns, then this list overrides any nameserver information +from <em>file</em>. If the variable is empty, <em>file</em> will be used +as the source of the information. +</p> + +<p> + If the DNSQUALIFY environment variable is set, a list of domain suffixes, +separated by spaces, tabs, newlines or carriage returns, is read from it, +and overrides any qualification information from <em>file</em>. If the +variable is empty, it amounts to one rule saying "no qualification". +</p> + +<p> + <tt>s6dns_init()</tt> is an alias to +<tt>s6dns_rci_init(&s6dns_rci_here, "/etc/resolv.conf")</tt>. +</p> + +<p> +<code> void s6dns_rci_free (s6dns_rci_t *rci) </code> <br /> +Frees the memory used by *<em>rci</em>. <em>rci</em> is then suitable to +be reused in a <tt>s6dns_rci_init</tt> call. +</p> + +<p> + <tt>s6dns_finish()</tt> calls <tt>s6dns_rci_free(&s6dns_rci_here)</tt>. +</p> + +<p> +<code> unsigned int s6dns_qualify (s6dns_domain_t *list, s6dns_domain_t const *d) </code> <br /> +Qualifies domain *<em>d</em> into the list of domains pointed to by <em>list</em> +according to the rules stored in <tt>s6dns_rci_here</tt>. Returns the number of +written domains (0 if it fails); this number cannot exceed +<tt>s6dns_rci_here.rulesnum</tt>. +</p> + +</body> +</html> diff --git a/doc/libs6dns/s6dns-resolve.html b/doc/libs6dns/s6dns-resolve.html new file mode 100644 index 0000000..bbb3f57 --- /dev/null +++ b/doc/libs6dns/s6dns-resolve.html @@ -0,0 +1,387 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns: the s6dns_resolve library interface</title> + <meta name="Description" content="s6-dns: the s6dns_resolve library interface" /> + <meta name="Keywords" content="s6-dns dns s6dns_resolve library libs6dns" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">libs6dns</a><br /> +<a href="../">s6-dns</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The <tt>s6dns_resolve</tt> library interface </h1> + +<p> + The following functions are declared in the <tt>s6-dns/s6dns-resolve.h</tt> header, +and implemented in the <tt>libs6dns.a</tt> or <tt>libs6dns.so</tt> library. +</p> + +<h2> General information </h2> + +<p> + <tt>s6dns_resolve</tt> provides functions and macros - mostly macros - +to perform high level synchronous DNS resolution. +</p> + +<p> + 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, <em>deadline</em> +and <em>stamp</em>. <em>deadline</em> is the read-only address of a +<a href="http://skarnet.org/software/skalibs/libstddjb/tai.h">struct taia</a> +containing an absolute time which is the deadline for the function, and +<em>stamp</em> is the read-write address of a <tt>struct taia</tt> being +an accurate enough representation of the current absolute time. If +the function has not returned by *<em>deadline</em>, then it immediately +returns with a failure code and errno set to ETIMEDOUT. In every case, +*<em>stamp</em> is automatically updated so it always represents the +absolute time accurately enough. +</p> + +<p> + In a single-threaded program, the STAMP global variable can be used to +store the current time. Macros ending with <tt>_g</tt> use this variable +automatically so you don't have to provide the <em>stamp</em> argument +everytime. Additionally, several resolution functions make implicit use +of global variables such as: +</p> + +<ul> + <li> <tt>s6dns_engine_here</tt>: a global +<a href="s6dns-engine.html">s6dns_engine_t</a> storing the current +query, for sequential queries. </li> + <li> <tt>s6dns_debughook_zero</tt>: a global <tt>s6dns_debughook_t</tt> +meaning no debugging is needed. </li> + <li> <tt>s6dns_rci_here</tt>: a global +<a href="s6dns-rci.html">s6dns_rci_t</a> containing the current +resolv.conf information. </li> +</ul> + +<p> + Reentrant, non-global-using functions are also provided, with the <tt>_r</tt> +suffix. In other words, if <em>foobarfunc</em> is a resolution function, +the following prototypes are generally provided, from the simplest to the +most complex: +</p> + +<ul> + <li> <em>foobarfunc_g</em>: only the relevant parameters and a deadline +must be given, the function uses the STAMP global and maybe DNS-specific +globals </li> + <li> <em>foobarfunc</em>: a deadline and stamp must be given, the function +uses all the DNS-specific globals </li> + <li> <em>foobarfunc_r_g</em>: No DNS-specific globals are used, the +information must be given via parameters, but the STAMP global is used </li> + <li> <em>foobarfunc_r</em>: fully reentrant function using no globals +at all </li> +</ul> + +<p> + For each set of four functions, only one is documented here. +The other prototypes can be found in the <tt>s6-dns/s6dns-resolve.h</tt> file. +</p> + +<p> + Some <tt>errno</tt> codes reported by these functions do not have +exactly the system meaning given by +<a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/strerror.html">strerror()</a>. +To get a user-friendly error message, use +<tt>s6dns_constants_error_str(errno)</tt> instead. The <tt>s6dns_constants_error_str</tt> +function is declared in the <tt>s6dns-constants.h</tt> header. +</p> + +<h2> Functions </h2> + +<h3> Single query resolution </h3> + +<p> + These functions are ordered from the lowest level to the highest level. +</p> + +<h4> Basic wrapper around s6dns_engine </h4> + +<p> +<code> int s6dns_resolve_loop_r_g (s6dns_engine_t *dt, struct taia const *deadline) </code> <br /> +Resolves the query stored in <tt>dt</tt>. +Returns 1 on success or 0 on failure. +</p> + +<h4> Generic resolution functions </h4> + +<p> +<code> int s6dns_resolve_core_g (s6dns_domain_t const *d, uint16 qtype, struct taia const *deadline) </code> <br /> +Resolves the query on domain *<em>d</em> (in packet form), of type <em>qtype</em>. +Returns 0 on failure, or 1 on success, in which case +<tt>s6dns_engine_here</tt> contains the answer. +</p> + +<p> +<code> int s6dns_resolve_parse_g (s6dns_domain_t const *d, uint16 qtype, s6dns_message_rr_func_t *f, void *data, struct taia const *deadline) </code> <br /> +Resolves the query on domain *<em>d</em> (in packet form), of type <em>qtype</em>, +then parses the answer with function <em>f</em> and stores the result into <em>data</em>. +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. +</p> + +<p> + Note that the function can return 1 without appending anything to <em>data</em>. +This means that the servers confirmed that the domain exists, but <em>f</em> +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. +</p> + +<p> +<code> int s6dns_resolvenoq_g (char const *name, unsigned int len, uint16 qtype, s6dns_message_rr_func_t *f, void *data, struct taia const *deadline) </code> <br /> +Performs a query of type <em>qtype</em> on name <em>name</em> of length <em>len</em>, +without qualifying it. Parses the answer with function <em>f</em> and stores the +result into <em>data</em>. 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. +</p> + +<p> +<code> int s6dns_resolveq_g (char const *name, unsigned int len, uint16 qtype, s6dns_message_rr_func_t *f, void *data, struct taia const *deadline) </code> <br /> +Performs a query of type <em>qtype</em> on name <em>name</em> of length <em>len</em>, +qualifying it first. Parses the answer with function <em>f</em> and stores the +result into <em>data</em>. 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. +</p> + +<p> +<code> int s6dns_resolve_g (char const *name, unsigned int len, uint16 qtype, s6dns_message_rr_func_t *f, void *data, int qualif, struct taia const *deadline) </code> <br /> +Performs a query of type <em>qtype</em> on name <em>name</em> of length <em>len</em>. +Qualifies <em>name</em> first if <em>qualif</em> is nonzero; else, does not +qualify it. Parses the answer with function <em>f</em> and stores the +result into <em>data</em>. 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. +</p> + +<h4> High-level type-specific functions </h4> + +<p> +<code> int s6dns_resolve_a_g (stralloc *ips, char const *name, unsigned int len, int qualif, struct taia const *deadline) </code> <br /> +Performs an A query on name <em>name</em> of length <em>len</em>, qualifying it +iff <em>qualif</em> 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 *<em>ips</em>, using 4 bytes per answer. +</p> + +<p> +<code> int s6dns_resolve_aaaa_g (stralloc *ips, char const *name, unsigned int len, int qualif, struct taia const *deadline) </code> <br /> +Performs an AAAA query on name <em>name</em> of length <em>len</em>, qualifying it +iff <em>qualif</em> 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 *<em>ips</em>, using 16 bytes per answer. +</p> + +<p> +<code> int s6dns_resolve_aaaaa_g (genalloc *ips, char const *name, unsigned int len, int qualif, struct taia const *deadline) </code> <br /> +Performs an AAAA query and an A query at the same time on name <em>name</em> +of length <em>len</em>, qualifying it first iff <em>qualif</em> 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 *<em>ips</em>, which contains an array of +<tt>ip46_t</tt>, the skalibs structure used to store IPv4 and IPv6 addresses +indiscriminately. +</p> + +<p> +<code> int s6dns_resolve_ptr_g (genalloc *ds, char const *name, unsigned int len, int qualif, struct taia const *deadline) </code> <br /> +Performs a PTR query on name <em>name</em> of length <em>len</em>, qualifying it +iff <em>qualif</em> 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 *<em>ds</em>, which contains an array of <tt>s6dns_domain_t</tt>. +</p> + +<p> +<code> int s6dns_resolve_name4_g (genalloc *ds, char const *ip, struct taia const *deadline) </code> <br /> +Performs a PTR query on the <tt>in-addr.arpa.</tt> name representing the IPv4 +address <em>ip</em> (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 *<em>ds</em>, which contains an array of <tt>s6dns_domain_t</tt>. +</p> + +<p> +<code> int s6dns_resolve_name6_g (genalloc *ds, char const *ip, struct taia const *deadline) </code> <br /> +Performs a PTR query on the <tt>ip6.arpa.</tt> name representing the IPv6 +address <em>ip</em> (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 *<em>ds</em>, which contains an array of <tt>s6dns_domain_t</tt>. +</p> + +<p> +<code> int s6dns_resolve_name46_g (genalloc *ds, ip46_t const *ip, struct taia const *deadline) </code> <br /> +Calls <tt>s6dns_resolve_name6_g()</tt> or <tt>s6dns_resolve_name4_g()</tt> +depending on which <em>ip</em> is an IPv6 or IPv4 address. +</p> + +<p> +<code> int s6dns_resolve_ns_g (genalloc *ds, char const *name, unsigned int len, int qualif, struct taia const *deadline) </code> <br /> +Performs a NS query on name <em>name</em> of length <em>len</em>, qualifying it +iff <em>qualif</em> 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 *<em>ds</em>, which contains an array of <tt>s6dns_domain_t</tt>. +</p> + +<p> +<code> int s6dns_resolve_cname_g (genalloc *ds, char const *name, unsigned int len, int qualif, struct taia const *deadline) </code> <br /> +Performs a CNAME query on name <em>name</em> of length <em>len</em>, qualifying it +iff <em>qualif</em> 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 *<em>ds</em>, which contains an array of <tt>s6dns_domain_t</tt>. +</p> + +<p> +<code> int s6dns_resolve_hinfo_g (genalloc *hinfos, char const *name, +unsigned int len, int qualif, struct taia const *deadline) </code> <br /> + Performs an HINFO query on name <em>name</em> of length <em>len</em>, qualifying it +iff <em>qualif</em> 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 *<em>hinfos</em>, which contains an array of +<tt>s6dns_message_rr_hinfo_t</tt>. +</p> + +<p> +<code> int s6dns_resolve_mx_g (genalloc *mxs, char const *name, +unsigned int len, int qualif, struct taia const *deadline) </code> <br /> + Performs an MX query on name <em>name</em> of length <em>len</em>, qualifying it +iff <em>qualif</em> 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 *<em>mxs</em>, which contains an array of +<tt>s6dns_message_rr_mx_t</tt>. +</p> + +<p> +<code> int s6dns_resolve_soa_g (genalloc *soas, char const *name, +unsigned int len, int qualif, struct taia const *deadline) </code> <br /> + Performs an SOA query on name <em>name</em> of length <em>len</em>, qualifying it +iff <em>qualif</em> 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 *<em>soas</em>, which contains an array of +<tt>s6dns_message_rr_soa_t</tt>. +</p> + +<p> +<code> int s6dns_resolve_srv_g (genalloc *srvs, char const *name, +unsigned int len, int qualif, struct taia const *deadline) </code> <br /> + Performs an SRV query on name <em>name</em> of length <em>len</em>, qualifying it +iff <em>qualif</em> 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 *<em>srvs</em>, which contains an array of +<tt>s6dns_message_rr_srv_t</tt>. +</p> + +<p> +<code> int s6dns_resolve_txt_g (stralloc *sa, genalloc *offsets, char const *name, +unsigned int len, int qualif, struct taia const *deadline) </code> <br /> + Performs an TXT query on name <em>name</em> of length <em>len</em>, qualifying it +iff <em>qualif</em> 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: +</p> + +<ul> + <li> The resulting strings are all stored into stralloc *<em>sa</em>. +Every string is terminated by a null character. </li> + <li> A series of unsigned ints is appended to genalloc *<em>offsets</em>. +Every integer represents the offset in *<em>sa</em> at which a string is stored. +The number of appended integers is the total number of answers. </li> +</ul> + +<h4> Parallel resolution </h4> + +<p> +<code> int s6dns_resolven_loop_g (s6dns_engine_t *dtl, unsigned int n, +unsigned int or, struct taia const *deadline) </code> <br /> + Resolves the <em>n</em> queries stored in the array pointed to by <em>dtl</em>, +in parallel. If <em>or</em> is zero, it does not return before all answers +have arrived. If <em>or</em> is 1, it returns when an answer arrives, but does +not return if a query generates an error (unless all queries do so). If +<em>or</em> is 2, it returns when an answer arrives or an error occurs. +Other values of <em>or</em> are unspecified yet. + +<p> + The return code is as follows: +</p> + +<ul> + <li> If <em>or</em> is 0: -1 on a global error (i.e. not specific to +a query), or a non-negative number which is the total of successful +queries. </li> + <li> If <em>or</em> is 1 or 2: -1 on a global error, or a non-negative +number which is the index of the query that triggered the event. </li> +</ul> + +<p> + If <em>or</em> is 1, a return code of -1 with errno set to ENOENT +means that all the queries failed. +</p> + +<p> + After the function returns, the <tt>status</tt> field of each +<tt>s6dns_engine_t</tt> 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. +</p> + +<p> +<code> int s6dns_resolven_parse_g (s6dns_resolve_t const *list, unsigned int n, +struct taia const *deadline) </code> <br /> +Performs <em>n</em> complete resolutions in parallel, parsing the results. +Returns 1 in case of success or 0 if a global error occurred. +</p> + +<p> +<em>list</em> is a pointer to an array of <em>n</em> <tt>s6dns_resolve_t</tt>, +which is a structure containing at least the following fields: +</p> + +<ul> + <li> <tt>q</tt> : a <tt>s6dns_domain_t</tt> containing the query. +It must be in encoded form. </li> + <li> <tt>qtype</tt> : a <tt>uint16</tt> containing the query type. +A list of valid query types can be found in the <tt>s6dns-constants.h</tt> +header. </li> + <li> <tt>options</tt> : a <tt>uint32</tt> containing options passed +to <a href="s6dns_engine.html">s6dns_engine_init()</a>. </li> + <li> <tt>deadline</tt> : a <tt>struct taia</tt> containing the +deadline for this query, i.e. the query will fail with an ETIMEDOUT code +if no answer has arrived by then. Note that the <em>deadline</em> +argument given to s6dns_resolven_parse() is a global deadline that +can make the function return with 0 ETIMEDOUT, but is independent from +this field, which is local to every query. </li> + <li> <tt>parsefunc</tt> : a <tt>s6dns_message_rr_func_t</tt> +function that will be used to parse the answer. </li> + <li> <tt>data</tt> : a <tt>void *</tt> that will be passed as an +additional pointer to the <tt>parsefunc</tt> function; it is generally +used to store the parsing result. </li> + <li> <tt>status</tt> : an <tt>int</tt>. It does not need to be +initialized. It will contain the error code for the query after the +function returns. ECONNABORTED means that the query could not be +started at all; EAGAIN means that the query was still pending when +an error happened; other codes report various network problems. </li> +</ul> + +<p> + 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 +<a href="../skadns/">skadns</a> library. +</p> + +</body> +</html> |