1cf47f86bSNiels Provos.\" 2cf47f86bSNiels Provos.\" Copyright (c) 2006 Niels Provos <[email protected]> 3cf47f86bSNiels Provos.\" All rights reserved. 4cf47f86bSNiels Provos.\" 5cf47f86bSNiels Provos.\" Redistribution and use in source and binary forms, with or without 6cf47f86bSNiels Provos.\" modification, are permitted provided that the following conditions 7cf47f86bSNiels Provos.\" are met: 8cf47f86bSNiels Provos.\" 9cf47f86bSNiels Provos.\" 1. Redistributions of source code must retain the above copyright 10cf47f86bSNiels Provos.\" notice, this list of conditions and the following disclaimer. 11cf47f86bSNiels Provos.\" 2. Redistributions in binary form must reproduce the above copyright 12cf47f86bSNiels Provos.\" notice, this list of conditions and the following disclaimer in the 13cf47f86bSNiels Provos.\" documentation and/or other materials provided with the distribution. 14cf47f86bSNiels Provos.\" 3. The name of the author may not be used to endorse or promote products 15cf47f86bSNiels Provos.\" derived from this software without specific prior written permission. 16cf47f86bSNiels Provos.\" 17cf47f86bSNiels Provos.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 18cf47f86bSNiels Provos.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 19cf47f86bSNiels Provos.\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 20cf47f86bSNiels Provos.\" THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21cf47f86bSNiels Provos.\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22cf47f86bSNiels Provos.\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23cf47f86bSNiels Provos.\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24cf47f86bSNiels Provos.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25cf47f86bSNiels Provos.\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 26cf47f86bSNiels Provos.\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27cf47f86bSNiels Provos.\" 28cf47f86bSNiels Provos.Dd October 7, 2006 29cf47f86bSNiels Provos.Dt EVDNS 3 30cf47f86bSNiels Provos.Os 31cf47f86bSNiels Provos.Sh NAME 32cf47f86bSNiels Provos.Nm evdns_init 33cf47f86bSNiels Provos.Nm evdns_shutdown 34cf47f86bSNiels Provos.Nm evdns_err_to_string 35cf47f86bSNiels Provos.Nm evdns_nameserver_add 36cf47f86bSNiels Provos.Nm evdns_count_nameservers 37cf47f86bSNiels Provos.Nm evdns_clear_nameservers_and_suspend 38cf47f86bSNiels Provos.Nm evdns_resume 39cf47f86bSNiels Provos.Nm evdns_nameserver_ip_add 40cf47f86bSNiels Provos.Nm evdns_resolve_ipv4 41cf47f86bSNiels Provos.Nm evdns_resolve_reverse 42cf47f86bSNiels Provos.Nm evdns_resolv_conf_parse 43cf47f86bSNiels Provos.Nm evdns_config_windows_nameservers 44cf47f86bSNiels Provos.Nm evdns_search_clear 45cf47f86bSNiels Provos.Nm evdns_search_add 46cf47f86bSNiels Provos.Nm evdns_search_ndots_set 47cf47f86bSNiels Provos.Nm evdns_set_log_fn 48cf47f86bSNiels Provos.Nd asynchronous functions for DNS resolution. 49cf47f86bSNiels Provos.Sh SYNOPSIS 50cf47f86bSNiels Provos.Fd #include <sys/time.h> 51cf47f86bSNiels Provos.Fd #include <event.h> 52cf47f86bSNiels Provos.Fd #include <evdns.h> 53cf47f86bSNiels Provos.Ft int 54cf47f86bSNiels Provos.Fn evdns_init 55cf47f86bSNiels Provos.Ft void 56cf47f86bSNiels Provos.Fn evdns_shutdown "int fail_requests" 57cf47f86bSNiels Provos.Ft "const char *" 58cf47f86bSNiels Provos.Fn evdns_err_to_string "int err" 59cf47f86bSNiels Provos.Ft int 60cf47f86bSNiels Provos.Fn evdns_nameserver_add "unsigned long int address" 61cf47f86bSNiels Provos.Ft int 62cf47f86bSNiels Provos.Fn evdns_count_nameservers 63cf47f86bSNiels Provos.Ft int 64cf47f86bSNiels Provos.Fn evdns_clear_nameservers_and_suspend 65cf47f86bSNiels Provos.Ft int 66cf47f86bSNiels Provos.Fn evdns_resume 67cf47f86bSNiels Provos.Ft int 68cf47f86bSNiels Provos.Fn evdns_nameserver_ip_add(const char *ip_as_string); 69cf47f86bSNiels Provos.Ft int 70cf47f86bSNiels Provos.Fn evdns_resolve_ipv4 "const char *name" "int flags" "evdns_callback_type callback" "void *ptr" 71cf47f86bSNiels Provos.Ft int 72cf47f86bSNiels Provos.Fn evdns_resolve_reverse "struct in_addr *in" "int flags" "evdns_callback_type callback" "void *ptr" 73cf47f86bSNiels Provos.Ft int 74cf47f86bSNiels Provos.Fn evdns_resolv_conf_parse "int flags" "const char *" 75cf47f86bSNiels Provos.Ft void 76cf47f86bSNiels Provos.Fn evdns_search_clear 77cf47f86bSNiels Provos.Ft void 78cf47f86bSNiels Provos.Fn evdns_search_add "const char *domain" 79cf47f86bSNiels Provos.Ft void 80cf47f86bSNiels Provos.Fn evdns_search_ndots_set "const int ndots" 81cf47f86bSNiels Provos.Ft void 82cf47f86bSNiels Provos.Fn evdns_set_log_fn "evdns_debug_log_fn_type fn" 83cf47f86bSNiels Provos.Ft int 84cf47f86bSNiels Provos.Fn evdns_config_windows_nameservers 85cf47f86bSNiels Provos.Sh DESCRIPTION 86cf47f86bSNiels ProvosWelcome, gentle reader 87cf47f86bSNiels Provos.Pp 88cf47f86bSNiels ProvosAsync DNS lookups are really a whole lot harder than they should be, 89cf47f86bSNiels Provosmostly stemming from the fact that the libc resolver has never been 90cf47f86bSNiels Provosvery good at them. Before you use this library you should see if libc 91cf47f86bSNiels Provoscan do the job for you with the modern async call getaddrinfo_a 92cf47f86bSNiels Provos(see http://www.imperialviolet.org/page25.html#e498). Otherwise, 93cf47f86bSNiels Provosplease continue. 94cf47f86bSNiels Provos.Pp 95cf47f86bSNiels ProvosThis code is based on libevent and you must call event_init before 96cf47f86bSNiels Provosany of the APIs in this file. You must also seed the OpenSSL random 97cf47f86bSNiels Provossource if you are using OpenSSL for ids (see below). 98cf47f86bSNiels Provos.Pp 99cf47f86bSNiels ProvosThis library is designed to be included and shipped with your source 100cf47f86bSNiels Provoscode. You statically link with it. You should also test for the 101cf47f86bSNiels Provosexistence of strtok_r and define HAVE_STRTOK_R if you have it. 102cf47f86bSNiels Provos.Pp 103cf47f86bSNiels ProvosThe DNS protocol requires a good source of id numbers and these 104cf47f86bSNiels Provosnumbers should be unpredictable for spoofing reasons. There are 105cf47f86bSNiels Provosthree methods for generating them here and you must define exactly 106cf47f86bSNiels Provosone of them. In increasing order of preference: 107cf47f86bSNiels Provos.Pp 108*ea52d9fdSNiels Provos.Bl -tag -width "DNS_USE_GETTIMEOFDAY_FOR_ID" -compact -offset indent 109*ea52d9fdSNiels Provos.It DNS_USE_GETTIMEOFDAY_FOR_ID 110cf47f86bSNiels ProvosUsing the bottom 16 bits of the usec result from gettimeofday. This 111cf47f86bSNiels Provosis a pretty poor solution but should work anywhere. 112*ea52d9fdSNiels Provos.It DNS_USE_CPU_CLOCK_FOR_ID 113cf47f86bSNiels ProvosUsing the bottom 16 bits of the nsec result from the CPU's time 114cf47f86bSNiels Provoscounter. This is better, but may not work everywhere. Requires 115cf47f86bSNiels ProvosPOSIX realtime support and you'll need to link against -lrt on 116cf47f86bSNiels Provosglibc systems at least. 117*ea52d9fdSNiels Provos.It DNS_USE_OPENSSL_FOR_ID 118cf47f86bSNiels ProvosUses the OpenSSL RAND_bytes call to generate the data. You must 119cf47f86bSNiels Provoshave seeded the pool before making any calls to this library. 120*ea52d9fdSNiels Provos.El 121cf47f86bSNiels Provos.Pp 122cf47f86bSNiels ProvosThe library keeps track of the state of nameservers and will avoid 123cf47f86bSNiels Provosthem when they go down. Otherwise it will round robin between them. 124cf47f86bSNiels Provos.Pp 125cf47f86bSNiels ProvosQuick start guide: 126cf47f86bSNiels Provos #include "evdns.h" 127cf47f86bSNiels Provos void callback(int result, char type, int count, int ttl, 128cf47f86bSNiels Provos void *addresses, void *arg); 129cf47f86bSNiels Provos evdns_resolv_conf_parse(DNS_OPTIONS_ALL, "/etc/resolv.conf"); 130cf47f86bSNiels Provos evdns_resolve("www.hostname.com", 0, callback, NULL); 131cf47f86bSNiels Provos.Pp 132cf47f86bSNiels ProvosWhen the lookup is complete the callback function is called. The 133cf47f86bSNiels Provosfirst argument will be one of the DNS_ERR_* defines in evdns.h. 134cf47f86bSNiels ProvosHopefully it will be DNS_ERR_NONE, in which case type will be 135cf47f86bSNiels ProvosDNS_IPv4_A, count will be the number of IP addresses, ttl is the time 136cf47f86bSNiels Provoswhich the data can be cached for (in seconds), addresses will point 137cf47f86bSNiels Provosto an array of uint32_t's and arg will be whatever you passed to 138cf47f86bSNiels Provosevdns_resolve. 139cf47f86bSNiels Provos.Pp 140cf47f86bSNiels ProvosSearching: 141cf47f86bSNiels Provos.Pp 142cf47f86bSNiels ProvosIn order for this library to be a good replacement for glibc's resolver it 143cf47f86bSNiels Provossupports searching. This involves setting a list of default domains, in 144cf47f86bSNiels Provoswhich names will be queried for. The number of dots in the query name 145cf47f86bSNiels Provosdetermines the order in which this list is used. 146cf47f86bSNiels Provos.Pp 147cf47f86bSNiels ProvosSearching appears to be a single lookup from the point of view of the API, 148cf47f86bSNiels Provosalthough many DNS queries may be generated from a single call to 149cf47f86bSNiels Provosevdns_resolve. Searching can also drastically slow down the resolution 150cf47f86bSNiels Provosof names. 151cf47f86bSNiels Provos.Pp 152cf47f86bSNiels ProvosTo disable searching: 153*ea52d9fdSNiels Provos.Bl -enum -compact -offset indent 154*ea52d9fdSNiels Provos.It 155*ea52d9fdSNiels ProvosNever set it up. If you never call 156*ea52d9fdSNiels Provos.Fn evdns_resolv_conf_parse, 157*ea52d9fdSNiels Provos.Fn evdns_init, 158*ea52d9fdSNiels Provosor 159*ea52d9fdSNiels Provos.Fn evdns_search_add 160*ea52d9fdSNiels Provosthen no searching will occur. 161*ea52d9fdSNiels Provos.It 162*ea52d9fdSNiels ProvosIf you do call 163*ea52d9fdSNiels Provos.Fn evdns_resolv_conf_parse 164*ea52d9fdSNiels Provosthen don't pass 165*ea52d9fdSNiels Provos.Va DNS_OPTION_SEARCH 166*ea52d9fdSNiels Provos(or 167*ea52d9fdSNiels Provos.Va DNS_OPTIONS_ALL, 168*ea52d9fdSNiels Provoswhich implies it). 169*ea52d9fdSNiels Provos.It 170*ea52d9fdSNiels ProvosWhen calling 171*ea52d9fdSNiels Provos.Fn evdns_resolve, 172*ea52d9fdSNiels Provospass the 173*ea52d9fdSNiels Provos.Va DNS_QUERY_NO_SEARCH 174*ea52d9fdSNiels Provosflag. 175*ea52d9fdSNiels Provos.El 176cf47f86bSNiels Provos.Pp 177cf47f86bSNiels ProvosThe order of searches depends on the number of dots in the name. If the 178cf47f86bSNiels Provosnumber is greater than the ndots setting then the names is first tried 179cf47f86bSNiels Provosglobally. Otherwise each search domain is appended in turn. 180cf47f86bSNiels Provos.Pp 181cf47f86bSNiels ProvosThe ndots setting can either be set from a resolv.conf, or by calling 182cf47f86bSNiels Provosevdns_search_ndots_set. 183cf47f86bSNiels Provos.Pp 184cf47f86bSNiels ProvosFor example, with ndots set to 1 (the default) and a search domain list of 185cf47f86bSNiels Provos["myhome.net"]: 186cf47f86bSNiels Provos Query: www 187cf47f86bSNiels Provos Order: www.myhome.net, www. 188cf47f86bSNiels Provos.Pp 189cf47f86bSNiels Provos Query: www.abc 190cf47f86bSNiels Provos Order: www.abc., www.abc.myhome.net 191cf47f86bSNiels Provos.Pp 192*ea52d9fdSNiels Provos.Sh API reference 193cf47f86bSNiels Provos.Pp 194*ea52d9fdSNiels Provos.Bl -tag -width 0123456 195*ea52d9fdSNiels Provos.It Ft int Fn evdns_init 196*ea52d9fdSNiels ProvosInitializes support for non-blocking name resolution by calling 197*ea52d9fdSNiels Provos.Fn evdns_resolv_conf_parse 198*ea52d9fdSNiels Provoson UNIX and 199*ea52d9fdSNiels Provos.Fn evdns_config_windows_nameservers 200*ea52d9fdSNiels Provoson Windows. 201*ea52d9fdSNiels Provos.It Ft int Fn evdns_nameserver_add "unsigned long int address" 202cf47f86bSNiels ProvosAdd a nameserver. The address should be an IP address in 203cf47f86bSNiels Provosnetwork byte order. The type of address is chosen so that 204cf47f86bSNiels Provosit matches in_addr.s_addr. 205cf47f86bSNiels ProvosReturns non-zero on error. 206*ea52d9fdSNiels Provos.It Ft int Fn evdns_nameserver_ip_add "const char *ip_as_string" 207cf47f86bSNiels ProvosThis wraps the above function by parsing a string as an IP 208cf47f86bSNiels Provosaddress and adds it as a nameserver. 209cf47f86bSNiels ProvosReturns non-zero on error 210*ea52d9fdSNiels Provos.It Ft int Fn evdns_resolve "const char *name" "int flags" "evdns_callback_type callback" "void *ptr" 211cf47f86bSNiels ProvosResolve a name. The name parameter should be a DNS name. 212cf47f86bSNiels ProvosThe flags parameter should be 0, or DNS_QUERY_NO_SEARCH 213cf47f86bSNiels Provoswhich disables searching for this query. (see defn of 214cf47f86bSNiels Provossearching above). 215cf47f86bSNiels Provos.Pp 216cf47f86bSNiels ProvosThe callback argument is a function which is called when 217cf47f86bSNiels Provosthis query completes and ptr is an argument which is passed 218cf47f86bSNiels Provosto that callback function. 219cf47f86bSNiels Provos.Pp 220cf47f86bSNiels ProvosReturns non-zero on error 221*ea52d9fdSNiels Provos.It Ft void Fn evdns_search_clear 222cf47f86bSNiels ProvosClears the list of search domains 223*ea52d9fdSNiels Provos.It Ft void Fn evdns_search_add "const char *domain" 224cf47f86bSNiels ProvosAdd a domain to the list of search domains 225*ea52d9fdSNiels Provos.It Ft void Fn evdns_search_ndots_set "int ndots" 226cf47f86bSNiels ProvosSet the number of dots which, when found in a name, causes 227cf47f86bSNiels Provosthe first query to be without any search domain. 228*ea52d9fdSNiels Provos.It Ft int Fn evdns_count_nameservers "void" 229cf47f86bSNiels ProvosReturn the number of configured nameservers (not necessarily the 230cf47f86bSNiels Provosnumber of running nameservers). This is useful for double-checking 231cf47f86bSNiels Provoswhether our calls to the various nameserver configuration functions 232cf47f86bSNiels Provoshave been successful. 233*ea52d9fdSNiels Provos.It Ft int Fn evdns_clear_nameservers_and_suspend "void" 234cf47f86bSNiels ProvosRemove all currently configured nameservers, and suspend all pending 235cf47f86bSNiels Provosresolves. Resolves will not necessarily be re-attempted until 236cf47f86bSNiels Provosevdns_resume() is called. 237*ea52d9fdSNiels Provos.It Ft int Fn evdns_resume "void" 238cf47f86bSNiels ProvosRe-attempt resolves left in limbo after an earlier call to 239cf47f86bSNiels Provosevdns_clear_nameservers_and_suspend(). 240*ea52d9fdSNiels Provos.It Ft int Fn evdns_config_windows_nameservers "void" 241cf47f86bSNiels ProvosAttempt to configure a set of nameservers based on platform settings on 242cf47f86bSNiels Provosa win32 host. Preferentially tries to use GetNetworkParams; if that fails, 243cf47f86bSNiels Provoslooks in the registry. Returns 0 on success, nonzero on failure. 244*ea52d9fdSNiels Provos.It Ft int Fn evdns_resolv_conf_parse "int flags" "const char *filename" 245cf47f86bSNiels ProvosParse a resolv.conf like file from the given filename. 246cf47f86bSNiels Provos.Pp 247cf47f86bSNiels ProvosSee the man page for resolv.conf for the format of this file. 248cf47f86bSNiels ProvosThe flags argument determines what information is parsed from 249cf47f86bSNiels Provosthis file: 250*ea52d9fdSNiels Provos.Bl -tag -width "DNS_OPTION_NAMESERVERS" -offset indent -compact -nested 251*ea52d9fdSNiels Provos.It DNS_OPTION_SEARCH 252*ea52d9fdSNiels Provosdomain, search and ndots options 253*ea52d9fdSNiels Provos.It DNS_OPTION_NAMESERVERS 254*ea52d9fdSNiels Provosnameserver lines 255*ea52d9fdSNiels Provos.It DNS_OPTION_MISC 256*ea52d9fdSNiels Provostimeout and attempts options 257*ea52d9fdSNiels Provos.It DNS_OPTIONS_ALL 258*ea52d9fdSNiels Provosall of the above 259*ea52d9fdSNiels Provos.El 260*ea52d9fdSNiels Provos.Pp 261cf47f86bSNiels ProvosThe following directives are not parsed from the file: 262cf47f86bSNiels Provos sortlist, rotate, no-check-names, inet6, debug 263cf47f86bSNiels Provos.Pp 264cf47f86bSNiels ProvosReturns non-zero on error: 265*ea52d9fdSNiels Provos.Bl -tag -width "0" -offset indent -compact -nested 266*ea52d9fdSNiels Provos.It 0 267*ea52d9fdSNiels Provosno errors 268*ea52d9fdSNiels Provos.It 1 269*ea52d9fdSNiels Provosfailed to open file 270*ea52d9fdSNiels Provos.It 2 271*ea52d9fdSNiels Provosfailed to stat file 272*ea52d9fdSNiels Provos.It 3 273*ea52d9fdSNiels Provosfile too large 274*ea52d9fdSNiels Provos.It 4 275*ea52d9fdSNiels Provosout of memory 276*ea52d9fdSNiels Provos.It 5 277*ea52d9fdSNiels Provosshort read from file 278*ea52d9fdSNiels Provos.El 279*ea52d9fdSNiels Provos.El 280*ea52d9fdSNiels Provos.Sh Internals: 281cf47f86bSNiels ProvosRequests are kept in two queues. The first is the inflight queue. In 282cf47f86bSNiels Provosthis queue requests have an allocated transaction id and nameserver. 283cf47f86bSNiels ProvosThey will soon be transmitted if they haven't already been. 284cf47f86bSNiels Provos.Pp 285cf47f86bSNiels ProvosThe second is the waiting queue. The size of the inflight ring is 286cf47f86bSNiels Provoslimited and all other requests wait in waiting queue for space. This 287cf47f86bSNiels Provosbounds the number of concurrent requests so that we don't flood the 288cf47f86bSNiels Provosnameserver. Several algorithms require a full walk of the inflight 289cf47f86bSNiels Provosqueue and so bounding its size keeps thing going nicely under huge 290cf47f86bSNiels Provos(many thousands of requests) loads. 291cf47f86bSNiels Provos.Pp 292cf47f86bSNiels ProvosIf a nameserver loses too many requests it is considered down and we 293cf47f86bSNiels Provostry not to use it. After a while we send a probe to that nameserver 294cf47f86bSNiels Provos(a lookup for google.com) and, if it replies, we consider it working 295cf47f86bSNiels Provosagain. If the nameserver fails a probe we wait longer to try again 296cf47f86bSNiels Provoswith the next probe. 297cf47f86bSNiels Provos.Sh SEE ALSO 298cf47f86bSNiels Provos.Xr event 3 , 299cf47f86bSNiels Provos.Xr gethostbyname 3 , 300cf47f86bSNiels Provos.Xr resolv.conf 5 301cf47f86bSNiels Provos.Sh HISTORY 302cf47f86bSNiels ProvosThe 303cf47f86bSNiels Provos.Nm evdns 304cf47f86bSNiels ProvosAPI was developed by Adam Langley on top of the 305cf47f86bSNiels Provos.Nm libevent 306cf47f86bSNiels ProvosAPI. 307cf47f86bSNiels ProvosThe code was integrate into 308cf47f86bSNiels Provos.Nm Tor 309cf47f86bSNiels Provosby Nick Mathewson and finally put into 310cf47f86bSNiels Provos.Nm libevent 311cf47f86bSNiels Provositself by Niels Provos. 312cf47f86bSNiels Provos.Sh AUTHORS 313cf47f86bSNiels ProvosThe 314cf47f86bSNiels Provos.Nm evdns 315cf47f86bSNiels ProvosAPI and code was written by Adam Langley with significant 316cf47f86bSNiels Provoscontributions by Nick Mathewson. 317cf47f86bSNiels Provos.Sh BUGS 318cf47f86bSNiels ProvosThis documentation is neither complete nor authoritative. 319cf47f86bSNiels ProvosIf you are in doubt about the usage of this API then 320cf47f86bSNiels Provoscheck the source code to find out how it works, write 321cf47f86bSNiels Provosup the missing piece of documentation and send it to 322cf47f86bSNiels Provosme for inclusion in this man page. 323