11 #define RESOLVE_PRIVATE
20 #include "ext/siphash.h"
23 #ifdef HAVE_SYS_TYPES_H
24 #include <sys/types.h>
26 #ifdef HAVE_SYS_SOCKET_H
27 #include <sys/socket.h>
67 #ifdef HAVE_GETADDRINFO
75 tor_addr_lookup_host_impl,(
const char *
name,
80 struct addrinfo *res=NULL, *res_p;
81 struct addrinfo *best=NULL;
82 struct addrinfo hints;
84 memset(&hints, 0,
sizeof(hints));
85 hints.ai_family = family;
86 hints.ai_socktype = SOCK_STREAM;
87 err = tor_getaddrinfo(
name, NULL, &hints, &res);
92 for (res_p = res; res_p; res_p = res_p->ai_next) {
93 if (family == AF_UNSPEC) {
94 if (res_p->ai_family == AF_INET) {
97 }
else if (res_p->ai_family == AF_INET6 && !best) {
100 }
else if (family == res_p->ai_family) {
107 if (best->ai_family == AF_INET) {
109 &((
struct sockaddr_in*)best->ai_addr)->sin_addr);
111 }
else if (best->ai_family == AF_INET6) {
116 tor_freeaddrinfo(res);
119 return (err == EAI_AGAIN) ? 1 : -1;
130 tor_addr_lookup_host_impl,(
const char *
name,
137 #ifdef HAVE_GETHOSTBYNAME_R_6_ARG
139 struct hostent hostent;
141 r = gethostbyname_r(
name, &hostent, buf,
sizeof(buf), &ent, &err);
142 #elif defined(HAVE_GETHOSTBYNAME_R_5_ARG)
144 struct hostent hostent;
145 ent = gethostbyname_r(
name, &hostent, buf,
sizeof(buf), &err);
146 #elif defined(HAVE_GETHOSTBYNAME_R_3_ARG)
147 struct hostent_data data;
149 memset(&data, 0,
sizeof(data));
150 err = gethostbyname_r(
name, &hent, &data);
151 ent = err ? NULL : &hent;
153 ent = gethostbyname(
name);
155 err = WSAGetLastError();
161 if (ent->h_addrtype == AF_INET) {
163 }
else if (ent->h_addrtype == AF_INET6) {
171 return (err == WSATRY_AGAIN) ? 1 : -1;
173 return (err == TRY_AGAIN) ? 1 : -1;
195 int parsed_family = 0;
200 tor_assert(family == AF_INET || family == AF_INET6 || family == AF_UNSPEC);
210 if (parsed_family >= 0) {
212 if (parsed_family == family || family == AF_UNSPEC) {
220 result = tor_addr_lookup_host_impl(
name, family, addr);
255 uint16_t portval = 0;
283 tor_assertf_nonfatal(family == AF_INET6,
284 "Wrong family: %d (should be IPv6: %d) which "
285 "failed IP:port parsing, but passed IP parsing. "
286 "input string: '%s'; parsed address: '%s'.",
287 family, AF_INET6, s,
fmt_addr(&addr));
320 #ifdef USE_SANDBOX_GETADDRINFO
322 static int sandbox_getaddrinfo_is_active = 0;
331 typedef struct cached_getaddrinfo_item_t {
332 HT_ENTRY(cached_getaddrinfo_item_t) node;
336 struct addrinfo *res;
339 } cached_getaddrinfo_item_t;
342 cached_getaddrinfo_item_hash(
const cached_getaddrinfo_item_t *item)
344 return (
unsigned)siphash24g(item->name, strlen(item->name)) + item->family;
348 cached_getaddrinfo_items_eq(
const cached_getaddrinfo_item_t *a,
349 const cached_getaddrinfo_item_t *b)
351 return (a->family == b->family) && 0 == strcmp(a->name, b->name);
354 #define cached_getaddrinfo_item_free(item) \
355 FREE_AND_NULL(cached_getaddrinfo_item_t, \
356 cached_getaddrinfo_item_free_, (item))
359 cached_getaddrinfo_item_free_(cached_getaddrinfo_item_t *item)
366 freeaddrinfo(item->res);
370 static HT_HEAD(getaddrinfo_cache, cached_getaddrinfo_item_t)
371 getaddrinfo_cache = HT_INITIALIZER();
373 HT_PROTOTYPE(getaddrinfo_cache, cached_getaddrinfo_item_t, node,
374 cached_getaddrinfo_item_hash,
375 cached_getaddrinfo_items_eq);
376 HT_GENERATE2(getaddrinfo_cache, cached_getaddrinfo_item_t, node,
377 cached_getaddrinfo_item_hash,
378 cached_getaddrinfo_items_eq,
382 static int sandbox_getaddrinfo_cache_disabled = 0;
388 sandbox_disable_getaddrinfo_cache(
void)
390 sandbox_getaddrinfo_cache_disabled = 1;
394 tor_freeaddrinfo(
struct addrinfo *ai)
396 if (sandbox_getaddrinfo_cache_disabled)
401 tor_getaddrinfo(
const char *
name,
const char *servname,
402 const struct addrinfo *hints,
403 struct addrinfo **res)
406 struct cached_getaddrinfo_item_t search, *item;
408 if (sandbox_getaddrinfo_cache_disabled) {
409 return getaddrinfo(
name, NULL, hints, res);
412 if (servname != NULL) {
413 log_warn(
LD_BUG,
"called with non-NULL servname");
417 log_warn(
LD_BUG,
"called with NULL name");
423 memset(&search, 0,
sizeof(search));
424 search.name = (
char *)
name;
425 search.family = hints ? hints->ai_family : AF_UNSPEC;
426 item = HT_FIND(getaddrinfo_cache, &getaddrinfo_cache, &search);
428 if (! sandbox_getaddrinfo_is_active) {
432 err = getaddrinfo(
name, NULL, hints, res);
433 log_info(
LD_NET,
"(Sandbox) getaddrinfo %s.", err ?
"failed" :
"succeeded");
436 item = tor_malloc_zero(
sizeof(*item));
437 item->name = tor_strdup(
name);
438 item->family = hints ? hints->ai_family : AF_UNSPEC;
439 HT_INSERT(getaddrinfo_cache, &getaddrinfo_cache, item);
443 freeaddrinfo(item->res);
459 log_err(
LD_BUG,
"(Sandbox) failed to get address %s!",
name);
464 tor_add_addrinfo(
const char *
name)
466 struct addrinfo *res;
467 struct addrinfo hints;
469 static const int families[] = { AF_INET, AF_INET6, AF_UNSPEC };
471 memset(&hints, 0,
sizeof(hints));
472 hints.ai_socktype = SOCK_STREAM;
473 for (i = 0; i < 3; ++i) {
474 hints.ai_family = families[i];
477 (void) tor_getaddrinfo(
name, NULL, &hints, &res);
479 tor_freeaddrinfo(res);
486 tor_free_getaddrinfo_cache(
void)
488 cached_getaddrinfo_item_t **next, **item, *
this;
490 for (item = HT_START(getaddrinfo_cache, &getaddrinfo_cache);
494 next = HT_NEXT_RMV(getaddrinfo_cache, &getaddrinfo_cache, item);
495 cached_getaddrinfo_item_free(
this);
498 HT_CLEAR(getaddrinfo_cache, &getaddrinfo_cache);
502 tor_make_getaddrinfo_cache_active(
void)
504 sandbox_getaddrinfo_is_active = 1;
508 sandbox_disable_getaddrinfo_cache(
void)
512 tor_make_getaddrinfo_cache_active(
void)
void tor_addr_copy(tor_addr_t *dest, const tor_addr_t *src)
int tor_addr_parse(tor_addr_t *addr, const char *src)
int tor_addr_port_parse(int severity, const char *addrport, tor_addr_t *address_out, uint16_t *port_out, int default_port)
int tor_addr_port_split(int severity, const char *addrport, char **address_out, uint16_t *port_out)
void tor_addr_from_in6(tor_addr_t *dest, const struct in6_addr *in6)
static sa_family_t tor_addr_family(const tor_addr_t *a)
static uint32_t tor_addr_to_ipv4h(const tor_addr_t *a)
#define tor_addr_from_in(dest, in)
HT_PROTOTYPE(hs_circuitmap_ht, circuit_t, hs_circuitmap_node, hs_circuit_hash_token, hs_circuits_have_same_token)
typedef HT_HEAD(hs_service_ht, hs_service_t) hs_service_ht
void tor_free_(void *mem)
void * tor_reallocarray_(void *ptr, size_t sz1, size_t sz2)
Headers for util_malloc.c.
int tor_lookup_hostname(const char *name, uint32_t *addr)
int tor_addr_lookup(const char *name, uint16_t family, tor_addr_t *addr)
int tor_addr_port_lookup(const char *s, tor_addr_t *addr_out, uint16_t *port_out)
#define MOCK_IMPL(rv, funcname, arglist)
const char * eat_whitespace(const char *s)
Header for util_string.c.