A clone of btpd with my configuration changes.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

307 lines
12 KiB

  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. * The original DNS code is due to Adam Langley with heavy
  29. * modifications by Nick Mathewson. Adam put his DNS software in the
  30. * public domain. You can find his original copyright below. Please,
  31. * aware that the code as part of libevent is governed by the 3-clause
  32. * BSD license above.
  33. *
  34. * This software is Public Domain. To view a copy of the public domain dedication,
  35. * visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
  36. * Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
  37. *
  38. * I ask and expect, but do not require, that all derivative works contain an
  39. * attribution similar to:
  40. * Parts developed by Adam Langley <agl@imperialviolet.org>
  41. *
  42. * You may wish to replace the word "Parts" with something else depending on
  43. * the amount of original code.
  44. *
  45. * (Derivative works does not include programs which link against, run or include
  46. * the source verbatim in their source distributions)
  47. */
  48. /*
  49. * Welcome, gentle reader
  50. *
  51. * Async DNS lookups are really a whole lot harder than they should be,
  52. * mostly stemming from the fact that the libc resolver has never been
  53. * very good at them. Before you use this library you should see if libc
  54. * can do the job for you with the modern async call getaddrinfo_a
  55. * (see http://www.imperialviolet.org/page25.html#e498). Otherwise,
  56. * please continue.
  57. *
  58. * This code is based on libevent and you must call event_init before
  59. * any of the APIs in this file. You must also seed the OpenSSL random
  60. * source if you are using OpenSSL for ids (see below).
  61. *
  62. * This library is designed to be included and shipped with your source
  63. * code. You statically link with it. You should also test for the
  64. * existence of strtok_r and define HAVE_STRTOK_R if you have it.
  65. *
  66. * The DNS protocol requires a good source of id numbers and these
  67. * numbers should be unpredictable for spoofing reasons. There are
  68. * three methods for generating them here and you must define exactly
  69. * one of them. In increasing order of preference:
  70. *
  71. * DNS_USE_GETTIMEOFDAY_FOR_ID:
  72. * Using the bottom 16 bits of the usec result from gettimeofday. This
  73. * is a pretty poor solution but should work anywhere.
  74. * DNS_USE_CPU_CLOCK_FOR_ID:
  75. * Using the bottom 16 bits of the nsec result from the CPU's time
  76. * counter. This is better, but may not work everywhere. Requires
  77. * POSIX realtime support and you'll need to link against -lrt on
  78. * glibc systems at least.
  79. * DNS_USE_OPENSSL_FOR_ID:
  80. * Uses the OpenSSL RAND_bytes call to generate the data. You must
  81. * have seeded the pool before making any calls to this library.
  82. *
  83. * The library keeps track of the state of nameservers and will avoid
  84. * them when they go down. Otherwise it will round robin between them.
  85. *
  86. * Quick start guide:
  87. * #include "evdns.h"
  88. * void callback(int result, char type, int count, int ttl,
  89. * void *addresses, void *arg);
  90. * evdns_resolv_conf_parse(DNS_OPTIONS_ALL, "/etc/resolv.conf");
  91. * evdns_resolve("www.hostname.com", 0, callback, NULL);
  92. *
  93. * When the lookup is complete the callback function is called. The
  94. * first argument will be one of the DNS_ERR_* defines in evdns.h.
  95. * Hopefully it will be DNS_ERR_NONE, in which case type will be
  96. * DNS_IPv4_A, count will be the number of IP addresses, ttl is the time
  97. * which the data can be cached for (in seconds), addresses will point
  98. * to an array of uint32_t's and arg will be whatever you passed to
  99. * evdns_resolve.
  100. *
  101. * Searching:
  102. *
  103. * In order for this library to be a good replacement for glibc's resolver it
  104. * supports searching. This involves setting a list of default domains, in
  105. * which names will be queried for. The number of dots in the query name
  106. * determines the order in which this list is used.
  107. *
  108. * Searching appears to be a single lookup from the point of view of the API,
  109. * although many DNS queries may be generated from a single call to
  110. * evdns_resolve. Searching can also drastically slow down the resolution
  111. * of names.
  112. *
  113. * To disable searching:
  114. * 1. Never set it up. If you never call evdns_resolv_conf_parse or
  115. * evdns_search_add then no searching will occur.
  116. *
  117. * 2. If you do call evdns_resolv_conf_parse then don't pass
  118. * DNS_OPTION_SEARCH (or DNS_OPTIONS_ALL, which implies it).
  119. *
  120. * 3. When calling evdns_resolve, pass the DNS_QUERY_NO_SEARCH flag.
  121. *
  122. * The order of searches depends on the number of dots in the name. If the
  123. * number is greater than the ndots setting then the names is first tried
  124. * globally. Otherwise each search domain is appended in turn.
  125. *
  126. * The ndots setting can either be set from a resolv.conf, or by calling
  127. * evdns_search_ndots_set.
  128. *
  129. * For example, with ndots set to 1 (the default) and a search domain list of
  130. * ["myhome.net"]:
  131. * Query: www
  132. * Order: www.myhome.net, www.
  133. *
  134. * Query: www.abc
  135. * Order: www.abc., www.abc.myhome.net
  136. *
  137. * API reference:
  138. *
  139. * int evdns_nameserver_add(unsigned long int address)
  140. * Add a nameserver. The address should be an IP address in
  141. * network byte order. The type of address is chosen so that
  142. * it matches in_addr.s_addr.
  143. * Returns non-zero on error.
  144. *
  145. * int evdns_nameserver_ip_add(const char *ip_as_string)
  146. * This wraps the above function by parsing a string as an IP
  147. * address and adds it as a nameserver.
  148. * Returns non-zero on error
  149. *
  150. * int evdns_resolve(const char *name, int flags,
  151. * evdns_callback_type callback,
  152. * void *ptr)
  153. * Resolve a name. The name parameter should be a DNS name.
  154. * The flags parameter should be 0, or DNS_QUERY_NO_SEARCH
  155. * which disables searching for this query. (see defn of
  156. * searching above).
  157. *
  158. * The callback argument is a function which is called when
  159. * this query completes and ptr is an argument which is passed
  160. * to that callback function.
  161. *
  162. * Returns non-zero on error
  163. *
  164. * void evdns_search_clear()
  165. * Clears the list of search domains
  166. *
  167. * void evdns_search_add(const char *domain)
  168. * Add a domain to the list of search domains
  169. *
  170. * void evdns_search_ndots_set(int ndots)
  171. * Set the number of dots which, when found in a name, causes
  172. * the first query to be without any search domain.
  173. *
  174. * int evdns_count_nameservers(void)
  175. * Return the number of configured nameservers (not necessarily the
  176. * number of running nameservers). This is useful for double-checking
  177. * whether our calls to the various nameserver configuration functions
  178. * have been successful.
  179. *
  180. * int evdns_clear_nameservers_and_suspend(void)
  181. * Remove all currently configured nameservers, and suspend all pending
  182. * resolves. Resolves will not necessarily be re-attempted until
  183. * evdns_resume() is called.
  184. *
  185. * int evdns_resume(void)
  186. * Re-attempt resolves left in limbo after an earlier call to
  187. * evdns_clear_nameservers_and_suspend().
  188. *
  189. * int evdns_config_windows_nameservers(void)
  190. * Attempt to configure a set of nameservers based on platform settings on
  191. * a win32 host. Preferentially tries to use GetNetworkParams; if that fails,
  192. * looks in the registry. Returns 0 on success, nonzero on failure.
  193. *
  194. * int evdns_resolv_conf_parse(int flags, const char *filename)
  195. * Parse a resolv.conf like file from the given filename.
  196. *
  197. * See the man page for resolv.conf for the format of this file.
  198. * The flags argument determines what information is parsed from
  199. * this file:
  200. * DNS_OPTION_SEARCH - domain, search and ndots options
  201. * DNS_OPTION_NAMESERVERS - nameserver lines
  202. * DNS_OPTION_MISC - timeout and attempts options
  203. * DNS_OPTIONS_ALL - all of the above
  204. * The following directives are not parsed from the file:
  205. * sortlist, rotate, no-check-names, inet6, debug
  206. *
  207. * Returns non-zero on error:
  208. * 0 no errors
  209. * 1 failed to open file
  210. * 2 failed to stat file
  211. * 3 file too large
  212. * 4 out of memory
  213. * 5 short read from file
  214. *
  215. * Internals:
  216. *
  217. * Requests are kept in two queues. The first is the inflight queue. In
  218. * this queue requests have an allocated transaction id and nameserver.
  219. * They will soon be transmitted if they haven't already been.
  220. *
  221. * The second is the waiting queue. The size of the inflight ring is
  222. * limited and all other requests wait in waiting queue for space. This
  223. * bounds the number of concurrent requests so that we don't flood the
  224. * nameserver. Several algorithms require a full walk of the inflight
  225. * queue and so bounding its size keeps thing going nicely under huge
  226. * (many thousands of requests) loads.
  227. *
  228. * If a nameserver loses too many requests it is considered down and we
  229. * try not to use it. After a while we send a probe to that nameserver
  230. * (a lookup for google.com) and, if it replies, we consider it working
  231. * again. If the nameserver fails a probe we wait longer to try again
  232. * with the next probe.
  233. */
  234. #ifndef EVENTDNS_H
  235. #define EVENTDNS_H
  236. /* Error codes 0-5 are as described in RFC 1035. */
  237. #define DNS_ERR_NONE 0
  238. /* The name server was unable to interpret the query */
  239. #define DNS_ERR_FORMAT 1
  240. /* The name server was unable to process this query due to a problem with the
  241. * name server */
  242. #define DNS_ERR_SERVERFAILED 2
  243. /* The domain name does not exist */
  244. #define DNS_ERR_NOTEXIST 3
  245. /* The name server does not support the requested kind of query */
  246. #define DNS_ERR_NOTIMPL 4
  247. /* The name server refuses to reform the specified operation for policy
  248. * reasons */
  249. #define DNS_ERR_REFUSED 5
  250. /* The reply was truncated or ill-formated */
  251. #define DNS_ERR_TRUNCATED 65
  252. /* An unknown error occurred */
  253. #define DNS_ERR_UNKNOWN 66
  254. /* Communication with the server timed out */
  255. #define DNS_ERR_TIMEOUT 67
  256. /* The request was canceled because the DNS subsystem was shut down. */
  257. #define DNS_ERR_SHUTDOWN 68
  258. #define DNS_IPv4_A 1
  259. #define DNS_PTR 2
  260. #define DNS_QUERY_NO_SEARCH 1
  261. #define DNS_OPTION_SEARCH 1
  262. #define DNS_OPTION_NAMESERVERS 2
  263. #define DNS_OPTION_MISC 4
  264. #define DNS_OPTIONS_ALL 7
  265. /*
  266. * The callback that contains the results from a lookup.
  267. * - type is either DNS_IPv4_A or DNS_PTR
  268. * - count contains the number of addresses of form type
  269. * - ttl is the number of seconds the resolution may be cached for.
  270. * - addresses needs to be cast according to type
  271. */
  272. typedef void (*evdns_callback_type) (int result, char type, int count, int ttl, void *addresses, void *arg);
  273. int evdns_init(void);
  274. void evdns_shutdown(int fail_requests);
  275. const char *evdns_err_to_string(int err);
  276. int evdns_nameserver_add(unsigned long int address);
  277. int evdns_count_nameservers(void);
  278. int evdns_clear_nameservers_and_suspend(void);
  279. int evdns_resume(void);
  280. int evdns_nameserver_ip_add(const char *ip_as_string);
  281. int evdns_resolve_ipv4(const char *name, int flags, evdns_callback_type callback, void *ptr);
  282. struct in_addr;
  283. int evdns_resolve_reverse(struct in_addr *in, int flags, evdns_callback_type callback, void *ptr);
  284. int evdns_resolv_conf_parse(int flags, const char *);
  285. #ifdef MS_WINDOWS
  286. int evdns_config_windows_nameservers(void);
  287. #endif
  288. void evdns_search_clear(void);
  289. void evdns_search_add(const char *domain);
  290. void evdns_search_ndots_set(const int ndots);
  291. typedef void (*evdns_debug_log_fn_type)(int is_warning, const char *msg);
  292. void evdns_set_log_fn(evdns_debug_log_fn_type fn);
  293. #define DNS_NO_SEARCH 1
  294. #endif // !EVENTDNS_H