resolve.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. /* Copyright (c) 2003-2004, Roger Dingledine
  2. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  3. * Copyright (c) 2007-2019, The Tor Project, Inc. */
  4. /* See LICENSE for licensing information */
  5. /**
  6. * \file resolve.c
  7. * \brief Use the libc DNS resolver to convert hostnames into addresses.
  8. **/
  9. #include "lib/net/resolve.h"
  10. #include "lib/net/address.h"
  11. #include "lib/net/inaddr.h"
  12. #include "lib/malloc/malloc.h"
  13. #include "lib/string/parse_int.h"
  14. #include "lib/string/util_string.h"
  15. #include "ext/siphash.h"
  16. #include "ext/ht.h"
  17. #ifdef HAVE_SYS_TYPES_H
  18. #include <sys/types.h>
  19. #endif
  20. #ifdef HAVE_SYS_SOCKET_H
  21. #include <sys/socket.h>
  22. #endif
  23. #ifdef HAVE_NETDB_H
  24. #include <netdb.h>
  25. #endif
  26. #include <string.h>
  27. /** Similar behavior to Unix gethostbyname: resolve <b>name</b>, and set
  28. * *<b>addr</b> to the proper IP address, in host byte order. Returns 0
  29. * on success, -1 on failure; 1 on transient failure.
  30. *
  31. * This function only accepts IPv4 addresses.
  32. *
  33. * (This function exists because standard windows gethostbyname
  34. * doesn't treat raw IP addresses properly.)
  35. */
  36. MOCK_IMPL(int,
  37. tor_lookup_hostname,(const char *name, uint32_t *addr))
  38. {
  39. tor_addr_t myaddr;
  40. int ret;
  41. if (BUG(!addr))
  42. return -1;
  43. *addr = 0;
  44. if ((ret = tor_addr_lookup(name, AF_INET, &myaddr)))
  45. return ret;
  46. if (tor_addr_family(&myaddr) == AF_INET) {
  47. *addr = tor_addr_to_ipv4h(&myaddr);
  48. return ret;
  49. }
  50. return -1;
  51. }
  52. #ifdef HAVE_GETADDRINFO
  53. /* Host lookup helper for tor_addr_lookup(), when getaddrinfo() is
  54. * available on this system.
  55. *
  56. * See tor_addr_lookup() for details.
  57. */
  58. static int
  59. tor_addr_lookup_host_getaddrinfo(const char *name,
  60. uint16_t family,
  61. tor_addr_t *addr)
  62. {
  63. int err;
  64. struct addrinfo *res=NULL, *res_p;
  65. struct addrinfo *best=NULL;
  66. struct addrinfo hints;
  67. int result = -1;
  68. memset(&hints, 0, sizeof(hints));
  69. hints.ai_family = family;
  70. hints.ai_socktype = SOCK_STREAM;
  71. err = tor_getaddrinfo(name, NULL, &hints, &res);
  72. /* The check for 'res' here shouldn't be necessary, but it makes static
  73. * analysis tools happy. */
  74. if (!err && res) {
  75. best = NULL;
  76. for (res_p = res; res_p; res_p = res_p->ai_next) {
  77. if (family == AF_UNSPEC) {
  78. if (res_p->ai_family == AF_INET) {
  79. best = res_p;
  80. break;
  81. } else if (res_p->ai_family == AF_INET6 && !best) {
  82. best = res_p;
  83. }
  84. } else if (family == res_p->ai_family) {
  85. best = res_p;
  86. break;
  87. }
  88. }
  89. if (!best)
  90. best = res;
  91. if (best->ai_family == AF_INET) {
  92. tor_addr_from_in(addr,
  93. &((struct sockaddr_in*)best->ai_addr)->sin_addr);
  94. result = 0;
  95. } else if (best->ai_family == AF_INET6) {
  96. tor_addr_from_in6(addr,
  97. &((struct sockaddr_in6*)best->ai_addr)->sin6_addr);
  98. result = 0;
  99. }
  100. tor_freeaddrinfo(res);
  101. return result;
  102. }
  103. return (err == EAI_AGAIN) ? 1 : -1;
  104. }
  105. #else /* !defined(HAVE_GETADDRINFO) */
  106. /* Host lookup helper for tor_addr_lookup(), which calls getaddrinfo().
  107. * Used when gethostbyname() is not available on this system.
  108. *
  109. * See tor_addr_lookup() for details.
  110. */
  111. static int
  112. tor_addr_lookup_host_gethostbyname(const char *name,
  113. tor_addr_t *addr)
  114. {
  115. struct hostent *ent;
  116. int err;
  117. #ifdef HAVE_GETHOSTBYNAME_R_6_ARG
  118. char buf[2048];
  119. struct hostent hostent;
  120. int r;
  121. r = gethostbyname_r(name, &hostent, buf, sizeof(buf), &ent, &err);
  122. #elif defined(HAVE_GETHOSTBYNAME_R_5_ARG)
  123. char buf[2048];
  124. struct hostent hostent;
  125. ent = gethostbyname_r(name, &hostent, buf, sizeof(buf), &err);
  126. #elif defined(HAVE_GETHOSTBYNAME_R_3_ARG)
  127. struct hostent_data data;
  128. struct hostent hent;
  129. memset(&data, 0, sizeof(data));
  130. err = gethostbyname_r(name, &hent, &data);
  131. ent = err ? NULL : &hent;
  132. #else
  133. ent = gethostbyname(name);
  134. #ifdef _WIN32
  135. err = WSAGetLastError();
  136. #else
  137. err = h_errno;
  138. #endif /* defined(_WIN32) */
  139. #endif /* defined(HAVE_GETHOSTBYNAME_R_6_ARG) || ... */
  140. if (ent) {
  141. if (ent->h_addrtype == AF_INET) {
  142. tor_addr_from_in(addr, (struct in_addr*) ent->h_addr);
  143. } else if (ent->h_addrtype == AF_INET6) {
  144. tor_addr_from_in6(addr, (struct in6_addr*) ent->h_addr);
  145. } else {
  146. tor_assert(0); // LCOV_EXCL_LINE: gethostbyname() returned bizarre type
  147. }
  148. return 0;
  149. }
  150. #ifdef _WIN32
  151. return (err == WSATRY_AGAIN) ? 1 : -1;
  152. #else
  153. return (err == TRY_AGAIN) ? 1 : -1;
  154. #endif
  155. }
  156. #endif /* defined(HAVE_GETADDRINFO) */
  157. /** Similar behavior to Unix gethostbyname: resolve <b>name</b>, and set
  158. * *<b>addr</b> to the proper IP address and family. The <b>family</b>
  159. * argument (which must be AF_INET, AF_INET6, or AF_UNSPEC) declares a
  160. * <i>preferred</i> family, though another one may be returned if only one
  161. * family is implemented for this address.
  162. *
  163. * Like tor_addr_parse(), this function accepts IPv6 addresses with or without
  164. * square brackets.
  165. *
  166. * Return 0 on success, -1 on failure; 1 on transient failure.
  167. */
  168. MOCK_IMPL(int,
  169. tor_addr_lookup,(const char *name, uint16_t family, tor_addr_t *addr))
  170. {
  171. /* Perhaps eventually this should be replaced by a tor_getaddrinfo or
  172. * something.
  173. */
  174. int parsed_family = 0;
  175. int result = -1;
  176. tor_assert(name);
  177. tor_assert(addr);
  178. tor_assert(family == AF_INET || family == AF_INET6 || family == AF_UNSPEC);
  179. if (!*name) {
  180. /* Empty address is an error. */
  181. goto permfail;
  182. }
  183. /* Is it an IP address? */
  184. parsed_family = tor_addr_parse(addr, name);
  185. if (parsed_family >= 0) {
  186. /* If the IP address family matches, or was unspecified */
  187. if (parsed_family == family || family == AF_UNSPEC) {
  188. goto success;
  189. } else {
  190. goto permfail;
  191. }
  192. } else {
  193. /* Clear the address after a failed tor_addr_parse(). */
  194. memset(addr, 0, sizeof(tor_addr_t));
  195. #ifdef HAVE_GETADDRINFO
  196. result = tor_addr_lookup_host_getaddrinfo(name, family, addr);
  197. goto done;
  198. #else /* !(defined(HAVE_GETADDRINFO)) */
  199. result = tor_addr_lookup_host_gethostbyname(name, addr);
  200. goto done;
  201. #endif /* defined(HAVE_GETADDRINFO) */
  202. }
  203. /* If we weren't successful, and haven't already set the result,
  204. * assume it's a permanent failure */
  205. permfail:
  206. result = -1;
  207. goto done;
  208. success:
  209. result = 0;
  210. /* We have set the result, now it's time to clean up */
  211. done:
  212. if (result) {
  213. /* Clear the address on error */
  214. memset(addr, 0, sizeof(tor_addr_t));
  215. }
  216. return result;
  217. }
  218. /** Parse an address or address-port combination from <b>s</b>, resolve the
  219. * address as needed, and put the result in <b>addr_out</b> and (optionally)
  220. * <b>port_out</b>.
  221. *
  222. * Like tor_addr_port_parse(), this function accepts:
  223. * - IPv6 address and port, when the IPv6 address is in square brackets,
  224. * - IPv6 address with square brackets,
  225. * - IPv6 address without square brackets.
  226. *
  227. * Return 0 on success, negative on failure. */
  228. int
  229. tor_addr_port_lookup(const char *s, tor_addr_t *addr_out, uint16_t *port_out)
  230. {
  231. tor_addr_t addr;
  232. uint16_t portval = 0;
  233. char *tmp = NULL;
  234. int rv = 0;
  235. int result;
  236. tor_assert(s);
  237. tor_assert(addr_out);
  238. s = eat_whitespace(s);
  239. /* Try parsing s as an address:port first, so we don't have to duplicate
  240. * the logic that rejects IPv6:Port with no square brackets. */
  241. rv = tor_addr_port_parse(LOG_WARN, s, &addr, &portval, 0);
  242. /* That was easy, no DNS required. */
  243. if (rv == 0)
  244. goto success;
  245. /* Now let's check for malformed IPv6 addresses and ports:
  246. * tor_addr_port_parse() requires squared brackes if there is a port,
  247. * and we want tor_addr_port_lookup() to have the same requirement.
  248. * But we strip the port using tor_addr_port_split(), so tor_addr_lookup()
  249. * only sees the address, and will accept it without square brackets. */
  250. int family = tor_addr_parse(&addr, s);
  251. /* If tor_addr_parse() succeeds where tor_addr_port_parse() failed, we need
  252. * to reject this address as malformed. */
  253. if (family >= 0) {
  254. /* Double-check it's an IPv6 address. If not, we have a parsing bug.
  255. */
  256. tor_assertf_nonfatal(family == AF_INET6,
  257. "Wrong family: %d (should be IPv6: %d) which "
  258. "failed IP:port parsing, but passed IP parsing. "
  259. "input string: '%s'; parsed address: '%s'.",
  260. family, AF_INET6, s, fmt_addr(&addr));
  261. goto err;
  262. }
  263. /* Now we have a hostname. Let's split off the port, if any. */
  264. rv = tor_addr_port_split(LOG_WARN, s, &tmp, &portval);
  265. if (rv < 0)
  266. goto err;
  267. /* And feed the hostname to the lookup function. */
  268. if (tor_addr_lookup(tmp, AF_UNSPEC, &addr) != 0)
  269. goto err;
  270. success:
  271. if (port_out)
  272. *port_out = portval;
  273. tor_addr_copy(addr_out, &addr);
  274. result = 0;
  275. goto done;
  276. err:
  277. /* Clear the address and port on error */
  278. memset(addr_out, 0, sizeof(tor_addr_t));
  279. if (port_out)
  280. *port_out = 0;
  281. result = -1;
  282. /* We have set the result, now it's time to clean up */
  283. done:
  284. tor_free(tmp);
  285. return result;
  286. }
  287. #ifdef USE_SANDBOX_GETADDRINFO
  288. /** True if we should only return cached values */
  289. static int sandbox_getaddrinfo_is_active = 0;
  290. /** Cache entry for getaddrinfo results; used when sandboxing is implemented
  291. * so that we can consult the cache when the sandbox prevents us from doing
  292. * getaddrinfo.
  293. *
  294. * We support only a limited range of getaddrinfo calls, where servname is null
  295. * and hints contains only socktype=SOCK_STREAM, family in INET,INET6,UNSPEC.
  296. */
  297. typedef struct cached_getaddrinfo_item_t {
  298. HT_ENTRY(cached_getaddrinfo_item_t) node;
  299. char *name;
  300. int family;
  301. /** set if no error; otherwise NULL */
  302. struct addrinfo *res;
  303. /** 0 for no error; otherwise an EAI_* value */
  304. int err;
  305. } cached_getaddrinfo_item_t;
  306. static unsigned
  307. cached_getaddrinfo_item_hash(const cached_getaddrinfo_item_t *item)
  308. {
  309. return (unsigned)siphash24g(item->name, strlen(item->name)) + item->family;
  310. }
  311. static unsigned
  312. cached_getaddrinfo_items_eq(const cached_getaddrinfo_item_t *a,
  313. const cached_getaddrinfo_item_t *b)
  314. {
  315. return (a->family == b->family) && 0 == strcmp(a->name, b->name);
  316. }
  317. #define cached_getaddrinfo_item_free(item) \
  318. FREE_AND_NULL(cached_getaddrinfo_item_t, \
  319. cached_getaddrinfo_item_free_, (item))
  320. static void
  321. cached_getaddrinfo_item_free_(cached_getaddrinfo_item_t *item)
  322. {
  323. if (item == NULL)
  324. return;
  325. tor_free(item->name);
  326. if (item->res)
  327. freeaddrinfo(item->res);
  328. tor_free(item);
  329. }
  330. static HT_HEAD(getaddrinfo_cache, cached_getaddrinfo_item_t)
  331. getaddrinfo_cache = HT_INITIALIZER();
  332. HT_PROTOTYPE(getaddrinfo_cache, cached_getaddrinfo_item_t, node,
  333. cached_getaddrinfo_item_hash,
  334. cached_getaddrinfo_items_eq)
  335. HT_GENERATE2(getaddrinfo_cache, cached_getaddrinfo_item_t, node,
  336. cached_getaddrinfo_item_hash,
  337. cached_getaddrinfo_items_eq,
  338. 0.6, tor_reallocarray_, tor_free_)
  339. /** If true, don't try to cache getaddrinfo results. */
  340. static int sandbox_getaddrinfo_cache_disabled = 0;
  341. /** Tell the sandbox layer not to try to cache getaddrinfo results. Used as in
  342. * tor-resolve, when we have no intention of initializing crypto or of
  343. * installing the sandbox.*/
  344. void
  345. sandbox_disable_getaddrinfo_cache(void)
  346. {
  347. sandbox_getaddrinfo_cache_disabled = 1;
  348. }
  349. void
  350. tor_freeaddrinfo(struct addrinfo *ai)
  351. {
  352. if (sandbox_getaddrinfo_cache_disabled)
  353. freeaddrinfo(ai);
  354. }
  355. int
  356. tor_getaddrinfo(const char *name, const char *servname,
  357. const struct addrinfo *hints,
  358. struct addrinfo **res)
  359. {
  360. int err;
  361. struct cached_getaddrinfo_item_t search, *item;
  362. if (sandbox_getaddrinfo_cache_disabled) {
  363. return getaddrinfo(name, NULL, hints, res);
  364. }
  365. if (servname != NULL) {
  366. log_warn(LD_BUG, "called with non-NULL servname");
  367. return EAI_NONAME;
  368. }
  369. if (name == NULL) {
  370. log_warn(LD_BUG, "called with NULL name");
  371. return EAI_NONAME;
  372. }
  373. *res = NULL;
  374. memset(&search, 0, sizeof(search));
  375. search.name = (char *) name;
  376. search.family = hints ? hints->ai_family : AF_UNSPEC;
  377. item = HT_FIND(getaddrinfo_cache, &getaddrinfo_cache, &search);
  378. if (! sandbox_getaddrinfo_is_active) {
  379. /* If the sandbox is not turned on yet, then getaddrinfo and store the
  380. result. */
  381. err = getaddrinfo(name, NULL, hints, res);
  382. log_info(LD_NET,"(Sandbox) getaddrinfo %s.", err ? "failed" : "succeeded");
  383. if (! item) {
  384. item = tor_malloc_zero(sizeof(*item));
  385. item->name = tor_strdup(name);
  386. item->family = hints ? hints->ai_family : AF_UNSPEC;
  387. HT_INSERT(getaddrinfo_cache, &getaddrinfo_cache, item);
  388. }
  389. if (item->res) {
  390. freeaddrinfo(item->res);
  391. item->res = NULL;
  392. }
  393. item->res = *res;
  394. item->err = err;
  395. return err;
  396. }
  397. /* Otherwise, the sandbox is on. If we have an item, yield its cached
  398. result. */
  399. if (item) {
  400. *res = item->res;
  401. return item->err;
  402. }
  403. /* getting here means something went wrong */
  404. log_err(LD_BUG,"(Sandbox) failed to get address %s!", name);
  405. return EAI_NONAME;
  406. }
  407. int
  408. tor_add_addrinfo(const char *name)
  409. {
  410. struct addrinfo *res;
  411. struct addrinfo hints;
  412. int i;
  413. static const int families[] = { AF_INET, AF_INET6, AF_UNSPEC };
  414. memset(&hints, 0, sizeof(hints));
  415. hints.ai_socktype = SOCK_STREAM;
  416. for (i = 0; i < 3; ++i) {
  417. hints.ai_family = families[i];
  418. res = NULL;
  419. (void) tor_getaddrinfo(name, NULL, &hints, &res);
  420. if (res)
  421. tor_freeaddrinfo(res);
  422. }
  423. return 0;
  424. }
  425. void
  426. tor_free_getaddrinfo_cache(void)
  427. {
  428. cached_getaddrinfo_item_t **next, **item, *this;
  429. for (item = HT_START(getaddrinfo_cache, &getaddrinfo_cache);
  430. item;
  431. item = next) {
  432. this = *item;
  433. next = HT_NEXT_RMV(getaddrinfo_cache, &getaddrinfo_cache, item);
  434. cached_getaddrinfo_item_free(this);
  435. }
  436. HT_CLEAR(getaddrinfo_cache, &getaddrinfo_cache);
  437. }
  438. void
  439. tor_make_getaddrinfo_cache_active(void)
  440. {
  441. sandbox_getaddrinfo_is_active = 1;
  442. }
  443. #else /* !defined(USE_SANDBOX_GETADDRINFO) */
  444. void
  445. sandbox_disable_getaddrinfo_cache(void)
  446. {
  447. }
  448. void
  449. tor_make_getaddrinfo_cache_active(void)
  450. {
  451. }
  452. #endif /* defined(USE_SANDBOX_GETADDRINFO) */