diff options
Diffstat (limited to 'doc')
29 files changed, 3352 insertions, 0 deletions
diff --git a/doc/getaddrinfo.html b/doc/getaddrinfo.html new file mode 100644 index 0000000..da0469c --- /dev/null +++ b/doc/getaddrinfo.html @@ -0,0 +1,94 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns: the problem with getaddrinfo()</title> + <meta name="Description" content="s6-dns: the problem with getaddrinfo()" /> + <meta name="Keywords" content="s6-dns client library getaddrinfo API interface" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-dns</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The problem with getaddrinfo() </h1> + +<p> + The standard C library provides an API to perform name +resolution: +<a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/getaddrinfo.html">getaddrinfo()</a>, +formerly <tt>gethostbyname()</tt>. However, for DNS resolution as well as +implementation in the libc, this interface is very impractical, to the point of +being unusable. Here are a few reasons why. +</p> + +<h2> getaddrinfo() performs NSS resolution, not DNS resolution. </h2> + +<p> + I explained this point in a message to the +<a href="http://busybox.net/">Busybox</a> mailing-list. You can +<a href="http://lists.busybox.net/pipermail/busybox/2012-July/078123.html">read +the post here</a>. +(There is a mistake in that post about <tt>/etc/nsswitch.conf</tt> and +<tt>/etc/host.conf</tt> syntax; the following two messages in the thread +correct that mistake.) +</p> + +<p> + TLDR: depending on the machine configuration, it is possible that +<tt>getaddrinfo()</tt> will not use DNS at all. +</p> + +<h2> It is unboundedly synchronous. </h2> + +<p> + DNS resolution performs network I/O, which can take a non-negligible +amount of time. <tt>getaddrinfo()</tt> is a blocking call and there is +no way to specify a timeout to make it return early, so it may block +indefinitely. This is bad design. +</p> + +<p> + Also, network operations being asynchronous by nature, even a +synchronous API should provide a way to perform several queries at +once and return when one of them, or all of them, get an answer. +<tt>getaddrinfo()</tt> does not even offer that. +</p> + +<h2> It focuses on the wrong details. </h2> + +<p> + Because it's generic, <tt>getaddrinfo()</tt> is cumbersome to use. + The data structures are impractical, requiring the user to fill in +information that is irrelevant to DNS resolution. The details of the +network transport protocols are of no interest to the user who just +wants answers to his DNS queries! +</p> + +<p> + But at the same time, <tt>getaddrinfo()</tt> does not allow the +user to provide the details he wants or refine his search. It's a very +basic and monolithic entry point, with no DNS-specific knobs. For +instance, only A and AAAA queries are supported, which is clearly +insufficient. +</p> + +<h2> Conclusion </h2> + +<p> +<tt>getaddrinfo()</tt> is a toy interface. For any half-serious DNS work, +another API must be used. +</p> + +<p> + Most people who need a real DNS client library use BIND's libresolv. +<a href="libresolv.html">This page</a> explains what is wrong with it, +and what s6-dns tries to do better. +</p> + +</body> +</html> diff --git a/doc/index.html b/doc/index.html new file mode 100644 index 0000000..5263664 --- /dev/null +++ b/doc/index.html @@ -0,0 +1,175 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns - a complete DNS client suite</title> + <meta name="Description" content="s6-dns - a complete DNS client suite" /> + <meta name="Keywords" content="s6-dns s6dns s6 DNS resolution unix linux laurent bercot ska skarnet" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> s6-dns </h1> + +<h2> What is it ? </h2> + +<p> + s6-dns is a suite of DNS client programs and libraries for Unix +systems, as an alternative to the BIND, djbdns or other DNS clients. +</p> + +<p> + s6-dns may include its own series of DNS caches and servers at some +point in the future. +</p> + +<hr /> + +<ul> +<li> <a href="getaddrinfo.html">Why a separate client library ?</a> Why not just use <tt>getaddrinfo()</tt> ?</li> +<li> <a href="libresolv.html">What is wrong with libresolv, BIND's client library ?</a></li> +</ul> + +<hr /> + +<h2> Installation </h2> + +<h3> Requirements </h3> + +<ul> + <li> A POSIX-compliant system with a standard C development environment </li> + <li> GNU make, version 3.81 or later </li> + <li> <a href="http://skarnet.org/software/skalibs/">skalibs</a> version +2.0.0.0 or later </li> +</ul> + +<h3> Licensing </h3> + +<p> + s6-dns is free software. It is available under the +<a href="http://opensource.org/licenses/ISC">ISC license</a>. +</p> + +<h3> Download </h3> + +<ul> + <li> The current released version of s6-dns is <a href="s6-dns-2.0.0.0.tar.gz">2.0.0.0</a>. </li> + <li> Alternatively, you can checkout a copy of the s6-dns git repository: +<pre> git clone git://git.skarnet.org/s6-dns </pre> </li> +</ul> + +<h3> Compilation </h3> + +<ul> + <li> See the enclosed INSTALL file for installation details. </li> +</ul> + +<h3> Upgrade notes </h3> + +<ul> + <li> <a href="upgrade.html">This page</a> lists the differences to be aware of between +the previous versions of s6-dns and the current one. </li> +</ul> + +<h2> Reference </h2> + +<h3> Commands </h3> + +<p> + All these commands exit 111 if they encounter a temporary error or +hardware error, and +100 if they encounter a permanent error - such as a misuse. Short-lived +commands exit 0 on success. Other exit codes are documented in the +relevant page. +</p> + +<h4> Command-line DNS clients programs </h4> + +<ul> +<li><a href="s6-dnsip4.html">The <tt>s6-dnsip4</tt> program</a></li> +<li><a href="s6-dnsip6.html">The <tt>s6-dnsip6</tt> program</a></li> +<li><a href="s6-dnsname.html">The <tt>s6-dnsname</tt> program</a></li> +<li><a href="s6-dnsmx.html">The <tt>s6-dnsmx</tt> program</a></li> +<li><a href="s6-dnsns.html">The <tt>s6-dnsns</tt> program</a></li> +<li><a href="s6-dnssoa.html">The <tt>s6-dnssoa</tt> program</a></li> +<li><a href="s6-dnssrv.html">The <tt>s6-dnssrv</tt> program</a></li> +<li><a href="s6-dnstxt.html">The <tt>s6-dnstxt</tt> program</a></li> +</ul> + +<h4> Filtering tools </h4> + +<ul> +<li><a href="s6-dnsip4-filter.html">The <tt>s6-dnsip4-filter</tt> program</a></li> +<li><a href="s6-dnsip6-filter.html">The <tt>s6-dnsip6-filter</tt> program</a></li> +<li><a href="s6-dnsname-filter.html">The <tt>s6-dnsname-filter</tt> program</a></li> +</ul> + +<h4> Command-line qualification </h4> + +<ul> +<li><a href="s6-dnsqualify.html">The <tt>s6-dnsqualify</tt> program</a></li> +</ul> + +<h4> DNS analysis and debug tools </h4> + +<ul> +<li><a href="s6-dnsq.html">The <tt>s6-dnsq</tt> program</a></li> +<li><a href="s6-dnsqr.html">The <tt>s6-dnsqr</tt> program</a></li> +</ul> + +<h4> Miscellaneous utilities </h4> + +<ul> +<li><a href="s6-randomip.html">The <tt>s6-randomip</tt> program</a></li> +</ul> + + +<h3> Libraries </h3> + +<h4> Protocol implementation and synchronous resolution </h4> + +<ul> +<li><a href="libs6dns/">The <tt>s6dns</tt> library interface</a></li> +</ul> + +<h4> Asynchronous resolution </h4> + +<ul> +<li><a href="skadns/">The <tt>skadns</tt> library interface</a></li> +</ul> + +<hr /> + +<a name="related"> +<h2> Related resources </h2> +</a> + +<h3> s6-dns discussion </h3> + +<ul> + <li> <tt>s6-dns</tt> is discussed on the +<a href="http://skarnet.org/lists.html#skaware">skaware</a> mailing-list. </li> + <li> It can also be discussed on the +<a href="http://cr.yp.to/lists.html#dns">cr.yp.to dns mailing-list</a>. </li> +</ul> + +<h3> Similar work </h3> + +<ul> + <li> <a href="http://www.isc.org/software/bind">BIND</a> is the most widely +used DNS software suite on the Internet. It's also arguably the most +<a href="http://cr.yp.to/djbdns/blurb/unbind.html">buggy</a>, +convoluted and impossible to understand. </li> + <li> <a href="http://cr.yp.to/djbdns.html">djbdns</a> is DJB's DNS suite. +It works very well, but is unfortunately unmaintained by the author. s6-dns +follows <a href="http://skarnet.org/software/skalibs/djblegacy.html">the +same design principles</a>. </li> +</ul> + +</body> +</html> diff --git a/doc/libresolv.html b/doc/libresolv.html new file mode 100644 index 0000000..7a9fd31 --- /dev/null +++ b/doc/libresolv.html @@ -0,0 +1,140 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns: the problem with libresolv</title> + <meta name="Description" content="s6-dns: the problem with libresolv" /> + <meta name="Keywords" content="s6-dns client library libresolv BIND API interface" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-dns</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The problem with libresolv </h1> + +<p> + The BIND name server software comes with its own client library, +named <em>libresolv</em>. +</p> + +<p> + As can be expected from an ISC product, libresolv is not good software. +Here are a few reasons why. +</p> + +<h2> libresolv's security model is flawed. </h2> + +<p> + The same people who wrote BIND wrote libresolv. That is the amount of +trust you can place in libresolv. Ten years ago, the security status +of libresolv looked like +<a href="http://cr.yp.to/djbdns/res-disaster.html">this</a>. I am not +confident that is has improved: bugs in the software may have been +fixed, but new ones will appear, and most importantly, the security +management policy at ISC is still the same: security holes will be +denied instead of acknowledged and worked upon. +</p> + +<p> + If you find a bug, and <em>a fortiori</em> a security hole, in +s6-dns, you can be sure it will be fixed promptly with apologies +from the author. skarnet.org doesn't do obfuscation, and never lets +politics get in the way of technical quality. +</p> + +<h2> libresolv is unboundedly synchronous. </h2> + +<p> + You'd expect a real DNS client library to do better in this aspect +than <a href="getaddrinfo.html">getaddrinfo()</a>, but no: libresolv's +function calls are still purely synchronous and may uncontrollably +block if the network is unresponsive. +</p> + +<p> + Additionally, libresolv <em>only</em> provides a synchronous +interface to clients. Despite the fundamentally asynchronous nature +of DNS, and the need to implement asynchronous primitives +internally, only blocking calls are made available in the API. +This forces users to stack yet another piece of software on top +of their dependencies if they need asynchronous DNS resolution. +</p> + +<p> + libs6dns provides several layers of asynchronous interfaces. +The user has access to +<a href="libs6dns/s6dns_engine.html">low-level packet sending +and receiving</a>, to +<a href="libs6dns/s6dns_resolve.html#parallel">synchronous +resolution of several queries at once</a>, and to a +<a href="skadns/">real high-level asynchronous DNS library</a>. +</p> + +<h2> It is too big for what it does. </h2> + +<p> + The <tt>libresolv-2.13.so</tt> binary file compiled for an i386 +Debian Linux system is roughly 71k bytes. The <tt>libs6dns.so.2.0</tt> +file, for the same system, is roughly 41k bytes, while offering +more functionality. libresolv does not do any high-level answer +parsing, so the user still has to do some work after the libresolv +calls. s6-dns tries to be small and still provide the user comfortable +interfaces. +</p> + +<h2> The API is cumbersome to use. </h2> + +<p> + Some examples of less-than-ideal interfaces for the users: +</p> + +<ul> + <li> There is a flag in libresolv's global state structure that +determines if queries are to be sent recursive or iterative. Which +means that a program that needs to make both recursive and iterative +queries must duplicate this state structure and use one for recursive +queries, one for iterative queries. Why this complexity ? The +recursive flag should be given for every query, not be a part +of the resolver state. </li> + <li> When a libresolv answer arrives but doesn't fit into the +user-supplied buffer, the query is discarded and has to be retried. +Does "network efficiency" ring a bell ? Also, the length of +the original answer is returned by the first call, which is a good +thing: the user can now provide a large enough buffer so the call +succeeds the next time, right ? Wrong. The next answer can +be different from the first, and in particular, longer, which +means that the next query can <em>still fail</em>. </li> +</ul> + +<p> + There is a reason why system calls and local functions take +user-supplied buffers as arguments. They are relatively fast, it is +not too costly to call them again if the buffer is too small the +first time, and the result is consistent, i.e. after the first call, +the right buffer length is <em>known</em>. But functions making +network exchanges with variable-length results from one call to +another ? Those <em>need</em> heap-allocated storage. It is +good design to avoid using the heap whenever possible, but it is +not good design to waste network round-trips to save a <tt>malloc()</tt>. +</p> + +<h2> Conclusion </h2> + +<p> + Like many other "standards", and C library interfaces in particular, +<tt>libresolv</tt> is at best a mediocre one, that people use because +there has been nothing better so far. +</p> + +<p> + s6-dns tries to be an alternative solution - not as ambitious, +but based on solid design principles and a reliable code base. +</p> + +</body> +</html> 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> diff --git a/doc/s6-dnsip4-filter.html b/doc/s6-dnsip4-filter.html new file mode 100644 index 0000000..5433438 --- /dev/null +++ b/doc/s6-dnsip4-filter.html @@ -0,0 +1,111 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns: the s6-dnsip4-filter program</title> + <meta name="Description" content="s6-dns: the s6-dnsip4-filter program" /> + <meta name="Keywords" content="s6-dns client s6-dnsip4-filter dnsip domain name ip address ipv4 filter" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-dns</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The s6-dnsip4-filter program </h1> + +<p> + s6-dnsip4-filter reads domain names on its standard input and +prints the corresponding IPv4 addresses on its standard output. +</p> + +<h2> Interface </h2> + +<pre> + s6-dnsip4-filter [ -l <em>maxlines</em> ] [ -c <em>maxconn</em> ] [ -t <em>timeout</em> ] [ -f <em>normalfmt</em> ] [ -e <em>errorfmt</em> ] +</pre> + +<ul> + <li> s6-dnsip4-filter reads lines from its stdin, processes them, and prints +the processed lines to its stdout, in the same order. It exits 0 when it +reads EOF on stdin. </li> + <li> Every line starting with a domain name is processed. Lines not +starting with a domain name are not, and the formatting rules treat them +as a pure "remainder". </li> + <li> For every processed line, an A query is made, and the result is +printed according to the formatting rules. The domain is not qualified +before being resolved. </li> + <li> By default, s6-dnsip4-filter looks for DNS cache addresses in the +<tt>/etc/resolv.conf</tt> file. If the DNSCACHEIP environment variable is set +and contains a list of IP (v4 or v6) addresses, separated by commas, +semicolons, spaces, tabs, newlines or carriage returns, then this list +is used instead. </li> +</ul> + +<h2> Options </h2> + +<ul> + <li> <tt>-l</tt> <em>maxlines</em> : maximum lines. s6-dnsip4-filter +will keep at most <em>maxlines</em> lines in memory at the same time. If line +<em>n</em> is still waiting for resolution and cannot be printed, then +s6-dnsip4-filter will stop reading from stdin before line <em>n+maxlines</em>, +until the result arrives for line <em>n</em>. By default, <em>maxlines</em> +is 256. </li> + <li> <tt>-c</tt> <em>maxconn</em> : maximum concurrent resolutions. +s6-dnsip4-filter will perform at most <em>maxconn</em> resolutions in +parallel at the same time. <em>maxlines</em> cannot be lesser than <em>maxconn</em>. +By default, <em>maxconn</em> is 128. </li> + <li> <tt>-t</tt> <em>timeout</em> : if any resolution takes more +than <em>timeout</em> milliseconds, then it is aborted and printed as a +timeout error. By default, <em>timeout</em> is 0, which means no timeout. </li> + <li> <tt>-f</tt> <em>normalfmt</em> : print the positive results according to +the <em>normalfmt</em> format string. By default, <em>normalfmt</em> is +<tt>%s=%d%w%r</tt>, which means: print the original domain name, then an equal +sign, then the corresponding IPv4 address, then the remainder of the line. </li> + <li> <tt>-e</tt> <em>errorfmt</em> : print the negative results according to +the <em>errorfmt</em> format string. By default, <em>errorfmt</em> is +<tt>%s=<%e%>%w%r</tt>, which means: print the original domain name, then an equal +sign, then the error message between angle brackets, then the remainder of the line. </li> +</ul> + +<h2> Formatting rules </h2> + +<p> + <em>normalfmt</em> and <em>errorfmt</em> are format strings, i.e. they tell the +program how a line must be printed. The following sequences are recognized: +</p> + +<ul> + <li> <tt>%%</tt> prints a single <tt>%</tt> character </li> + <li> <tt>%s</tt> prints the original domain name </li> + <li> <tt>%d</tt> prints the IP address, if any </li> + <li> <tt>%e</tt> prints the error message, if any </li> + <li> <tt>%w%r</tt> prints the remainder of the input line </li> +</ul> + +<h2> Example </h2> + +<pre> + s6-dnsns google.com | s6-dnsip4-filter -f "%d" +</pre> + +<p> + prints all the nameserver addresses for the <tt>google.com</tt> +domain. This is useful, for instance, to give the result as an +argument to <a href="s6-dnsq.html">s6-dnsq</a>. +</p> + +<h2> Notes </h2> + +<p> + s6-dnsip4-filter does not perform DNS resolutions itself. Instead, if forks +a <a href="skadns/skadnsd.html">skadnsd</a> child and sends it queries, getting +the results asynchronously. The s6-dns filter programs have actually been +written as example uses of the <a href="skadns/">skadns library</a>. +</p> + +</body> +</html> diff --git a/doc/s6-dnsip4.html b/doc/s6-dnsip4.html new file mode 100644 index 0000000..72f585b --- /dev/null +++ b/doc/s6-dnsip4.html @@ -0,0 +1,63 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns: the s6-dnsip4 program</title> + <meta name="Description" content="s6-dns: the s6-dnsip4 program" /> + <meta name="Keywords" content="s6-dns client s6-dnsip4 dnsip domain name ip address ipv4" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-dns</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The s6-dnsip4 program </h1> + +<p> + s6-dnsip4 finds the IPv4 addresses associated to a domain name. +</p> + +<h2> Interface </h2> + +<pre> + s6-dnsip4 [ -q ] [ -r ] [ -t <em>timeout</em> ] <em>domain</em> +</pre> + +<ul> + <li> s6-dnsip4 makes an A query for the name <em>domain</em>. It +waits for the result and prints the obtained IPv4 addresses, one per line, +then exits 0. </li> + <li> If the domain exists but no relevant field has been found, it exits 1. </li> + <li> If the DNS answered but no answer is available, it prints a relevant +error message and exits 2. </li> + <li> By default, s6-dnsip4 looks for DNS cache addresses in the +<tt>/etc/resolv.conf</tt> file. If the DNSCACHEIP environment variable is set +and contains a list of IP (v4 or v6) addresses, separated by commas, +semicolons, spaces, tabs, newlines or carriage returns, then this list +is used instead. </li> +</ul> + +<h2> Options </h2> + +<ul> + <li> <tt>-q</tt> : qualify. Qualifies <em>domain</em> before resolution, +according to suffixes found in <tt>/etc/resolv.conf</tt>. If the DNSQUALIFY +environment variable is set and contains a list of suffixes separated by spaces, +tabs, newlines or carriage returns, then this list is used instead. By +default, no qualification is used: if <em>domain</em> is not a FQDN, a dot +is just appended to it. </li> + <li> <tt>-r</tt> : random. By default, the program does not sort the +result, but prints them in the order received from the DNS. With this +option, it performs a random permutation on the results before printing +them. </li> + <li> <tt>-t</tt> <em>timeout</em> : if the resolution takes more +than <em>timeout</em> milliseconds, then it exits 99 right away with an error +message. By default, <em>timeout</em> is 0, which means no timeout. </li> +</ul> + +</body> +</html> diff --git a/doc/s6-dnsip6-filter.html b/doc/s6-dnsip6-filter.html new file mode 100644 index 0000000..7cbad6b --- /dev/null +++ b/doc/s6-dnsip6-filter.html @@ -0,0 +1,99 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns: the s6-dnsip6-filter program</title> + <meta name="Description" content="s6-dns: the s6-dnsip6-filter program" /> + <meta name="Keywords" content="s6-dns client s6-dnsip6-filter dnsip domain name ip address ipv6 filter" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-dns</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The s6-dnsip6-filter program </h1> + +<p> + s6-dnsip6-filter reads domain names on its standard input and +prints the corresponding IPv6 addresses on its standard output. +</p> + +<h2> Interface </h2> + +<pre> + s6-dnsip6-filter [ -l <em>maxlines</em> ] [ -c <em>maxconn</em> ] [ -t <em>timeout</em> ] [ -f <em>normalfmt</em> ] [ -e <em>errorfmt</em> ] +</pre> + +<ul> + <li> s6-dnsip6-filter reads lines from its stdin, processes them, and prints +the processed lines to its stdout, in the same order. It exits 0 when it +reads EOF on stdin. </li> + <li> Every line starting with a domain name is processed. Lines not +starting with a domain name are not, and the formatting rules treat them +as a pure "remainder". </li> + <li> For every processed line, an AAAA query is made, and the result is +printed according to the formatting rules. The domain is not qualified before +being resolved. </li> + <li> By default, s6-dnsip6-filter looks for DNS cache addresses in the +<tt>/etc/resolv.conf</tt> file. If the DNSCACHEIP environment variable is set +and contains a list of IP (v4 or v6) addresses, separated by commas, +semicolons, spaces, tabs, newlines or carriage returns, then this list +is used instead. </li> +</ul> + +<h2> Options </h2> + +<ul> + <li> <tt>-l</tt> <em>maxlines</em> : maximum lines. s6-dnsip6-filter +will keep at most <em>maxlines</em> lines in memory at the same time. If line +<em>n</em> is still waiting for resolution and cannot be printed, then +s6-dnsip6-filter will stop reading from stdin before line <em>n+maxlines</em>, +until the result arrives for line <em>n</em>. By default, <em>maxlines</em> +is 256. </li> + <li> <tt>-c</tt> <em>maxconn</em> : maximum concurrent resolutions. +s6-dnsip6-filter will perform at most <em>maxconn</em> resolutions in +parallel at the same time. <em>maxlines</em> cannot be lesser than <em>maxconn</em>. +By default, <em>maxconn</em> is 128. </li> + <li> <tt>-t</tt> <em>timeout</em> : if any resolution takes more +than <em>timeout</em> milliseconds, then it is aborted and printed as a +timeout error. By default, <em>timeout</em> is 0, which means no timeout. </li> + <li> <tt>-f</tt> <em>normalfmt</em> : print the positive results according to +the <em>normalfmt</em> format string. By default, <em>normalfmt</em> is +<tt>%s=%d%w%r</tt>, which means: print the original domain name, then an equal +sign, then the corresponding IPv6 address, then the remainder of the line. </li> + <li> <tt>-e</tt> <em>errorfmt</em> : print the negative results according to +the <em>errorfmt</em> format string. By default, <em>errorfmt</em> is +<tt>%s=<%e%>%w%r</tt>, which means: print the original domain name, then an equal +sign, then the error message between angle brackets, then the remainder of the line. </li> +</ul> + +<h2> Formatting rules </h2> + +<p> + <em>normalfmt</em> and <em>errorfmt</em> are format strings, i.e. they tell the +program how a line must be printed. The following sequences are recognized: +</p> + +<ul> + <li> <tt>%%</tt> prints a single <tt>%</tt> character </li> + <li> <tt>%s</tt> prints the original domain name </li> + <li> <tt>%d</tt> prints the IP address, if any </li> + <li> <tt>%e</tt> prints the error message, if any </li> + <li> <tt>%w%r</tt> prints the remainder of the input line </li> +</ul> + +<h2> Notes </h2> + +<p> + s6-dnsip6-filter does not perform DNS resolutions itself. Instead, if forks +a <a href="skadns/skadnsd.html">skadnsd</a> child and sends it queries, getting +the results asynchronously. The s6-dns filter programs have actually been +written as example uses of the <a href="skadns/">skadns library</a>. +</p> + +</body> +</html> diff --git a/doc/s6-dnsip6.html b/doc/s6-dnsip6.html new file mode 100644 index 0000000..d417011 --- /dev/null +++ b/doc/s6-dnsip6.html @@ -0,0 +1,73 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns: the s6-dnsip6 program</title> + <meta name="Description" content="s6-dns: the s6-dnsip6 program" /> + <meta name="Keywords" content="s6-dns client s6-dnsip6 dnsip domain name ip address ipv6" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-dns</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The s6-dnsip6 program </h1> + +<p> + s6-dnsip6 finds the IPv6 addresses associated to a domain name. +</p> + +<h2> Interface </h2> + +<pre> + s6-dnsip6 [ -q ] [ -r ] [ -t <em>timeout</em> ] <em>domain</em> +</pre> + +<ul> + <li> s6-dnsip6 makes an AAAA query for the name <em>domain</em>. It +waits for the result and prints the obtained IPv6 addresses, one per line, +then exits 0. </li> + <li> If the domain exists but no relevant field has been found, it exits 1. </li> + <li> If the DNS answered but no answer is available, it prints a relevant +error message and exits 2. </li> + <li> By default, s6-dnsip6 looks for DNS cache addresses in the +<tt>/etc/resolv.conf</tt> file. If the DNSCACHEIP environment variable is set +and contains a list of IP (v4 or v6) addresses, separated by commas, +semicolons, spaces, tabs, newlines or carriage returns, then this list +is used instead. </li> +</ul> + +<h2> Options </h2> + +<ul> + <li> <tt>-q</tt> : qualify. Qualifies <em>domain</em> before resolution, +according to suffixes found in <tt>/etc/resolv.conf</tt>. If the DNSQUALIFY +environment variable is set and contains a list of suffixes separated by spaces, +tabs, newlines or carriage returns, then this list is used instead. By +default, no qualification is used: if <em>domain</em> is not a FQDN, a dot +is just appended to it. </li> + <li> <tt>-r</tt> : random. By default, the program does not sort the +result, but prints them in the order received from the DNS. With this +option, it performs a random permutation on the results before printing +them. </li> + <li> <tt>-t</tt> <em>timeout</em> : if the resolution takes more +than <em>timeout</em> milliseconds, then it exits 99 right away with an error +message. By default, <em>timeout</em> is 0, which means no timeout. </li> +</ul> + +<h2> Notes </h2> + +<p> + Bear in mind that <em>making AAAA queries</em> is very different, and +totally independent, from <em>using IPv6 transport for the DNS queries</em>. +Even if the underlying skalibs has been compiled without IPv6 support, +or IPv6 DNS transport is unavailable for any reason, you can still perform +AAAA queries and s6-dnsip6 will answer correctly. +</p> + +</body> +</html> diff --git a/doc/s6-dnsmx.html b/doc/s6-dnsmx.html new file mode 100644 index 0000000..1396aed --- /dev/null +++ b/doc/s6-dnsmx.html @@ -0,0 +1,64 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns: the s6-dnsmx program</title> + <meta name="Description" content="s6-dns: the s6-dnsmx program" /> + <meta name="Keywords" content="s6-dns client s6-dnsmx dnsmx domain name mx mail exchanger" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-dns</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The s6-dnsmx program </h1> + +<p> + s6-dnsmx finds the MX information associated to a domain name. +</p> + +<h2> Interface </h2> + +<pre> + s6-dnsmx [ -q ] [ -r ] [ -t <em>timeout</em> ] <em>domain</em> +</pre> + +<ul> + <li> s6-dnsmx makes an MX query for the name <em>domain</em>. It +waits for the result and prints the obtained information, one exchanger +per line, then exits 0. It prints the preference, then a space, then +the exchanger name. </li> + <li> If the domain exists but no relevant field has been found, it exits 1. </li> + <li> If the DNS answered but no answer is available, it prints a relevant +error message and exits 2. </li> + <li> By default, s6-dnsmx looks for DNS cache addresses in the +<tt>/etc/resolv.conf</tt> file. If the DNSCACHEIP environment variable is set +and contains a list of IP (v4 or v6) addresses, separated by commas, +semicolons, spaces, tabs, newlines or carriage returns, then this list +is used instead. </li> +</ul> + +<h2> Options </h2> + +<ul> + <li> <tt>-q</tt> : qualify. Qualifies <em>domain</em> before resolution, +according to suffixes found in <tt>/etc/resolv.conf</tt>. If the DNSQUALIFY +environment variable is set and contains a list of suffixes separated by spaces, +tabs, newlines or carriage returns, then this list is used instead. By +default, no qualification is used: if <em>domain</em> is not a FQDN, a dot +is just appended to it. </li> + <li> <tt>-r</tt> : random. By default, the program does not sort the +result, but prints them in the order received from the DNS. With this +option, it performs a random permutation on the results before printing +them. </li> + <li> <tt>-t</tt> <em>timeout</em> : if the resolution takes more +than <em>timeout</em> milliseconds, then it exits 99 right away with an error +message. By default, <em>timeout</em> is 0, which means no timeout. </li> +</ul> + +</body> +</html> diff --git a/doc/s6-dnsname-filter.html b/doc/s6-dnsname-filter.html new file mode 100644 index 0000000..1554270 --- /dev/null +++ b/doc/s6-dnsname-filter.html @@ -0,0 +1,103 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns: the s6-dnsname-filter program</title> + <meta name="Description" content="s6-dns: the s6-dnsname-filter program" /> + <meta name="Keywords" content="s6-dns client s6-dnsname-filter dnsname domain name ptr ip address filter" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-dns</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The s6-dnsname-filter program </h1> + +<p> + s6-dnsname-filter reads IP addresses on its standard input and +prints the corresponding domain names on its standard output. +</p> + +<h2> Interface </h2> + +<pre> + s6-dnsname-filter [ -4 ] [ -6 ] [ -l <em>maxlines</em> ] [ -c <em>maxconn</em> ] [ -t <em>timeout</em> ] [ -f <em>normalfmt</em> ] [ -e <em>errorfmt</em> ] +</pre> + +<ul> + <li> s6-dnsname-filter reads lines from its stdin, processes them, and prints +the processed lines to its stdout, in the same order. It exits 0 when it +reads EOF on stdin. </li> + <li> Every line starting with an IP address is processed. Lines not +starting with an IP address are not, and the formatting rules treat them +as a pure "remainder". </li> + <li> For every processed line, the read IP address is converted to an +<tt>in-addr.arpa.</tt> or <tt>ip6.arpa.</tt> domain on which a PTR query is made, +and the result is printed according to the formatting rules. </li> + <li> By default, s6-dnsname-filter looks for DNS cache addresses in the +<tt>/etc/resolv.conf</tt> file. If the DNSCACHEIP environment variable is set +and contains a list of IP (v4 or v6) addresses, separated by commas, +semicolons, spaces, tabs, newlines or carriage returns, then this list +is used instead. </li> +</ul> + +<h2> Options </h2> + +<ul> + <li> <tt>-4</tt> : scan for IPv4 addresses. </li> + <li> <tt>-6</tt> : scan for IPv6 addresses. Both the <tt>-4</tt> and +<tt>-6</tt> options may be given. If none is given, by default +s6-dnsname-filter will only scan for IPv4 addresses. </li> + <li> <tt>-l</tt> <em>maxlines</em> : maximum lines. s6-dnsname-filter +will keep at most <em>maxlines</em> lines in memory at the same time. If line +<em>n</em> is still waiting for resolution and cannot be printed, then +s6-dnsname-filter will stop reading from stdin before line <em>n+maxlines</em>, +until the result arrives for line <em>n</em>. By default, <em>maxlines</em> +is 256. </li> + <li> <tt>-c</tt> <em>maxconn</em> : maximum concurrent resolutions. +s6-dnsname-filter will perform at most <em>maxconn</em> resolutions in +parallel at the same time. <em>maxlines</em> cannot be lesser than <em>maxconn</em>. +By default, <em>maxconn</em> is 128. </li> + <li> <tt>-t</tt> <em>timeout</em> : if any resolution takes more +than <em>timeout</em> milliseconds, then it is aborted and printed as a +timeout error. By default, <em>timeout</em> is 0, which means no timeout. </li> + <li> <tt>-f</tt> <em>normalfmt</em> : print the positive results according to +the <em>normalfmt</em> format string. By default, <em>normalfmt</em> is +<tt>%s=%d%w%r</tt>, which means: print the original IP address, then an equal +sign, then the corresponding domain name, then the remainder of the line. </li> + <li> <tt>-e</tt> <em>errorfmt</em> : print the negative results according to +the <em>errorfmt</em> format string. By default, <em>errorfmt</em> is +<tt>%s=<%e%>%w%r</tt>, which means: print the original IP address, then an equal +sign, then the error message between angle brackets, then the remainder of the line. </li> +</ul> + +<h2> Formatting rules </h2> + +<p> + <em>normalfmt</em> and <em>errorfmt</em> are format strings, i.e. they tell the +program how a line must be printed. The following sequences are recognized: +</p> + +<ul> + <li> <tt>%%</tt> prints a single <tt>%</tt> character </li> + <li> <tt>%s</tt> prints the original IP address </li> + <li> <tt>%d</tt> prints the domain name, if any </li> + <li> <tt>%e</tt> prints the error message, if any </li> + <li> <tt>%w%r</tt> prints the remainder of the input line </li> +</ul> + +<h2> Notes </h2> + +<p> + s6-dnsname-filter does not perform DNS resolutions itself. Instead, if forks +a <a href="skadns/skadnsd.html">skadnsd</a> child and sends it queries, getting +the results asynchronously. The s6-dns filter programs have actually been +written as example uses of the <a href="skadns/">skadns library</a>. +</p> + +</body> +</html> diff --git a/doc/s6-dnsname.html b/doc/s6-dnsname.html new file mode 100644 index 0000000..0c0c5b0 --- /dev/null +++ b/doc/s6-dnsname.html @@ -0,0 +1,72 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns: the s6-dnsname program</title> + <meta name="Description" content="s6-dns: the s6-dnsname program" /> + <meta name="Keywords" content="s6-dns client s6-dnsname dnsname domain name ip address ipv4 ipv6" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-dns</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The s6-dnsname program </h1> + +<p> + s6-dnsname finds the name associated to an IPv4 or IPv6 address. +</p> + +<h2> Interface </h2> + +<pre> + s6-dnsname [ -4 | -6 ] [ -r ] [ -t <em>timeout</em> ] <em>ip</em> +</pre> + +<ul> + <li> s6-dnsname converts the IP address <em>ip</em> to a name +ending in <tt>in-addr.arpa.</tt> or <tt>ip6.arpa.</tt> then makes a +PTR query for this name. +It waits for the result and prints the obtained names, one per line, +then exits 0. </li> + <li> If the domain exists but no relevant field has been found, it exits 1. </li> + <li> If the DNS answered but no answer is available, it prints a relevant +error message and exits 2. </li> + <li> By default, s6-dnsname looks for DNS cache addresses in the +<tt>/etc/resolv.conf</tt> file. If the DNSCACHEIP environment variable is set +and contains a list of IP (v4 or v6) addresses, separated by commas, +semicolons, spaces, tabs, newlines or carriage returns, then this list +is used instead. </li> +</ul> + +<h2> Options </h2> + +<ul> + <li> <tt>-4</tt> : interpret <em>ip</em> as an IPv4 address. </li> + <li> <tt>-6</tt> : interpret <em>ip</em> as an IPv6 address. +If neither of the <tt>-4</tt> and <tt>-6</tt> is given, or if both are +given, then <em>ip</em> will be interpreted as v4 or v6 depending on +its syntax. </li> + <li> <tt>-r</tt> : random. By default, the program does not sort the +result, but prints them in the order received from the DNS. With this +option, it performs a random permutation on the results before printing +them. </li> + <li> <tt>-t</tt> <em>timeout</em> : if the resolution takes more +than <em>timeout</em> milliseconds, then it exits 99 right away with an error +message. By default, <em>timeout</em> is 0, which means no timeout. </li> +</ul> + +<h2> Notes </h2> + +<ul> + <li> If the underlying skalibs has been compiled with IPv6 support disabled, +s6-dnsname will not be able to use IPv6 transport for its resolution, but it +will still accept and resolve IPv6 addresses. </li> +</ul> + +</body> +</html> diff --git a/doc/s6-dnsns.html b/doc/s6-dnsns.html new file mode 100644 index 0000000..c15a7df --- /dev/null +++ b/doc/s6-dnsns.html @@ -0,0 +1,63 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns: the s6-dnsns program</title> + <meta name="Description" content="s6-dns: the s6-dnsns program" /> + <meta name="Keywords" content="s6-dns client s6-dnsns domain name nameserver ns rr field" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-dns</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The s6-dnsns program </h1> + +<p> + s6-dnsns finds the relevant nameservers providing data for a domain. +</p> + +<h2> Interface </h2> + +<pre> + s6-dnsns [ -q ] [ -r ] [ -t <em>timeout</em> ] <em>domain</em> +</pre> + +<ul> + <li> s6-dnsns makes an NS query for the name <em>domain</em>. It +waits for the result and prints the obtained information, one name +per line, then exits 0. </li> + <li> If the domain exists but no relevant field has been found, it exits 1. </li> + <li> If the DNS answered but no answer is available, it prints a relevant +error message and exits 2. </li> + <li> By default, s6-dnsns looks for DNS cache addresses in the +<tt>/etc/resolv.conf</tt> file. If the DNSCACHEIP environment variable is set +and contains a list of IP (v4 or v6) addresses, separated by commas, +semicolons, spaces, tabs, newlines or carriage returns, then this list +is used instead. </li> +</ul> + +<h2> Options </h2> + +<ul> + <li> <tt>-q</tt> : qualify. Qualifies <em>domain</em> before resolution, +according to suffixes found in <tt>/etc/resolv.conf</tt>. If the DNSQUALIFY +environment variable is set and contains a list of suffixes separated by spaces, +tabs, newlines or carriage returns, then this list is used instead. By +default, no qualification is used: if <em>domain</em> is not a FQDN, a dot +is just appended to it. </li> + <li> <tt>-r</tt> : random. By default, the program does not sort the +result, but prints them in the order received from the DNS. With this +option, it performs a random permutation on the results before printing +them. </li> + <li> <tt>-t</tt> <em>timeout</em> : if the resolution takes more +than <em>timeout</em> milliseconds, then it exits 99 right away with an error +message. By default, <em>timeout</em> is 0, which means no timeout. </li> +</ul> + +</body> +</html> diff --git a/doc/s6-dnsq.html b/doc/s6-dnsq.html new file mode 100644 index 0000000..9a22602 --- /dev/null +++ b/doc/s6-dnsq.html @@ -0,0 +1,82 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns: the s6-dnsq program</title> + <meta name="Description" content="s6-dns: the s6-dnsq program" /> + <meta name="Keywords" content="s6-dns client s6-dnsq dnsq analysis debug" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-dns</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The s6-dnsq program </h1> + +<p> + s6-dnsq is an analysis and debug tool. It performs a non-recursive DNS query +to a given list of servers, +then prints the contents of the answer packet, and optionally debug +information during the resolution. +</p> + +<h2> Interface </h2> + +<pre> + s6-dnsq [ -1 | -2 ] [ -t <em>timeout</em> ] [ -D <em>level</em> ] <em>qtype</em> <em>domain</em> <em>serverlist</em> +</pre> + +<ul> + <li> s6-dnsq makes an iterative DNS query of type <em>qtype</em> for the name <em>domain</em> +to <em>serverlist</em>. +It prints the answer packet, in human-readable form, to its standard output, +then exits 0. </li> + <li> It does not qualify <em>domain</em>. </li> + <li> If the resolution fails for some reason, s6-dnsq exits 2. </li> + <li> <em>serverlist</em> is a list of IP addresses (v4 or v6), one or more addresses +per argument on the command line (so you can use, for instance, +<tt>`s6-dnsip4 ns.example.com`</tt> as argument, and get all the addresses for +<tt>ns.example.com</tt> in your server list). +Servers are tried in the order given, until a definitive +answer is obtained or s6-dnsq runs out of server addresses. </li> +</ul> + +<h2> Options </h2> + +<ul> + <li> <tt>-1</tt> : send debug information to stdout. </li> + <li> <tt>-2</tt> : send debug information to stderr. This is the default. Note that +those options only apply to debug output, not to the regular packet dump, which +is always printed to stdout. </li> + <li> <tt>-t</tt> <em>timeout</em> : if the resolution takes more +than <em>timeout</em> milliseconds, then it exits 99 right away with an error +message. By default, <em>timeout</em> is 0, which means no timeout. </li> + <li> <tt>-D</tt> <em>level</em> : produce debug output during +resolution. If <em>level</em> is: + <ul> + <li> 0: no debug output is produced </li> + <li> 1: information is printed when s6-dnsq receives a DNS packet from a server </li> + <li> 2: information is printed before and after s6-dnsq sends a DNS packet to a server </li> + <li> 3: both 1. and 2. apply </li> + </ul> +</ul> + +<h2> Notes </h2> + +<ul> + <li> TXT records are printed in a quoted form similar to +<a href="http://skarnet.org/software/s6-portable-utils/s6-quote.html">s6-quote</a>'s +output. </li> + <li> If s6-dnsq finds a record it cannot print, such as an unknown RR type, +it dumps its contents in the same quoted form. </li> + <li> The normal output format should be stable, so you can write programs that +automatically parse it. However, the debug output format is undocumented and subject +to change. </li> +</ul> + +</body> +</html> diff --git a/doc/s6-dnsqr.html b/doc/s6-dnsqr.html new file mode 100644 index 0000000..ce308bd --- /dev/null +++ b/doc/s6-dnsqr.html @@ -0,0 +1,80 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns: the s6-dnsqr program</title> + <meta name="Description" content="s6-dns: the s6-dnsqr program" /> + <meta name="Keywords" content="s6-dns client s6-dnsqr dnsqr analysis debug" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-dns</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The s6-dnsqr program </h1> + +<p> + s6-dnsqr is an analysis and debug tool. It performs a DNS resolution, +then prints the contents of the answer packet, and optionally debug +information during the resolution. +</p> + +<h2> Interface </h2> + +<pre> + s6-dnsqr [ -1 | -2 ] [ -t <em>timeout</em> ] [ -D <em>level</em> ] <em>qtype</em> <em>domain</em> +</pre> + +<ul> + <li> s6-dnsqr makes a recursive DNS query of type <em>qtype</em> for the name <em>domain</em>. +It prints the answer packet, in human-readable form, to its standard output, +then exits 0. </li> + <li> It does not qualify <em>domain</em>. </li> + <li> If the resolution fails for some reason, s6-dnsqr exits 2. </li> + <li> By default, s6-dnsqr looks for DNS cache addresses in the +<tt>/etc/resolv.conf</tt> file. If the DNSCACHEIP environment variable is set +and contains a list of IP (v4 or v6) addresses, separated by commas, +semicolons, spaces, tabs, newlines or carriage returns, then this list +is used instead. </li> +</ul> + +<h2> Options </h2> + +<ul> + <li> <tt>-1</tt> : send debug information to stdout. </li> + <li> <tt>-2</tt> : send debug information to stderr. This is the default. Not that +those options only apply to debug output, not to the regular packet dump, which +is always printed to stdout. </li> + <li> <tt>-t</tt> <em>timeout</em> : if the resolution takes more +than <em>timeout</em> milliseconds, then it exits 99 right away with an error +message. By default, <em>timeout</em> is 0, which means no timeout. </li> + <li> <tt>-D</tt> <em>level</em> : produce debug output during +resolution. If <em>level</em> is: + <ul> + <li> 0: no debug output is produced </li> + <li> 1: information is printed when s6-dnsqr receives a DNS packet from a cache </li> + <li> 2: information is printed before and after s6-dnsqr sends a DNS packet to a cache </li> + <li> 3: both 1. and 2. apply </li> + </ul> + +</ul> + +<h2> Notes </h2> + +<ul> + <li> TXT records are printed in a quoted form similar to +<a href="http://skarnet.org/software/s6-portable-utils/s6-quote.html">s6-quote</a>'s +output. </li> + <li> If s6-dnsqr finds a record it cannot print, such as an unknown RR type, +it dumps its content in the same quoted form. </li> + <li> The normal output format should be stable, so you can write programs that +automatically parse it. However, the debug output format is undocumented and subject +to change. </li> +</ul> + +</body> +</html> diff --git a/doc/s6-dnsqualify.html b/doc/s6-dnsqualify.html new file mode 100644 index 0000000..f515be7 --- /dev/null +++ b/doc/s6-dnsqualify.html @@ -0,0 +1,41 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns: the s6-dnsqualify program</title> + <meta name="Description" content="s6-dns: the s6-dnsqualify program" /> + <meta name="Keywords" content="s6-dns s6-dnsqualify domain name qualification fqdn resolv.conf" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-dns</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The s6-dnsqualify program </h1> + +<p> + s6-dnsqualify qualifies a domain name. +</p> + +<h2> Interface </h2> + +<pre> + s6-dnsqualify <em>domain</em> +</pre> + +<ul> + <li> s6-dnsqualify qualifies <em>domain</em> according to the "domain" and +"search" rules in <tt>/etc/resolv.conf</tt>. It prints the result on +stdout, one FQDN per line. </li> + <li> If the DNSQUALIFY +environment variable is set and contains a list of suffixes separated by spaces, +tabs, newlines or carriage returns, then this list is used instead of the +<tt>/etc/resolv.conf</tt> rules. </li> +</ul> + +</body> +</html> diff --git a/doc/s6-dnssoa.html b/doc/s6-dnssoa.html new file mode 100644 index 0000000..6f4a8f2 --- /dev/null +++ b/doc/s6-dnssoa.html @@ -0,0 +1,65 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns: the s6-dnssoa program</title> + <meta name="Description" content="s6-dns: the s6-dnssoa program" /> + <meta name="Keywords" content="s6-dns client s6-dnssoa domain soa start of authority rr field" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-dns</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The s6-dnssoa program </h1> + +<p> + s6-dnssoa finds the SOA information associated to a domain. +</p> + +<h2> Interface </h2> + +<pre> + s6-dnssoa [ -q ] [ -r ] [ -t <em>timeout</em> ] <em>domain</em> +</pre> + +<ul> + <li> s6-dnsmx makes an SOA query for the name <em>domain</em>. It +waits for the result and prints the obtained information line by line, +then exits 0. It prints the mname, the rname, the serial number, and +the refresh, retry, expiration and minimum times, in that order, +separated by spaces. </li> + <li> If the domain exists but no relevant field has been found, it exits 1. </li> + <li> If the DNS answered but no answer is available, it prints a relevant +error message and exits 2. </li> + <li> By default, s6-dnssoa looks for DNS cache addresses in the +<tt>/etc/resolv.conf</tt> file. If the DNSCACHEIP environment variable is set +and contains a list of IP (v4 or v6) addresses, separated by commas, +semicolons, spaces, tabs, newlines or carriage returns, then this list +is used instead. </li> +</ul> + +<h2> Options </h2> + +<ul> + <li> <tt>-q</tt> : qualify. Qualifies <em>domain</em> before resolution, +according to suffixes found in <tt>/etc/resolv.conf</tt>. If the DNSQUALIFY +environment variable is set and contains a list of suffixes separated by spaces, +tabs, newlines or carriage returns, then this list is used instead. By +default, no qualification is used: if <em>domain</em> is not a FQDN, a dot +is just appended to it. </li> + <li> <tt>-r</tt> : random. By default, the program does not sort the +result, but prints them in the order received from the DNS. With this +option, it performs a random permutation on the results before printing +them. </li> + <li> <tt>-t</tt> <em>timeout</em> : if the resolution takes more +than <em>timeout</em> milliseconds, then it exits 99 right away with an error +message. By default, <em>timeout</em> is 0, which means no timeout. </li> +</ul> + +</body> +</html> diff --git a/doc/s6-dnssrv.html b/doc/s6-dnssrv.html new file mode 100644 index 0000000..2a88408 --- /dev/null +++ b/doc/s6-dnssrv.html @@ -0,0 +1,65 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns: the s6-dnssrv program</title> + <meta name="Description" content="s6-dns: the s6-dnssrv program" /> + <meta name="Keywords" content="s6-dns client s6-dnssrv domain name srv rr field service" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-dns</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The s6-dnssrv program </h1> + +<p> + s6-dnssrv finds the SRV information associated to a +service name, protocol name and domain name. +</p> + +<h2> Interface </h2> + +<pre> + s6-dnssrv [ -q ] [ -r ] [ -t <em>timeout</em> ] <em>service</em> <em>proto</em> <em>domain</em> +</pre> + +<ul> + <li> s6-dnssrv makes an SRV query for _<em>service</em>._<em>proto</em>.<em>domain</em>. +It waits for the result and prints the obtained information line by line, +then exits 0. It prints the priority, the weight, the port number and the +target, in that order, separated by spaces. </li> + <li> If the domain exists but no relevant field has been found, it exits 1. </li> + <li> If the DNS answered but no answer is available, it prints a relevant +error message and exits 2. </li> + <li> By default, s6-dnssrv looks for DNS cache addresses in the +<tt>/etc/resolv.conf</tt> file. If the DNSCACHEIP environment variable is set +and contains a list of IP (v4 or v6) addresses, separated by commas, +semicolons, spaces, tabs, newlines or carriage returns, then this list +is used instead. </li> +</ul> + +<h2> Options </h2> + +<ul> + <li> <tt>-q</tt> : qualify. Qualifies <em>domain</em> before resolution, +according to suffixes found in <tt>/etc/resolv.conf</tt>. If the DNSQUALIFY +environment variable is set and contains a list of suffixes separated by spaces, +tabs, newlines or carriage returns, then this list is used instead. By +default, no qualification is used: if <em>domain</em> is not a FQDN, a dot +is just appended to it. </li> + <li> <tt>-r</tt> : random. By default, the program does not sort the +result, but prints them in the order received from the DNS. With this +option, it performs a random permutation on the results before printing +them. </li> + <li> <tt>-t</tt> <em>timeout</em> : if the resolution takes more +than <em>timeout</em> milliseconds, then it exits 99 right away with an error +message. By default, <em>timeout</em> is 0, which means no timeout. </li> +</ul> + +</body> +</html> diff --git a/doc/s6-dnstxt.html b/doc/s6-dnstxt.html new file mode 100644 index 0000000..fa84174 --- /dev/null +++ b/doc/s6-dnstxt.html @@ -0,0 +1,77 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns: the s6-dnstxt program</title> + <meta name="Description" content="s6-dns: the s6-dnstxt program" /> + <meta name="Keywords" content="s6-dns client s6-dnstxt dnstxt domain name txt text rr field" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-dns</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The s6-dnstxt program </h1> + +<p> + s6-dnstxt finds the TXT information associated to a domain name. +</p> + +<h2> Interface </h2> + +<pre> + s6-dnstxt [ -q ] [ -r ] [ -t <em>timeout</em> ] <em>domain</em> +</pre> + +<ul> + <li> s6-dnstxt makes a TXT query for the name <em>domain</em>. It +waits for the result and prints the obtained strings, one by line, +in a quoted form similar to +<a href="http://skarnet.org/software/s6-portable-utils/s6-quote.html">s6-quote</a>'s +output. You can pipe s6-dnstxt's output through +<a href="http://skarnet.org/software/s6-portable-utils/s6-unquote-filter.html">s6-unquote-filter</a> +to get unquoted TXT fields. </li> + <li> If the domain exists but no relevant field has been found, it exits 1. </li> + <li> If the DNS answered but no answer is available, it prints a relevant +error message and exits 2. </li> + <li> By default, s6-dnstxt looks for DNS cache addresses in the +<tt>/etc/resolv.conf</tt> file. If the DNSCACHEIP environment variable is set +and contains a list of IP (v4 or v6) addresses, separated by commas, +semicolons, spaces, tabs, newlines or carriage returns, then this list +is used instead. </li> +</ul> + +<h2> Options </h2> + +<ul> + <li> <tt>-q</tt> : qualify. Qualifies <em>domain</em> before resolution, +according to suffixes found in <tt>/etc/resolv.conf</tt>. If the DNSQUALIFY +environment variable is set and contains a list of suffixes separated by spaces, +tabs, newlines or carriage returns, then this list is used instead. By +default, no qualification is used: if <em>domain</em> is not a FQDN, a dot +is just appended to it. </li> + <li> <tt>-r</tt> : random. By default, the program does not sort the +result, but prints them in the order received from the DNS. With this +option, it performs a random permutation on the results before printing +them. </li> + <li> <tt>-t</tt> <em>timeout</em> : if the resolution takes more +than <em>timeout</em> milliseconds, then it exits 99 right away with an error +message. By default, <em>timeout</em> is 0, which means no timeout. </li> +</ul> + +<h2> Notes </h2> + +<p> + There can be more than one character-string in a TXT RR, and there can be +more than one TXT RR per domain. DNS clients usually concatenate all this +and only give one string. s6-dnstxt concatenates all the character-strings +in one TXT record, but separates different TXT records, printing each one +on a separate line. +</p> + +</body> +</html> diff --git a/doc/s6-randomip.html b/doc/s6-randomip.html new file mode 100644 index 0000000..0ad3b46 --- /dev/null +++ b/doc/s6-randomip.html @@ -0,0 +1,57 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns: the s6-randomip program</title> + <meta name="Description" content="s6-dns: the s6-randomip program" /> + <meta name="Keywords" content="s6-dns s6-randomip randomip random ip address filter" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-dns</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The s6-randomip program </h1> + +<p> + s6-randomip generates random IP addresses and prints them to +its standard output, one per line. +</p> + +<h2> Interface </h2> + +<pre> + s6-randomip [ -4 ] [ -6 ] [ -n <em>max</em> ] +</pre> + +<ul> + <li> s6-randomip makes up IP addresses and prints +them to its stdout. It keeps running until it receives a signal. </li> + <li> IP addresses are not guaranteed to represent anything. They are totally random. </li> +</ul> + +<h2> Options </h2> + +<ul> + <li> <tt>-4</tt> : generate IPv4 addresses. </li> + <li> <tt>-6</tt> : generate IPv6 addresses. Both the <tt>-4</tt> and +<tt>-6</tt> options may be given. If none is given, by default +s6-randomip will only generate IPv4 addresses. </li> + <li> <tt>-n</tt> <em>max</em> : s6-randomip will only generate +<em>max</em> addresses, then exit 0, instead of running forever. </li> +</ul> + +<h2> Notes </h2> + +<p> + s6-randomip can be used in conjunction with +<a href="s6-dnsname-filter">s6-dnsname-filter</a> to stress-test your +DNS architecture. Please use this responsibly and ethically. +</p> + +</body> +</html> diff --git a/doc/skadns/index.html b/doc/skadns/index.html new file mode 100644 index 0000000..f02f2dd --- /dev/null +++ b/doc/skadns/index.html @@ -0,0 +1,262 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns: the skadns library interface</title> + <meta name="Description" content="s6-dns: the skadns library interface" /> + <meta name="Keywords" content="s6-dns skadns library asynchronous resolution resolver client C interface" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="../index.html">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>skadns</tt> library interface </h1> + +<p> + The <tt>skadns</tt> library provides an API for asynchronous DNS +resolution. +</p> + +<h2> Compiling </h2> + +<ul> +<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/skadns.h></tt> </li> + <li> You might also want to include the <tt>s6-dns/s6dns.h</tt> header for +the definition of the <tt>s6dns_domain_t</tt> type and the various +qtype constants </li> +</ul> + +<h2> Linking </h2> + +<ul> + <li> Make sure the s6 libraries, as well as the skalibs libraries, +are visible in your library search path. </li> + <li> Link against <tt>-lskadns</tt> and <tt>-lskarnet</tt>. </li> + <li> If you're using a skadnsd service, also add `cat $SYSDEPS/socket.lib` +to the end of your linking command line, $SYSDEPS standing for your +skalibs sysdeps directory. </li> +</ul> + + +<h2> Programming </h2> + +<p> + Check the <tt>s6-dns/skadns.h</tt> header for the +exact function prototypes. +</p> + +<p> + Make sure your application is not disturbed by children it doesn't +know it has. This means paying some attention to the SIGCHLD handler, +if any, and to the way you perform <tt>waitpid()</tt>s. The best +practice is to use a +<a href="http://skarnet.org/software/skalibs/libstddjb/selfpipe.html">self-pipe</a> +to handle SIGCHLD (as well as other signals the application needs to trap), +and to <em>always</em> use <tt>wait_nohang()</tt> to reap children, +simply ignoring pids you don't know. +</p> + +<p> + If your (badly programmed) application has trouble handling unknown +children, consider using a skadnsd service. +</p> + +<h3> A programming example </h3> + +<p> + The <tt>src/clients/s6dns_generic_filter_main.c</tt> file in the s6-dns +package, used in the <tt>s6-dns*-filter</tt> programs, illustrates how to +use the skadns library. +</p> + +<h3> Starting and ending a session </h3> + +<pre> +skadns_t a = SKADNS_ZERO ; +tain_t deadline, stamp ; + +tain_now(&stamp) ; +tain_addsec(&deadline, &stamp, 2) + +// char const *path = SKADNS_IPCPATH ; +// skadns_start(&a, path, &deadline, &stamp) ; +skadns_startf(&a, &deadline, &stamp) ; +</pre> + +<p> +<tt>skadns_start</tt> starts a session with a skadnsd service, listening +on <em>path</em>. <br /> +<tt>skadns_startf</tt> starts a session with a skadnsd process as a child +(which is the simplest usage). <br /> +<tt>a</tt> is a skadns_t structure that must be declared and +initialized to SKADNS_ZERO. +<tt>stamp</tt> must be an accurate enough timestamp. <br /> +If the session initialization fails, the function returns 0 and errno is set; +else the function returns 1. +</p> +<p> +If the absolute time <tt>deadline</tt> is reached and the function +has not returned yet, it immediately returns 0 with errno set to ETIMEDOUT. + +Only local interprocess communications are involved; unless your system is +heavily overloaded, the function should return near-instantly. One or two +seconds of delay between <tt>stamp</tt> and <tt>deadline</tt> should be +enough: if the function takes more than that to return, then there is a +problem with the underlying processes. +</p> + +<p> + You can have more than one session open in parallel, by declaring +several distinct <tt>skadns_t</tt> structures and calling +<tt>skadns_startf</tt> (or <tt>skadns_start</tt>) more than once. +However, this is only useful if you need to perform more than +SKADNS_MAXCONCURRENCY, i.e. a thousand, concurrent requests. In +most situations, a single skadns session will be enough. +</p> + +<pre> +skadns_end(&a) ; +</pre> + +<p> +<tt>skadns_end</tt> frees all the resources used by the session. The +<tt>a</tt> structure is then reusable for another session. +</p> + +<h3> Sending a DNS query </h3> + +<pre> +s6dns_domain_t d ; +uint16 qtype ; +uint16 id ; +tain_t limit, deadline, stamp ; + +skadns_send(&a, &id, &d, qtype, &limit, &deadline, &stamp) ; +</pre> + +<p> +<tt>skadns_send</tt> starts the asynchronous resolution of domain <em>d</em> +with query type <em>qtype</em>. <em>d</em> must be encoded in packet form. +<em>stamp</em> must be an accurate enough timetamp. +If the resolution hasn't completed by deadline <em>limit</em>, it will +automatically fail with a status set to ETIMEDOUT. +</p> + +<p> + Like <tt>skadns_startf()</tt>, the <tt>skadns_send()</tt> call +is synchronous but should not be blocking; however, if it hasn't returned by +deadline <em>deadline</em>, it then returns 0 with errno set to ETIMEDOUT. +On failure, the call returns 0 and sets errno. On success, it returns 1 and +<em>id</em> is set to a 16-bit number identifying the query. +</p> + +<h3> Cancelling a query </h3> + +<pre> +skadns_cancel(&a, id, &deadline, &stamp) ; +</pre> + +<p> + <tt>skadns_cancel</tt> cancels the resolution identified by <em>id</em>. +<em>stamp</em> must be an accurate enough timestamp. +The call returns 1 on success, or 0 (and sets errno) on failure. It is +synchronous but should return almost-instantly; if it hasn't returned +by <em>deadline</em>, it then returns 0 ETIMEDOUT. +</p> + +<p> + After a query has been successfully canceled, its id can be discarded. +</p> + +<h3> Asynchronously waiting for answers </h3> + +<p> +<em> (from now on, the functions are listed with their prototypes instead +of usage examples.) </em> +</p> + +<pre> +int skadns_fd (skadns_t const *a) +</pre> + +<p> + Returns a file descriptor to select on for reading. Do not +<tt>read()</tt> it though. +</p> + +<pre> +int skadns_update (skadns_t *a) +</pre> + +<p> + Call this function whenever the fd checks readability: it will +update <em>a</em>'s internal structures with information from the +<a href="skadnsd.html">skadnsd</a> daemon. It returns -1 if an error +occurs; in case of success, it returns the number of identifiers for +which something happened. +</p> + +<p> + When <tt>skadns_update</tt> returns, +<tt>genalloc_s(uint16, &a->list)</tt> points to an array of +<tt>genalloc_len(uint16, &a->list)</tt> 16-bit unsigned +integers. Those integers are valid ids that can be used with the +following functions. +</p> + +<pre> +char const *skadns_packet (skadns_t *a, uint16 id) +int skadns_packetlen (skadns_t *a, uint16 id) +</pre> + +<p> + <tt>skadns_packet()</tt> returns a pointer to the DNS packet +containing the answer to the query identified by <em>id</em>, +and <tt>skadns_packetlen()</tt> returns its length. If an +error has occurred, <tt>skadns_packet()</tt> returns NULL and +<tt>skadns_packetlen()</tt> returns -1; either call sets errno +to a value identifying the error. Some errno values have a +special meaning: +</p> + +<ul> + <li> EAGAIN: the result has not arrived yet. </li> + <li> ECANCELED: the query has been canceled. </li> + <li> EINVAL: <em>id</em> does not identify a valid query. Note +that <strong>if</strong> you get EINVAL, <strong>then</strong> +<em>id</em> is invalid, but the reverse is not true: +using invalid ids is a programming error and may result in a crash. </li> +</ul> + +<pre> +int skadns_release (skadns_t *a, uint16 id) +</pre> + +<p> + <tt>skadns_release()</tt> frees the cell holding the result of +query <em>id</em>. It returns 1 on success, then <em>id</em> can +be discarded - further calls to <tt>skadns_send()</tt> may reuse +the same number. +</p> + +<p> + <tt>skadns_release()</tt> may fail, and return 0. This signals a +programming error and shouldn't be relied on - however, if it happens, +errno can help you identify the problem: +</p> + +<ul> + <li> EBUSY: the query is still pending, cancelled or not. </li> + <li> EINVAL: <em>id</em> is invalid. +</ul> + +</body> +</html> diff --git a/doc/skadns/skadnsd.html b/doc/skadns/skadnsd.html new file mode 100644 index 0000000..e8316b8 --- /dev/null +++ b/doc/skadns/skadnsd.html @@ -0,0 +1,120 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns: the skadnsd internal program</title> + <meta name="Description" content="s6-dns: the skadnsd internal program" /> + <meta name="Keywords" content="s6-dns skadnsd asynchronous dns daemon" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<a href="index.html">libskadns</a><br /> +<a href="../index.html">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>skadnsd</tt> program </h1> + +<p> +<tt>skadnsd</tt> is the skadns daemon. It reads a series of +queries from the client on stdin, resolves them asynchronously, +and writes +the answers to the client as soon as it gets them. It exits 0 +when its stdin closes. It exits 111 on any serious error, +writing the error message to stderr. +</p> + +<p> +<tt>skadnsd</tt> is a stub resolver. It reads <tt>/etc/resolv.conf</tt> +at start looking for a "nameserver" line containing +the address of a DNS cache (aka full resolver). It will exit 111 if it cannot +find any valid cache address in <tt>/etc/resolv.conf</tt>. If the +<tt>DNSCACHEIP</tt> environment variable is set, its value overrides +what <tt>/etc/resolv.conf</tt> says. +</p> + +<h2> Interface </h2> + +<p> +skadnsd does not fork, does not background itself automatically, +and does not use syslog. It is not meant to be run directly by the +user: it will be invoked and spawned by the skadns library calls. +</p> + +<p> + There are 2 ways to use skadnsd: +</p> +<ol> +<li> (preferred) Use the <tt>skadns_startf()</tt> library call. +A <tt>skadnsd</tt> child will then be spawned from your +calling process, and automatically reaped when you call +<tt>skadns_end()</tt>. It requires care with applications that +trap SIGCHLD. </li> +<li> Use the <tt>skadns_start()</tt> library call, together with +a <em>skadnsd service</em>. </li> +</ol> + +<h3> Running skadnsd as a child process </h3> + +<p> + This is the simplest and safest way of using <em>skadns</em>. Forget +about <tt>skadnsd</tt>: just start your library calls with +<tt>skadns_startf()</tt> and end them with <tt>skadns_end()</tt>. +Be careful though: if you're using SIGCHLD handlers, make sure they do +not interfere with the child processes your application has without +knowing. This is a general Unix programming rule. +</p> + +<h3> Running a skadnsd as a daemon: the skadnsd service </h3> + +<p> + In this mode, you set up a daemon listening on a Unix domain socket, +and clients connect to this socket to access the service. The +advantage of this setup is that it works even with badly written +clients that have trouble handling a child process; the drawback is +that it requires support from the system administrator. +</p> + +<p> +skadnsd has no "standalone" mode: it is designed to work with a Unix +domain superserver, like +<a href="http://skarnet.org/software/s6-networking/s6-ipcserver.html">s6-ipcserver</a>. +skadnsd follows the <a href="http://cr.yp.to/proto/ucspi.txt">UCSPI"</a> +interface, it can be directly executed from the superserver. +</p> + +<p> +You should run skadnsd (and its Unix superserver) under a specific user +and group, for elementary security reasons; and you should run its +dedicated logger as another specific user. Do NOT run skadnsd as root; +check your super-server documentation to find how +to run it under a specific account. +</p> + +<h2> Notes </h2> + +<ul> + <li> Users should never invoke <tt>skadnsd</tt> directly. It's an +internal program designed to be spawned by the skadns library. </li> + <li> If a poorly designed client sends a lot of queries and never reads the +answers, those will indefinitely queue up in the daemon, eating up +memory. You should run your process (or your Unix superserver, if you're +using a skadnsd service) under a program like +<a href="http://skarnet.org/software/s6/s6-softlimit.html">s6-softlimit</a> to +set a memory limit to every skadnsd instance. If skadnsd runs out of +allowed memory, it will simply die. </li> + <li> If you're using a skadnsd service: you should configure your +Unix superserver to set a maximum +number of concurrent skadnsd instances; most +Unix superserver implementations provide the +<tt>-c</tt> option for this. The s6-ipcserver program also +allows you to specify a maximum number of concurrent daemon +instances per client. </li> +<li> The only way to ensure absolute reliability of the skadnsd process is +to run it as a child, not as a daemon: use <tt>skadnsd_startf()</tt> when +possible. </li> +</ul> + +</body> +</html> diff --git a/doc/upgrade.html b/doc/upgrade.html new file mode 100644 index 0000000..c75d08e --- /dev/null +++ b/doc/upgrade.html @@ -0,0 +1,32 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>s6-dns: how to upgrade</title> + <meta name="Description" content="s6-dns: how to upgrade" /> + <meta name="Keywords" content="s6-dns installation upgrade" /> + <!-- <link rel="stylesheet" type="text/css" href="http://skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">s6-dns</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> What has changed in s6-dns </h1> + +<h2> in 2.0.0.0 </h2> + +<ul> + <li> The build system has completely changed. It is now a standard +<tt>./configure && make && sudo make install</tt> +build system. See the enclosed INSTALL file for details. </li> + <li> slashpackage is not activated by default. </li> + <li> shared libraries are not used by default. </li> + <li> skalibs dependency bumped to 2.0.0.0. </li> +</ul> + +</body> +</html> |