Esempio n. 1
0
/*
 * 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;
}
Esempio n. 2
0
/*
 * 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;
}