Annotation of embedaddon/libevent/evdns.h, revision 1.1.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:  * 1. Redistributions of source code must retain the above copyright
                      9:  *    notice, this list of conditions and the following disclaimer.
                     10:  * 2. Redistributions in binary form must reproduce the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer in the
                     12:  *    documentation and/or other materials provided with the distribution.
                     13:  * 3. The name of the author may not be used to endorse or promote products
                     14:  *    derived from this software without specific prior written permission.
                     15:  *
                     16:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     17:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     18:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     19:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     20:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     21:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     22:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     23:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     24:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     25:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     26:  */
                     27: 
                     28: /*
                     29:  * The original DNS code is due to Adam Langley with heavy
                     30:  * modifications by Nick Mathewson.  Adam put his DNS software in the
                     31:  * public domain.  You can find his original copyright below.  Please,
                     32:  * aware that the code as part of libevent is governed by the 3-clause
                     33:  * BSD license above.
                     34:  *
                     35:  * This software is Public Domain. To view a copy of the public domain dedication,
                     36:  * visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
                     37:  * Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
                     38:  *
                     39:  * I ask and expect, but do not require, that all derivative works contain an
                     40:  * attribution similar to:
                     41:  *     Parts developed by Adam Langley <agl@imperialviolet.org>
                     42:  *
                     43:  * You may wish to replace the word "Parts" with something else depending on
                     44:  * the amount of original code.
                     45:  *
                     46:  * (Derivative works does not include programs which link against, run or include
                     47:  * the source verbatim in their source distributions)
                     48:  */
                     49: 
                     50: /** @file evdns.h
                     51:  *
                     52:  * Welcome, gentle reader
                     53:  *
                     54:  * Async DNS lookups are really a whole lot harder than they should be,
                     55:  * mostly stemming from the fact that the libc resolver has never been
                     56:  * very good at them. Before you use this library you should see if libc
                     57:  * can do the job for you with the modern async call getaddrinfo_a
                     58:  * (see http://www.imperialviolet.org/page25.html#e498). Otherwise,
                     59:  * please continue.
                     60:  *
                     61:  * This code is based on libevent and you must call event_init before
                     62:  * any of the APIs in this file. You must also seed the OpenSSL random
                     63:  * source if you are using OpenSSL for ids (see below).
                     64:  *
                     65:  * This library is designed to be included and shipped with your source
                     66:  * code. You statically link with it. You should also test for the
                     67:  * existence of strtok_r and define HAVE_STRTOK_R if you have it.
                     68:  *
                     69:  * The DNS protocol requires a good source of id numbers and these
                     70:  * numbers should be unpredictable for spoofing reasons. There are
                     71:  * three methods for generating them here and you must define exactly
                     72:  * one of them. In increasing order of preference:
                     73:  *
                     74:  * DNS_USE_GETTIMEOFDAY_FOR_ID:
                     75:  *   Using the bottom 16 bits of the usec result from gettimeofday. This
                     76:  *   is a pretty poor solution but should work anywhere.
                     77:  * DNS_USE_CPU_CLOCK_FOR_ID:
                     78:  *   Using the bottom 16 bits of the nsec result from the CPU's time
                     79:  *   counter. This is better, but may not work everywhere. Requires
                     80:  *   POSIX realtime support and you'll need to link against -lrt on
                     81:  *   glibc systems at least.
                     82:  * DNS_USE_OPENSSL_FOR_ID:
                     83:  *   Uses the OpenSSL RAND_bytes call to generate the data. You must
                     84:  *   have seeded the pool before making any calls to this library.
                     85:  *
                     86:  * The library keeps track of the state of nameservers and will avoid
                     87:  * them when they go down. Otherwise it will round robin between them.
                     88:  *
                     89:  * Quick start guide:
                     90:  *   #include "evdns.h"
                     91:  *   void callback(int result, char type, int count, int ttl,
                     92:  *              void *addresses, void *arg);
                     93:  *   evdns_resolv_conf_parse(DNS_OPTIONS_ALL, "/etc/resolv.conf");
                     94:  *   evdns_resolve("www.hostname.com", 0, callback, NULL);
                     95:  *
                     96:  * When the lookup is complete the callback function is called. The
                     97:  * first argument will be one of the DNS_ERR_* defines in evdns.h.
                     98:  * Hopefully it will be DNS_ERR_NONE, in which case type will be
                     99:  * DNS_IPv4_A, count will be the number of IP addresses, ttl is the time
                    100:  * which the data can be cached for (in seconds), addresses will point
                    101:  * to an array of uint32_t's and arg will be whatever you passed to
                    102:  * evdns_resolve.
                    103:  *
                    104:  * Searching:
                    105:  *
                    106:  * In order for this library to be a good replacement for glibc's resolver it
                    107:  * supports searching. This involves setting a list of default domains, in
                    108:  * which names will be queried for. The number of dots in the query name
                    109:  * determines the order in which this list is used.
                    110:  *
                    111:  * Searching appears to be a single lookup from the point of view of the API,
                    112:  * although many DNS queries may be generated from a single call to
                    113:  * evdns_resolve. Searching can also drastically slow down the resolution
                    114:  * of names.
                    115:  *
                    116:  * To disable searching:
                    117:  *   1. Never set it up. If you never call evdns_resolv_conf_parse or
                    118:  *   evdns_search_add then no searching will occur.
                    119:  *
                    120:  *   2. If you do call evdns_resolv_conf_parse then don't pass
                    121:  *   DNS_OPTION_SEARCH (or DNS_OPTIONS_ALL, which implies it).
                    122:  *
                    123:  *   3. When calling evdns_resolve, pass the DNS_QUERY_NO_SEARCH flag.
                    124:  *
                    125:  * The order of searches depends on the number of dots in the name. If the
                    126:  * number is greater than the ndots setting then the names is first tried
                    127:  * globally. Otherwise each search domain is appended in turn.
                    128:  *
                    129:  * The ndots setting can either be set from a resolv.conf, or by calling
                    130:  * evdns_search_ndots_set.
                    131:  *
                    132:  * For example, with ndots set to 1 (the default) and a search domain list of
                    133:  * ["myhome.net"]:
                    134:  *  Query: www
                    135:  *  Order: www.myhome.net, www.
                    136:  *
                    137:  *  Query: www.abc
                    138:  *  Order: www.abc., www.abc.myhome.net
                    139:  *
                    140:  * Internals:
                    141:  *
                    142:  * Requests are kept in two queues. The first is the inflight queue. In
                    143:  * this queue requests have an allocated transaction id and nameserver.
                    144:  * They will soon be transmitted if they haven't already been.
                    145:  *
                    146:  * The second is the waiting queue. The size of the inflight ring is
                    147:  * limited and all other requests wait in waiting queue for space. This
                    148:  * bounds the number of concurrent requests so that we don't flood the
                    149:  * nameserver. Several algorithms require a full walk of the inflight
                    150:  * queue and so bounding its size keeps thing going nicely under huge
                    151:  * (many thousands of requests) loads.
                    152:  *
                    153:  * If a nameserver loses too many requests it is considered down and we
                    154:  * try not to use it. After a while we send a probe to that nameserver
                    155:  * (a lookup for google.com) and, if it replies, we consider it working
                    156:  * again. If the nameserver fails a probe we wait longer to try again
                    157:  * with the next probe.
                    158:  */
                    159: 
                    160: #ifndef EVENTDNS_H
                    161: #define EVENTDNS_H
                    162: 
                    163: #ifdef __cplusplus
                    164: extern "C" {
                    165: #endif
                    166: 
                    167: /* For integer types. */
                    168: #include <evutil.h>
                    169: 
                    170: /** Error codes 0-5 are as described in RFC 1035. */
                    171: #define DNS_ERR_NONE 0
                    172: /** The name server was unable to interpret the query */
                    173: #define DNS_ERR_FORMAT 1
                    174: /** The name server was unable to process this query due to a problem with the
                    175:  * name server */
                    176: #define DNS_ERR_SERVERFAILED 2
                    177: /** The domain name does not exist */
                    178: #define DNS_ERR_NOTEXIST 3
                    179: /** The name server does not support the requested kind of query */
                    180: #define DNS_ERR_NOTIMPL 4
                    181: /** The name server refuses to reform the specified operation for policy
                    182:  * reasons */
                    183: #define DNS_ERR_REFUSED 5
                    184: /** The reply was truncated or ill-formated */
                    185: #define DNS_ERR_TRUNCATED 65
                    186: /** An unknown error occurred */
                    187: #define DNS_ERR_UNKNOWN 66
                    188: /** Communication with the server timed out */
                    189: #define DNS_ERR_TIMEOUT 67
                    190: /** The request was canceled because the DNS subsystem was shut down. */
                    191: #define DNS_ERR_SHUTDOWN 68
                    192: 
                    193: #define DNS_IPv4_A 1
                    194: #define DNS_PTR 2
                    195: #define DNS_IPv6_AAAA 3
                    196: 
                    197: #define DNS_QUERY_NO_SEARCH 1
                    198: 
                    199: #define DNS_OPTION_SEARCH 1
                    200: #define DNS_OPTION_NAMESERVERS 2
                    201: #define DNS_OPTION_MISC 4
                    202: #define DNS_OPTIONS_ALL 7
                    203: 
                    204: /**
                    205:  * The callback that contains the results from a lookup.
                    206:  * - type is either DNS_IPv4_A or DNS_PTR or DNS_IPv6_AAAA
                    207:  * - count contains the number of addresses of form type
                    208:  * - ttl is the number of seconds the resolution may be cached for.
                    209:  * - addresses needs to be cast according to type
                    210:  */
                    211: typedef void (*evdns_callback_type) (int result, char type, int count, int ttl, void *addresses, void *arg);
                    212: 
                    213: /**
                    214:   Initialize the asynchronous DNS library.
                    215: 
                    216:   This function initializes support for non-blocking name resolution by
                    217:   calling evdns_resolv_conf_parse() on UNIX and
                    218:   evdns_config_windows_nameservers() on Windows.
                    219: 
                    220:   @return 0 if successful, or -1 if an error occurred
                    221:   @see evdns_shutdown()
                    222:  */
                    223: int evdns_init(void);
                    224: 
                    225: 
                    226: /**
                    227:   Shut down the asynchronous DNS resolver and terminate all active requests.
                    228: 
                    229:   If the 'fail_requests' option is enabled, all active requests will return
                    230:   an empty result with the error flag set to DNS_ERR_SHUTDOWN. Otherwise,
                    231:   the requests will be silently discarded.
                    232: 
                    233:   @param fail_requests if zero, active requests will be aborted; if non-zero,
                    234:                active requests will return DNS_ERR_SHUTDOWN.
                    235:   @see evdns_init()
                    236:  */
                    237: void evdns_shutdown(int fail_requests);
                    238: 
                    239: 
                    240: /**
                    241:   Convert a DNS error code to a string.
                    242: 
                    243:   @param err the DNS error code
                    244:   @return a string containing an explanation of the error code
                    245: */
                    246: const char *evdns_err_to_string(int err);
                    247: 
                    248: 
                    249: /**
                    250:   Add a nameserver.
                    251: 
                    252:   The address should be an IPv4 address in network byte order.
                    253:   The type of address is chosen so that it matches in_addr.s_addr.
                    254: 
                    255:   @param address an IP address in network byte order
                    256:   @return 0 if successful, or -1 if an error occurred
                    257:   @see evdns_nameserver_ip_add()
                    258:  */
                    259: int evdns_nameserver_add(unsigned long int address);
                    260: 
                    261: 
                    262: /**
                    263:   Get the number of configured nameservers.
                    264: 
                    265:   This returns the number of configured nameservers (not necessarily the
                    266:   number of running nameservers).  This is useful for double-checking
                    267:   whether our calls to the various nameserver configuration functions
                    268:   have been successful.
                    269: 
                    270:   @return the number of configured nameservers
                    271:   @see evdns_nameserver_add()
                    272:  */
                    273: int evdns_count_nameservers(void);
                    274: 
                    275: 
                    276: /**
                    277:   Remove all configured nameservers, and suspend all pending resolves.
                    278: 
                    279:   Resolves will not necessarily be re-attempted until evdns_resume() is called.
                    280: 
                    281:   @return 0 if successful, or -1 if an error occurred
                    282:   @see evdns_resume()
                    283:  */
                    284: int evdns_clear_nameservers_and_suspend(void);
                    285: 
                    286: 
                    287: /**
                    288:   Resume normal operation and continue any suspended resolve requests.
                    289: 
                    290:   Re-attempt resolves left in limbo after an earlier call to
                    291:   evdns_clear_nameservers_and_suspend().
                    292: 
                    293:   @return 0 if successful, or -1 if an error occurred
                    294:   @see evdns_clear_nameservers_and_suspend()
                    295:  */
                    296: int evdns_resume(void);
                    297: 
                    298: 
                    299: /**
                    300:   Add a nameserver.
                    301: 
                    302:   This wraps the evdns_nameserver_add() function by parsing a string as an IP
                    303:   address and adds it as a nameserver.
                    304: 
                    305:   @return 0 if successful, or -1 if an error occurred
                    306:   @see evdns_nameserver_add()
                    307:  */
                    308: int evdns_nameserver_ip_add(const char *ip_as_string);
                    309: 
                    310: 
                    311: /**
                    312:   Lookup an A record for a given name.
                    313: 
                    314:   @param name a DNS hostname
                    315:   @param flags either 0, or DNS_QUERY_NO_SEARCH to disable searching for this query.
                    316:   @param callback a callback function to invoke when the request is completed
                    317:   @param ptr an argument to pass to the callback function
                    318:   @return 0 if successful, or -1 if an error occurred
                    319:   @see evdns_resolve_ipv6(), evdns_resolve_reverse(), evdns_resolve_reverse_ipv6()
                    320:  */
                    321: int evdns_resolve_ipv4(const char *name, int flags, evdns_callback_type callback, void *ptr);
                    322: 
                    323: 
                    324: /**
                    325:   Lookup an AAAA record for a given name.
                    326: 
                    327:   @param name a DNS hostname
                    328:   @param flags either 0, or DNS_QUERY_NO_SEARCH to disable searching for this query.
                    329:   @param callback a callback function to invoke when the request is completed
                    330:   @param ptr an argument to pass to the callback function
                    331:   @return 0 if successful, or -1 if an error occurred
                    332:   @see evdns_resolve_ipv4(), evdns_resolve_reverse(), evdns_resolve_reverse_ipv6()
                    333:  */
                    334: int evdns_resolve_ipv6(const char *name, int flags, evdns_callback_type callback, void *ptr);
                    335: 
                    336: struct in_addr;
                    337: struct in6_addr;
                    338: 
                    339: /**
                    340:   Lookup a PTR record for a given IP address.
                    341: 
                    342:   @param in an IPv4 address
                    343:   @param flags either 0, or DNS_QUERY_NO_SEARCH to disable searching for this query.
                    344:   @param callback a callback function to invoke when the request is completed
                    345:   @param ptr an argument to pass to the callback function
                    346:   @return 0 if successful, or -1 if an error occurred
                    347:   @see evdns_resolve_reverse_ipv6()
                    348:  */
                    349: int evdns_resolve_reverse(const struct in_addr *in, int flags, evdns_callback_type callback, void *ptr);
                    350: 
                    351: 
                    352: /**
                    353:   Lookup a PTR record for a given IPv6 address.
                    354: 
                    355:   @param in an IPv6 address
                    356:   @param flags either 0, or DNS_QUERY_NO_SEARCH to disable searching for this query.
                    357:   @param callback a callback function to invoke when the request is completed
                    358:   @param ptr an argument to pass to the callback function
                    359:   @return 0 if successful, or -1 if an error occurred
                    360:   @see evdns_resolve_reverse_ipv6()
                    361:  */
                    362: int evdns_resolve_reverse_ipv6(const struct in6_addr *in, int flags, evdns_callback_type callback, void *ptr);
                    363: 
                    364: 
                    365: /**
                    366:   Set the value of a configuration option.
                    367: 
                    368:   The currently available configuration options are:
                    369: 
                    370:     ndots, timeout, max-timeouts, max-inflight, and attempts
                    371: 
                    372:   @param option the name of the configuration option to be modified
                    373:   @param val the value to be set
                    374:   @param flags either 0 | DNS_OPTION_SEARCH | DNS_OPTION_MISC
                    375:   @return 0 if successful, or -1 if an error occurred
                    376:  */
                    377: int evdns_set_option(const char *option, const char *val, int flags);
                    378: 
                    379: 
                    380: /**
                    381:   Parse a resolv.conf file.
                    382: 
                    383:   The 'flags' parameter determines what information is parsed from the
                    384:   resolv.conf file. See the man page for resolv.conf for the format of this
                    385:   file.
                    386: 
                    387:   The following directives are not parsed from the file: sortlist, rotate,
                    388:   no-check-names, inet6, debug.
                    389: 
                    390:   If this function encounters an error, the possible return values are: 1 =
                    391:   failed to open file, 2 = failed to stat file, 3 = file too large, 4 = out of
                    392:   memory, 5 = short read from file, 6 = no nameservers listed in the file
                    393: 
                    394:   @param flags any of DNS_OPTION_NAMESERVERS|DNS_OPTION_SEARCH|DNS_OPTION_MISC|
                    395:          DNS_OPTIONS_ALL
                    396:   @param filename the path to the resolv.conf file
                    397:   @return 0 if successful, or various positive error codes if an error
                    398:           occurred (see above)
                    399:   @see resolv.conf(3), evdns_config_windows_nameservers()
                    400:  */
                    401: int evdns_resolv_conf_parse(int flags, const char *const filename);
                    402: 
                    403: 
                    404: /**
                    405:   Obtain nameserver information using the Windows API.
                    406: 
                    407:   Attempt to configure a set of nameservers based on platform settings on
                    408:   a win32 host.  Preferentially tries to use GetNetworkParams; if that fails,
                    409:   looks in the registry.
                    410: 
                    411:   @return 0 if successful, or -1 if an error occurred
                    412:   @see evdns_resolv_conf_parse()
                    413:  */
                    414: #ifdef WIN32
                    415: int evdns_config_windows_nameservers(void);
                    416: #endif
                    417: 
                    418: 
                    419: /**
                    420:   Clear the list of search domains.
                    421:  */
                    422: void evdns_search_clear(void);
                    423: 
                    424: 
                    425: /**
                    426:   Add a domain to the list of search domains
                    427: 
                    428:   @param domain the domain to be added to the search list
                    429:  */
                    430: void evdns_search_add(const char *domain);
                    431: 
                    432: 
                    433: /**
                    434:   Set the 'ndots' parameter for searches.
                    435: 
                    436:   Sets the number of dots which, when found in a name, causes
                    437:   the first query to be without any search domain.
                    438: 
                    439:   @param ndots the new ndots parameter
                    440:  */
                    441: void evdns_search_ndots_set(const int ndots);
                    442: 
                    443: /**
                    444:   A callback that is invoked when a log message is generated
                    445: 
                    446:   @param is_warning indicates if the log message is a 'warning'
                    447:   @param msg the content of the log message
                    448:  */
                    449: typedef void (*evdns_debug_log_fn_type)(int is_warning, const char *msg);
                    450: 
                    451: 
                    452: /**
                    453:   Set the callback function to handle log messages.
                    454: 
                    455:   @param fn the callback to be invoked when a log message is generated
                    456:  */
                    457: void evdns_set_log_fn(evdns_debug_log_fn_type fn);
                    458: 
                    459: /**
                    460:    Set a callback that will be invoked to generate transaction IDs.  By
                    461:    default, we pick transaction IDs based on the current clock time.
                    462: 
                    463:    @param fn the new callback, or NULL to use the default.
                    464:  */
                    465: void evdns_set_transaction_id_fn(ev_uint16_t (*fn)(void));
                    466: 
                    467: #define DNS_NO_SEARCH 1
                    468: 
                    469: /*
                    470:  * Structures and functions used to implement a DNS server.
                    471:  */
                    472: 
                    473: struct evdns_server_request {
                    474:        int flags;
                    475:        int nquestions;
                    476:        struct evdns_server_question **questions;
                    477: };
                    478: struct evdns_server_question {
                    479:        int type;
                    480: #ifdef __cplusplus
                    481:        int dns_question_class;
                    482: #else
                    483:        /* You should refer to this field as "dns_question_class".  The
                    484:         * name "class" works in C for backward compatibility, and will be
                    485:         * removed in a future version. (1.5 or later). */
                    486:        int class;
                    487: #define dns_question_class class
                    488: #endif
                    489:        char name[1];
                    490: };
                    491: typedef void (*evdns_request_callback_fn_type)(struct evdns_server_request *, void *);
                    492: #define EVDNS_ANSWER_SECTION 0
                    493: #define EVDNS_AUTHORITY_SECTION 1
                    494: #define EVDNS_ADDITIONAL_SECTION 2
                    495: 
                    496: #define EVDNS_TYPE_A      1
                    497: #define EVDNS_TYPE_NS     2
                    498: #define EVDNS_TYPE_CNAME   5
                    499: #define EVDNS_TYPE_SOA    6
                    500: #define EVDNS_TYPE_PTR   12
                    501: #define EVDNS_TYPE_MX    15
                    502: #define EVDNS_TYPE_TXT   16
                    503: #define EVDNS_TYPE_AAAA          28
                    504: 
                    505: #define EVDNS_QTYPE_AXFR 252
                    506: #define EVDNS_QTYPE_ALL         255
                    507: 
                    508: #define EVDNS_CLASS_INET   1
                    509: 
                    510: struct evdns_server_port *evdns_add_server_port(int socket, int is_tcp, evdns_request_callback_fn_type callback, void *user_data);
                    511: void evdns_close_server_port(struct evdns_server_port *port);
                    512: 
                    513: int evdns_server_request_add_reply(struct evdns_server_request *req, int section, const char *name, int type, int dns_class, int ttl, int datalen, int is_name, const char *data);
                    514: int evdns_server_request_add_a_reply(struct evdns_server_request *req, const char *name, int n, void *addrs, int ttl);
                    515: int evdns_server_request_add_aaaa_reply(struct evdns_server_request *req, const char *name, int n, void *addrs, int ttl);
                    516: int evdns_server_request_add_ptr_reply(struct evdns_server_request *req, struct in_addr *in, const char *inaddr_name, const char *hostname, int ttl);
                    517: int evdns_server_request_add_cname_reply(struct evdns_server_request *req, const char *name, const char *cname, int ttl);
                    518: 
                    519: int evdns_server_request_respond(struct evdns_server_request *req, int err);
                    520: int evdns_server_request_drop(struct evdns_server_request *req);
                    521: struct sockaddr;
                    522: int evdns_server_request_get_requesting_addr(struct evdns_server_request *_req, struct sockaddr *sa, int addr_len);
                    523: 
                    524: #ifdef __cplusplus
                    525: }
                    526: #endif
                    527: 
                    528: #endif  /* !EVENTDNS_H */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>