Welcome, gentle reader.
Async DNS lookups are really a whole lot harder than they should
    be, mostly stemming from the fact that the libc resolver has never been very
    good at them. Before you use this library you should see if libc can do the
    job for you with the modern async call getaddrinfo_a (see
    http://www.imperialviolet.org/page25.html#e498). Otherwise, please
  continue.
The library keeps track of the state of nameservers and will avoid
    them when they go down. Otherwise it will round robin between them.
Quick start guide: #include 'evdns.h' void callback(int result,
    char type, int count, int ttl, void *addresses, void *arg);
    evdns_resolv_conf_parse(DNS_OPTIONS_ALL, '/etc/resolv.conf');
    evdns_resolve('www.hostname.com', 0, callback, NULL);
When the lookup is complete the callback function is called. The
    first argument will be one of the DNS_ERR_* defines in evdns.h. Hopefully it
    will be DNS_ERR_NONE, in which case type will be DNS_IPv4_A, count will be
    the number of IP addresses, ttl is the time which the data can be cached for
    (in seconds), addresses will point to an array of uint32_t's and arg will be
    whatever you passed to evdns_resolve.
Searching:
In order for this library to be a good replacement for glibc's
    resolver it supports searching. This involves setting a list of default
    domains, in which names will be queried for. The number of dots in the query
    name determines the order in which this list is used.
Searching appears to be a single lookup from the point of view of
    the API, although many DNS queries may be generated from a single call to
    evdns_resolve. Searching can also drastically slow down the resolution of
    names.
To disable searching:
  - 1.
- Never set it up. If you never call evdns_resolv_conf_parse or
      evdns_search_add then no searching will occur.
- 2.
- If you do call evdns_resolv_conf_parse then don't pass DNS_OPTION_SEARCH
      (or DNS_OPTIONS_ALL, which implies it).
- 3.
- When calling evdns_resolve, pass the DNS_QUERY_NO_SEARCH flag.
The order of searches depends on the number of dots in the name.
    If the number is greater than the ndots setting then the names is first
    tried globally. Otherwise each search domain is appended in turn.
The ndots setting can either be set from a resolv.conf, or by
    calling evdns_search_ndots_set.
For example, with ndots set to 1 (the default) and a search domain
    list of ['myhome.net']: Query: www Order: www.myhome.net, www.
Query: www.abc Order: www.abc., www.abc.myhome.net
Internals:
Requests are kept in two queues. The first is the inflight queue.
    In this queue requests have an allocated transaction id and nameserver. They
    will soon be transmitted if they haven't already been.
The second is the waiting queue. The size of the inflight ring is
    limited and all other requests wait in waiting queue for space. This bounds
    the number of concurrent requests so that we don't flood the nameserver.
    Several algorithms require a full walk of the inflight queue and so bounding
    its size keeps thing going nicely under huge (many thousands of requests)
    loads.
If a nameserver loses too many requests it is considered down and
    we try not to use it. After a while we send a probe to that nameserver (a
    lookup for google.com) and, if it replies, we consider it working again. If
    the nameserver fails a probe we wait longer to try again with the next
    probe.
Create a new DNS server port.
Parameters:
base The event base to handle events for the
  server port.
socket A UDP socket to accept DNS requests.
flags Always 0 for now.
callback A function to invoke whenever we get a DNS request on the
  socket.
user_data Data to pass to the callback.
Returns:
an evdns_server_port structure for this server
  port.
Remove all hosts entries that have been loaded into the event_base via
  evdns_base_load_hosts or via event_base_resolv_conf_parse.
Parameters:
evdns_base the evdns base to remove outdated host
  addresses from
Remove all configured nameservers, and suspend all pending resolves. Resolves
  will not necessarily be re-attempted until evdns_base_resume() is
  called.
Parameters:
base the evdns_base to which to apply this
  operation
Returns:
0 if successful, or -1 if an error occurred
See also:
evdns_base_resume()
Get the number of configured nameservers. This returns the number of configured
  nameservers (not necessarily the number of running nameservers). This is
  useful for double-checking whether our calls to the various nameserver
  configuration functions have been successful.
Parameters:
base the evdns_base to which to apply this
  operation
Returns:
the number of configured nameservers
See also:
evdns_base_nameserver_add()
Shut down the asynchronous DNS resolver and terminate all active requests. If
  the 'fail_requests' option is enabled, all active requests will return an
  empty result with the error flag set to DNS_ERR_SHUTDOWN. Otherwise, the
  requests will be silently discarded.
Parameters:
evdns_base the evdns base to free
fail_requests if zero, active requests will be aborted; if non-zero,
  active requests will return DNS_ERR_SHUTDOWN.
See also:
evdns_base_new()
Retrieve the address of the 'idx'th configured nameserver.
Parameters:
base The evdns_base to examine.
idx The index of the nameserver to get the address of.
sa A location to receive the server's address.
len The number of bytes available at sa.
Returns:
the number of bytes written into sa on success. On
  failure, returns -1 if idx is greater than the number of configured
  nameservers, or a value greater than 'len' if len was not high enough.
Load an /etc/hosts-style file from 'hosts_fname' into 'base'. If hosts_fname is
  NULL, add minimal entries for localhost, and nothing else.
Note that only evdns_getaddrinfo uses the /etc/hosts entries.
This function does not replace previously loaded hosts entries; to
    do that, call evdns_base_clear_host_addresses first.
Return 0 on success, negative on failure.
Add a nameserver. The address should be an IPv4 address in network byte order.
  The type of address is chosen so that it matches in_addr.s_addr.
Parameters:
base the evdns_base to which to add the name
  server
address an IP address in network byte order
Returns:
0 if successful, or -1 if an error occurred
See also:
evdns_base_nameserver_ip_add()
Add a nameserver by string address. This function parses a n IPv4 or IPv6
  address from a string and adds it as a nameserver. It supports the following
  formats:
  - [IPv6Address]:port
- [IPv6Address]
- IPv6Address
- IPv4Address:port
- IPv4Address
If no port is specified, it defaults to 53.
Parameters:
base the evdns_base to which to apply this
  operation
Returns:
0 if successful, or -1 if an error occurred
See also:
evdns_base_nameserver_add()
Initialize the asynchronous DNS library. This function initializes support for
  non-blocking name resolution by calling evdns_resolv_conf_parse() on
  UNIX and evdns_config_windows_nameservers() on Windows.
Parameters:
event_base the event base to
  associate the dns client with
flags any of EVDNS_BASE_INITIALIZE_NAMESERVERS|
  EVDNS_BASE_DISABLE_WHEN_INACTIVE
Returns:
evdns_base object if successful, or NULL if an error
  occurred.
See also:
evdns_base_free()
Parse a resolv.conf file. The 'flags' parameter determines what information is
  parsed from the resolv.conf file. See the man page for resolv.conf for the
  format of this file.
The following directives are not parsed from the file: sortlist,
    rotate, no-check-names, inet6, debug.
If this function encounters an error, the possible return values
    are: 1 = failed to open file, 2 = failed to stat file, 3 = file too large, 4
    = out of memory, 5 = short read from file, 6 = no nameservers listed in the
    file
Parameters:
base the evdns_base to which to apply this
  operation
flags any of DNS_OPTION_NAMESERVERS|DNS_OPTION_SEARCH|DNS_OPTION_MISC|
  DNS_OPTION_HOSTSFILE|DNS_OPTIONS_ALL
filename the path to the resolv.conf file
Returns:
0 if successful, or various positive error codes if an
  error occurred (see above)
See also:
resolv.conf(3), evdns_config_windows_nameservers()
Lookup an A record for a given name.
Parameters:
base the evdns_base to which to apply this
  operation
name a DNS hostname
flags either 0, or DNS_QUERY_NO_SEARCH to disable searching for this
  query.
callback a callback function to invoke when the request is completed
ptr an argument to pass to the callback function
Returns:
an evdns_request object if successful, or NULL if an
  error occurred.
See also:
evdns_resolve_ipv6(),
  evdns_resolve_reverse(), evdns_resolve_reverse_ipv6(),
  evdns_cancel_request()
Lookup an AAAA record for a given name.
Parameters:
base the evdns_base to which to apply this
  operation
name a DNS hostname
flags either 0, or DNS_QUERY_NO_SEARCH to disable searching for this
  query.
callback a callback function to invoke when the request is completed
ptr an argument to pass to the callback function
Returns:
an evdns_request object if successful, or NULL if an
  error occurred.
See also:
evdns_resolve_ipv4(),
  evdns_resolve_reverse(), evdns_resolve_reverse_ipv6(),
  evdns_cancel_request()
Lookup a PTR record for a given IP address.
Parameters:
base the evdns_base to which to apply this
  operation
in an IPv4 address
flags either 0, or DNS_QUERY_NO_SEARCH to disable searching for this
  query.
callback a callback function to invoke when the request is completed
ptr an argument to pass to the callback function
Returns:
an evdns_request object if successful, or NULL if an
  error occurred.
See also:
evdns_resolve_reverse_ipv6(),
  evdns_cancel_request()
Lookup a PTR record for a given IPv6 address.
Parameters:
base the evdns_base to which to apply this
  operation
in an IPv6 address
flags either 0, or DNS_QUERY_NO_SEARCH to disable searching for this
  query.
callback a callback function to invoke when the request is completed
ptr an argument to pass to the callback function
Returns:
an evdns_request object if successful, or NULL if an
  error occurred.
See also:
evdns_resolve_reverse_ipv6(),
  evdns_cancel_request()
Resume normal operation and continue any suspended resolve requests. Re-attempt
  resolves left in limbo after an earlier call to
  evdns_base_clear_nameservers_and_suspend().
Parameters:
base the evdns_base to which to apply this
  operation
Returns:
0 if successful, or -1 if an error occurred
See also:
evdns_base_clear_nameservers_and_suspend()
Add a domain to the list of search domains.
Parameters:
domain the domain to be added to the search
  list
Obtain nameserver information using the Windows API. Attempt to configure a set
  of nameservers based on platform settings on a win32 host. Preferentially
  tries to use GetNetworkParams; if that fails, looks in the registry.
Returns:
0 if successful, or -1 if an error occurred
See also:
evdns_resolv_conf_parse() Clear the list of search
  domains.
Set the 'ndots' parameter for searches. Sets the number of dots which, when
  found in a name, causes the first query to be without any search domain.
Parameters:
ndots the new ndots parameter
Set the value of a configuration option. The currently available configuration
  options are:
ndots, timeout, max-timeouts, max-inflight, attempts,
    randomize-case, bind-to, initial-probe-timeout, getaddrinfo-allow-skew.
In versions before Libevent 2.0.3-alpha, the option name needed to
    end with a colon.
Parameters:
base the evdns_base to which to apply this
  operation
option the name of the configuration option to be modified
val the value to be set
Returns:
0 if successful, or -1 if an error occurred
Cancels a pending DNS resolution request.
Parameters:
base the evdns_base that was used to make the
  request
req the evdns_request that was returned by calling a resolve
  function
See also:
evdns_base_resolve_ipv4(),
  evdns_base_resolve_ipv6, evdns_base_resolve_reverse
Close down a DNS server port, and free associated structures.
Convert a DNS error code to a string.
Parameters:
err the DNS error code
Returns:
a string containing an explanation of the error
  code
Make a non-blocking getaddrinfo request using the dns_base in 'dns_base'. If we
  can answer the request immediately (with an error or not!), then we invoke cb
  immediately and return NULL. Otherwise we return an evdns_getaddrinfo_request
  and invoke cb later.
When the callback is invoked, we pass as its first argument the
    error code that getaddrinfo would return (or 0 for no error). As its second
    argument, we pass the evutil_addrinfo structures we found (or NULL on
    error). We pass 'arg' as the third argument.
Limitations:
  - The AI_V4MAPPED and AI_ALL flags are not currently implemented.
- For ai_socktype, we only handle SOCKTYPE_STREAM, SOCKTYPE_UDP, and 0.
- For ai_protocol, we only handle IPPROTO_TCP, IPPROTO_UDP, and 0.
Sets some flags in a reply we're building. Allows setting of the AA or RD flags
Set the callback function to handle DNS log messages. If this callback is not
  set, evdns log messages are handled with the regular Libevent logging system.Parameters:
fn the callback to be invoked when a log message
  is generated
Set a callback used to generate random bytes. By default, we use the same
  function as passed to evdns_set_transaction_id_fn to generate bytes two at a
  time. If a function is provided here, it's also used to generate transaction
  IDs.
NOTE: This function has no effect in Libevent 2.0.4-alpha and
    later, since Libevent now provides its own secure RNG.
Set a callback that will be invoked to generate transaction IDs. By default, we
  pick transaction IDs based on the current clock time, which is bad for
  security.
Parameters:
fn the new callback, or NULL to use the
  default.
NOTE: This function has no effect in Libevent 2.0.4-alpha and
    later, since Libevent now provides its own secure RNG.