/* * Torsocks call for getaddrinfo(3). */ LIBC_GETADDRINFO_RET_TYPE tsocks_getaddrinfo(LIBC_GETADDRINFO_SIG) { int ret, af; struct in_addr addr4; struct in6_addr addr6; void *addr; char *ip_str, ipv4[INET_ADDRSTRLEN], ipv6[INET6_ADDRSTRLEN]; socklen_t ip_str_size; const char *node; DBG("[getaddrinfo] Requesting %s hostname", __node); if (!__node) { ret = EAI_NONAME; goto error; } /* Use right domain for the next step. */ switch (__hints->ai_family) { default: /* Default value is to use IPv4. */ case AF_INET: addr = &addr4; ip_str = ipv4; ip_str_size = sizeof(ipv4); af = AF_INET; break; case AF_INET6: addr = &addr6; ip_str = ipv6; ip_str_size = sizeof(ipv6); af = AF_INET6; break; } ret = inet_pton(af, __node, &addr); if (ret == 0) { /* The node most probably is a DNS name. */ ret = tsocks_tor_resolve(__node, (uint32_t *) addr); if (ret < 0) { ret = EAI_FAIL; goto error; } (void) inet_ntop(af, addr, ip_str, ip_str_size); node = ip_str; DBG("[getaddrinfo] Node %s resolved to %s", __node, node); } else { node = __node; DBG("[getaddrinfo] Node %s will be passed to the libc call", node); } ret = tsocks_libc_getaddrinfo(node, __service, __hints, __res); if (ret) { goto error; } return 0; error: return ret; }
/* * Torsocks call for getaddrinfo(3). */ LIBC_GETADDRINFO_RET_TYPE tsocks_getaddrinfo(LIBC_GETADDRINFO_SIG) { int ret, af; struct in_addr addr4; struct in6_addr addr6; void *addr; char *ip_str, ipv4[INET_ADDRSTRLEN], ipv6[INET6_ADDRSTRLEN]; socklen_t ip_str_size; const char *tmp_node; DBG("[getaddrinfo] Requesting %s hostname", node); if (!node) { /* * As stated in the man page, if node is NULL, the libc call will * return a valid socket address but NO external DNS resolution is * possible since there is no host name to resolve. */ tmp_node = node; goto libc_call; } /* * Quoting the getaddrinfo(3) man page: * * All the other fields in the structure pointed to by hints must * contain either 0 or a NULL pointer, as appropriate. Specifying hints * as NULL is equivalent to setting ai_socktype and ai_protocol to * 0; ai_family to AF_UNSPEC; and ai_flags to (AI_V4MAPPED | * AI_ADDRCONFIG). * * This means that for sure the ai_family will be treated as AF_UNSPEC. */ if (!hints) { tmp_node = node; goto libc_call; } /* Use right domain for the next step. */ switch (hints->ai_family) { default: /* Default value is to use IPv4. */ case AF_INET: addr = &addr4; ip_str = ipv4; ip_str_size = sizeof(ipv4); af = AF_INET; break; case AF_INET6: addr = &addr6; ip_str = ipv6; ip_str_size = sizeof(ipv6); af = AF_INET6; break; } ret = inet_pton(af, node, addr); if (ret == 0) { /* If AI_NUMERICHOST is set, return a error. */ if (hints->ai_flags & AI_NUMERICHOST) { ret = EAI_NONAME; goto error; } /* The node most probably is a DNS name. */ ret = tsocks_tor_resolve(af, node, addr); if (ret < 0) { ret = EAI_FAIL; goto error; } (void) inet_ntop(af, addr, ip_str, ip_str_size); tmp_node = ip_str; DBG("[getaddrinfo] Node %s resolved to %s", node,tmp_node); } else { tmp_node = node; DBG("[getaddrinfo] Node %s will be passed to the libc call", tmp_node); } libc_call: ret = tsocks_libc_getaddrinfo(tmp_node, service, hints, res); if (ret) { goto error; } return 0; error: return ret; }