xref: /libevent-2.1.12/evdns.3 (revision ea52d9fd)
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