resolve.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. /* Copyright (c) 2003-2004, Roger Dingledine
  2. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  3. * Copyright (c) 2007-2018, 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 "siphash.h"
  16. #include "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 exists because standard windows gethostbyname
  32. * doesn't treat raw IP addresses properly.)
  33. */
  34. MOCK_IMPL(int,
  35. tor_lookup_hostname,(const char *name, uint32_t *addr))
  36. {
  37. tor_addr_t myaddr;
  38. int ret;
  39. if ((ret = tor_addr_lookup(name, AF_INET, &myaddr)))
  40. return ret;
  41. if (tor_addr_family(&myaddr) == AF_INET) {
  42. *addr = tor_addr_to_ipv4h(&myaddr);
  43. return ret;
  44. }
  45. return -1;
  46. }
  47. /** Similar behavior to Unix gethostbyname: resolve <b>name</b>, and set
  48. * *<b>addr</b> to the proper IP address and family. The <b>family</b>
  49. * argument (which must be AF_INET, AF_INET6, or AF_UNSPEC) declares a
  50. * <i>preferred</i> family, though another one may be returned if only one
  51. * family is implemented for this address.
  52. *
  53. * Return 0 on success, -1 on failure; 1 on transient failure.
  54. */
  55. MOCK_IMPL(int,
  56. tor_addr_lookup,(const char *name, uint16_t family, tor_addr_t *addr))
  57. {
  58. /* Perhaps eventually this should be replaced by a tor_getaddrinfo or
  59. * something.
  60. */
  61. struct in_addr iaddr;
  62. struct in6_addr iaddr6;
  63. tor_assert(name);
  64. tor_assert(addr);
  65. tor_assert(family == AF_INET || family == AF_INET6 || family == AF_UNSPEC);
  66. if (!*name) {
  67. /* Empty address is an error. */
  68. return -1;
  69. } else if (tor_inet_pton(AF_INET, name, &iaddr)) {
  70. /* It's an IPv4 IP. */
  71. if (family == AF_INET6)
  72. return -1;
  73. tor_addr_from_in(addr, &iaddr);
  74. return 0;
  75. } else if (tor_inet_pton(AF_INET6, name, &iaddr6)) {
  76. if (family == AF_INET)
  77. return -1;
  78. tor_addr_from_in6(addr, &iaddr6);
  79. return 0;
  80. } else {
  81. #ifdef HAVE_GETADDRINFO
  82. int err;
  83. struct addrinfo *res=NULL, *res_p;
  84. struct addrinfo *best=NULL;
  85. struct addrinfo hints;
  86. int result = -1;
  87. memset(&hints, 0, sizeof(hints));
  88. hints.ai_family = family;
  89. hints.ai_socktype = SOCK_STREAM;
  90. err = tor_getaddrinfo(name, NULL, &hints, &res);
  91. /* The check for 'res' here shouldn't be necessary, but it makes static
  92. * analysis tools happy. */
  93. if (!err && res) {
  94. best = NULL;
  95. for (res_p = res; res_p; res_p = res_p->ai_next) {
  96. if (family == AF_UNSPEC) {
  97. if (res_p->ai_family == AF_INET) {
  98. best = res_p;
  99. break;
  100. } else if (res_p->ai_family == AF_INET6 && !best) {
  101. best = res_p;
  102. }
  103. } else if (family == res_p->ai_family) {
  104. best = res_p;
  105. break;
  106. }
  107. }
  108. if (!best)
  109. best = res;
  110. if (best->ai_family == AF_INET) {
  111. tor_addr_from_in(addr,
  112. &((struct sockaddr_in*)best->ai_addr)->sin_addr);
  113. result = 0;
  114. } else if (best->ai_family == AF_INET6) {
  115. tor_addr_from_in6(addr,
  116. &((struct sockaddr_in6*)best->ai_addr)->sin6_addr);
  117. result = 0;
  118. }
  119. tor_freeaddrinfo(res);
  120. return result;
  121. }
  122. return (err == EAI_AGAIN) ? 1 : -1;
  123. #else /* !(defined(HAVE_GETADDRINFO)) */
  124. struct hostent *ent;
  125. int err;
  126. #ifdef HAVE_GETHOSTBYNAME_R_6_ARG
  127. char buf[2048];
  128. struct hostent hostent;
  129. int r;
  130. r = gethostbyname_r(name, &hostent, buf, sizeof(buf), &ent, &err);
  131. #elif defined(HAVE_GETHOSTBYNAME_R_5_ARG)
  132. char buf[2048];
  133. struct hostent hostent;
  134. ent = gethostbyname_r(name, &hostent, buf, sizeof(buf), &err);
  135. #elif defined(HAVE_GETHOSTBYNAME_R_3_ARG)
  136. struct hostent_data data;
  137. struct hostent hent;
  138. memset(&data, 0, sizeof(data));
  139. err = gethostbyname_r(name, &hent, &data);
  140. ent = err ? NULL : &hent;
  141. #else
  142. ent = gethostbyname(name);
  143. #ifdef _WIN32
  144. err = WSAGetLastError();
  145. #else
  146. err = h_errno;
  147. #endif
  148. #endif /* defined(HAVE_GETHOSTBYNAME_R_6_ARG) || ... */
  149. if (ent) {
  150. if (ent->h_addrtype == AF_INET) {
  151. tor_addr_from_in(addr, (struct in_addr*) ent->h_addr);
  152. } else if (ent->h_addrtype == AF_INET6) {
  153. tor_addr_from_in6(addr, (struct in6_addr*) ent->h_addr);
  154. } else {
  155. tor_assert(0); // LCOV_EXCL_LINE: gethostbyname() returned bizarre type
  156. }
  157. return 0;
  158. }
  159. #ifdef _WIN32
  160. return (err == WSATRY_AGAIN) ? 1 : -1;
  161. #else
  162. return (err == TRY_AGAIN) ? 1 : -1;
  163. #endif
  164. #endif /* defined(HAVE_GETADDRINFO) */
  165. }
  166. }
  167. /** Parse an address or address-port combination from <b>s</b>, resolve the
  168. * address as needed, and put the result in <b>addr_out</b> and (optionally)
  169. * <b>port_out</b>. Return 0 on success, negative on failure. */
  170. int
  171. tor_addr_port_lookup(const char *s, tor_addr_t *addr_out, uint16_t *port_out)
  172. {
  173. const char *port;
  174. tor_addr_t addr;
  175. uint16_t portval;
  176. char *tmp = NULL;
  177. tor_assert(s);
  178. tor_assert(addr_out);
  179. s = eat_whitespace(s);
  180. if (*s == '[') {
  181. port = strstr(s, "]");
  182. if (!port)
  183. goto err;
  184. tmp = tor_strndup(s+1, port-(s+1));
  185. port = port+1;
  186. if (*port == ':')
  187. port++;
  188. else
  189. port = NULL;
  190. } else {
  191. port = strchr(s, ':');
  192. if (port)
  193. tmp = tor_strndup(s, port-s);
  194. else
  195. tmp = tor_strdup(s);
  196. if (port)
  197. ++port;
  198. }
  199. if (tor_addr_lookup(tmp, AF_UNSPEC, &addr) != 0)
  200. goto err;
  201. tor_free(tmp);
  202. if (port) {
  203. portval = (int) tor_parse_long(port, 10, 1, 65535, NULL, NULL);
  204. if (!portval)
  205. goto err;
  206. } else {
  207. portval = 0;
  208. }
  209. if (port_out)
  210. *port_out = portval;
  211. tor_addr_copy(addr_out, &addr);
  212. return 0;
  213. err:
  214. tor_free(tmp);
  215. return -1;
  216. }
  217. #ifdef USE_SANDBOX_GETADDRINFO
  218. /** True if we should only return cached values */
  219. static int sandbox_getaddrinfo_is_active = 0;
  220. /** Cache entry for getaddrinfo results; used when sandboxing is implemented
  221. * so that we can consult the cache when the sandbox prevents us from doing
  222. * getaddrinfo.
  223. *
  224. * We support only a limited range of getaddrinfo calls, where servname is null
  225. * and hints contains only socktype=SOCK_STREAM, family in INET,INET6,UNSPEC.
  226. */
  227. typedef struct cached_getaddrinfo_item_t {
  228. HT_ENTRY(cached_getaddrinfo_item_t) node;
  229. char *name;
  230. int family;
  231. /** set if no error; otherwise NULL */
  232. struct addrinfo *res;
  233. /** 0 for no error; otherwise an EAI_* value */
  234. int err;
  235. } cached_getaddrinfo_item_t;
  236. static unsigned
  237. cached_getaddrinfo_item_hash(const cached_getaddrinfo_item_t *item)
  238. {
  239. return (unsigned)siphash24g(item->name, strlen(item->name)) + item->family;
  240. }
  241. static unsigned
  242. cached_getaddrinfo_items_eq(const cached_getaddrinfo_item_t *a,
  243. const cached_getaddrinfo_item_t *b)
  244. {
  245. return (a->family == b->family) && 0 == strcmp(a->name, b->name);
  246. }
  247. #define cached_getaddrinfo_item_free(item) \
  248. FREE_AND_NULL(cached_getaddrinfo_item_t, \
  249. cached_getaddrinfo_item_free_, (item))
  250. static void
  251. cached_getaddrinfo_item_free_(cached_getaddrinfo_item_t *item)
  252. {
  253. if (item == NULL)
  254. return;
  255. tor_free(item->name);
  256. if (item->res)
  257. freeaddrinfo(item->res);
  258. tor_free(item);
  259. }
  260. static HT_HEAD(getaddrinfo_cache, cached_getaddrinfo_item_t)
  261. getaddrinfo_cache = HT_INITIALIZER();
  262. HT_PROTOTYPE(getaddrinfo_cache, cached_getaddrinfo_item_t, node,
  263. cached_getaddrinfo_item_hash,
  264. cached_getaddrinfo_items_eq)
  265. HT_GENERATE2(getaddrinfo_cache, cached_getaddrinfo_item_t, node,
  266. cached_getaddrinfo_item_hash,
  267. cached_getaddrinfo_items_eq,
  268. 0.6, tor_reallocarray_, tor_free_)
  269. /** If true, don't try to cache getaddrinfo results. */
  270. static int sandbox_getaddrinfo_cache_disabled = 0;
  271. /** Tell the sandbox layer not to try to cache getaddrinfo results. Used as in
  272. * tor-resolve, when we have no intention of initializing crypto or of
  273. * installing the sandbox.*/
  274. void
  275. sandbox_disable_getaddrinfo_cache(void)
  276. {
  277. sandbox_getaddrinfo_cache_disabled = 1;
  278. }
  279. void
  280. tor_freeaddrinfo(struct addrinfo *ai)
  281. {
  282. if (sandbox_getaddrinfo_cache_disabled)
  283. freeaddrinfo(ai);
  284. }
  285. int
  286. tor_getaddrinfo(const char *name, const char *servname,
  287. const struct addrinfo *hints,
  288. struct addrinfo **res)
  289. {
  290. int err;
  291. struct cached_getaddrinfo_item_t search, *item;
  292. if (sandbox_getaddrinfo_cache_disabled) {
  293. return getaddrinfo(name, NULL, hints, res);
  294. }
  295. if (servname != NULL) {
  296. log_warn(LD_BUG, "called with non-NULL servname");
  297. return EAI_NONAME;
  298. }
  299. if (name == NULL) {
  300. log_warn(LD_BUG, "called with NULL name");
  301. return EAI_NONAME;
  302. }
  303. *res = NULL;
  304. memset(&search, 0, sizeof(search));
  305. search.name = (char *) name;
  306. search.family = hints ? hints->ai_family : AF_UNSPEC;
  307. item = HT_FIND(getaddrinfo_cache, &getaddrinfo_cache, &search);
  308. if (! sandbox_getaddrinfo_is_active) {
  309. /* If the sandbox is not turned on yet, then getaddrinfo and store the
  310. result. */
  311. err = getaddrinfo(name, NULL, hints, res);
  312. log_info(LD_NET,"(Sandbox) getaddrinfo %s.", err ? "failed" : "succeeded");
  313. if (! item) {
  314. item = tor_malloc_zero(sizeof(*item));
  315. item->name = tor_strdup(name);
  316. item->family = hints ? hints->ai_family : AF_UNSPEC;
  317. HT_INSERT(getaddrinfo_cache, &getaddrinfo_cache, item);
  318. }
  319. if (item->res) {
  320. freeaddrinfo(item->res);
  321. item->res = NULL;
  322. }
  323. item->res = *res;
  324. item->err = err;
  325. return err;
  326. }
  327. /* Otherwise, the sandbox is on. If we have an item, yield its cached
  328. result. */
  329. if (item) {
  330. *res = item->res;
  331. return item->err;
  332. }
  333. /* getting here means something went wrong */
  334. log_err(LD_BUG,"(Sandbox) failed to get address %s!", name);
  335. return EAI_NONAME;
  336. }
  337. int
  338. tor_add_addrinfo(const char *name)
  339. {
  340. struct addrinfo *res;
  341. struct addrinfo hints;
  342. int i;
  343. static const int families[] = { AF_INET, AF_INET6, AF_UNSPEC };
  344. memset(&hints, 0, sizeof(hints));
  345. hints.ai_socktype = SOCK_STREAM;
  346. for (i = 0; i < 3; ++i) {
  347. hints.ai_family = families[i];
  348. res = NULL;
  349. (void) tor_getaddrinfo(name, NULL, &hints, &res);
  350. if (res)
  351. tor_freeaddrinfo(res);
  352. }
  353. return 0;
  354. }
  355. void
  356. tor_free_getaddrinfo_cache(void)
  357. {
  358. cached_getaddrinfo_item_t **next, **item, *this;
  359. for (item = HT_START(getaddrinfo_cache, &getaddrinfo_cache);
  360. item;
  361. item = next) {
  362. this = *item;
  363. next = HT_NEXT_RMV(getaddrinfo_cache, &getaddrinfo_cache, item);
  364. cached_getaddrinfo_item_free(this);
  365. }
  366. HT_CLEAR(getaddrinfo_cache, &getaddrinfo_cache);
  367. }
  368. void
  369. tor_make_getaddrinfo_cache_active(void)
  370. {
  371. sandbox_getaddrinfo_is_active = 1;
  372. }
  373. #endif