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