Example #1
0
/*
 * Resolve a hostname through Tor and set the ip address in the given pointer.
 *
 * Return 0 on success else a negative value and the result addr is untouched.
 */
int tsocks_tor_resolve(const char *hostname, uint32_t *ip_addr)
{
	int ret;
	struct connection conn;

	assert(hostname);
	assert(ip_addr);

	ret = hosts_file_resolve(hostname, ip_addr);
	if (!ret) {
		goto end;
	}

	DBG("Resolving %s on the Tor network", hostname);

	/*
	 * Tor hidden service address have no IP address so we send back an onion
	 * reserved IP address that acts as a cookie that we will use to find the
	 * onion hostname at the connect() stage.
	 */
	if (utils_strcasecmpend(hostname, ".onion") == 0) {
		struct onion_entry *entry;

		entry = get_onion_entry(hostname, &tsocks_onion_pool);
		if (entry) {
			memcpy(ip_addr, &entry->ip, sizeof(entry->ip));
			ret = 0;
			goto end;
		}
	}

	conn.fd = tsocks_libc_socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (conn.fd < 0) {
		PERROR("socket");
		ret = -errno;
		goto error;
	}

	ret = setup_tor_connection(&conn);
	if (ret < 0) {
		goto error;
	}

	ret = socks5_send_resolve_request(hostname, &conn);
	if (ret < 0) {
		goto error;
	}

	/* Force IPv4 resolution for now. */
	ret = socks5_recv_resolve_reply(&conn, ip_addr, sizeof(uint32_t));
	if (ret < 0) {
		goto error;
	}

	ret = close(conn.fd);
	if (ret < 0) {
		PERROR("close");
	}

end:
error:
	return ret;
}
Example #2
0
/*
 * Resolve a hostname through Tor and set the ip address in the given pointer.
 *
 * Return 0 on success else a negative value and the result addr is untouched.
 */
int tsocks_tor_resolve(int af, const char *hostname, void *ip_addr)
{
	int ret;
	size_t addr_len;
	struct connection conn;

	assert(hostname);
	assert(ip_addr);

	if (af == AF_INET) {
		addr_len = sizeof(uint32_t);
		conn.dest_addr.domain = CONNECTION_DOMAIN_INET;
	} else if (af == AF_INET6) {
		addr_len = 16;
		conn.dest_addr.domain = CONNECTION_DOMAIN_INET6;
		/* Tor daemon does not support IPv6 DNS resolution yet. */
		ret = -ENOSYS;
		goto error;
	} else {
		ret = -EINVAL;
		goto error;
	}

	ret = utils_localhost_resolve(hostname, af, ip_addr, addr_len);
	if (ret) {
		/* Found to be a localhost name. */
		ret = 0;
		goto end;
	}

	DBG("Resolving %s on the Tor network", hostname);

	/*
	 * Tor hidden service address have no IP address so we send back an onion
	 * reserved IP address that acts as a cookie that we will use to find the
	 * onion hostname at the connect() stage.
	 */
	if (utils_strcasecmpend(hostname, ".onion") == 0) {
		struct onion_entry *entry;

		entry = get_onion_entry(hostname, &tsocks_onion_pool);
		if (entry) {
			memcpy(ip_addr, &entry->ip, sizeof(entry->ip));
			ret = 0;
			goto end;
		}
	}

	conn.fd = tsocks_libc_socket(af, SOCK_STREAM, IPPROTO_TCP);
	if (conn.fd < 0) {
		PERROR("socket");
		ret = -errno;
		goto error;
	}

	ret = setup_tor_connection(&conn, SOCKS5_NO_AUTH_METHOD);
	if (ret < 0) {
		goto end_close;
	}

	ret = socks5_send_resolve_request(hostname, &conn);
	if (ret < 0) {
		goto end_close;
	}

	/* Force IPv4 resolution for now. */
	ret = socks5_recv_resolve_reply(&conn, ip_addr, addr_len);
	if (ret < 0) {
		goto end_close;
	}

end_close:
	if (tsocks_libc_close(conn.fd) < 0) {
		PERROR("close");
	}
end:
error:
	return ret;
}