コード例 #1
0
ファイル: dns.c プロジェクト: vstakhov/curvedns
int dns_forward_query_tcp(event_entry_t *general_entry) {
	struct event_tcp_entry *entry = &general_entry->tcp;

	if (!ip_tcp_open(&entry->intsock, &global_target_address)) {
		debug_log(DEBUG_ERROR, "dns_forward_query_tcp(): unable to open TCP socket\n");
		goto wrong;
	}
	
	// randomizing port is not really necessary, as TCP is invulnerable to cache poisoning
	// however, the source IP address is set in ip_bind_random...
	if (!ip_bind_random(entry->intsock)) {
		// if this fails, let the kernel handle it (would mean source IP address is not guaranteed...)
		debug_log(DEBUG_WARN, "dns_forward_query_tcp(): unable to bind to source IP address and/or random port\n");
	}

	if (!ip_connect(entry->intsock, &global_target_address)) {
		debug_log(DEBUG_ERROR, "dns_forward_query_tcp(): unable to connect to authoritative name server (%s)\n", strerror(errno));
		goto wrong;
	}

	// Now generate a new TXID to forecome any poisoning:
	entry->buffer[0] = misc_crypto_random(256);
	entry->buffer[1] = misc_crypto_random(256);
	// XXX: do this platform safe (i.e. ntoh)
	entry->dns.dsttxid = (entry->buffer[0] << 8) + entry->buffer[1];

	debug_log(DEBUG_INFO, "dns_forward_query_tcp(): forwarding query to authoritative name server (prev id = %d, new id = %d)\n",
			entry->dns.srctxid, entry->dns.dsttxid);

	return 1;

wrong:
	return 0;
}
コード例 #2
0
ファイル: dns.c プロジェクト: charlieyqin/curvedns
int dns_forward_query_udp(event_entry_t *general_entry) {
	int sock, n;
	struct event_udp_entry *entry = &general_entry->udp;

	if (!ip_udp_open(&sock, &global_target_address)) {
		debug_log(DEBUG_ERROR, "dns_forward_query_udp(): unable to open a UDP socket to forward query to authoritative server\n");
		goto wrong;
	}

	// randomize the outgoing source port and set the source IP address, if needed
	if (!ip_bind_random(sock)) {
		// if this fails, let the kernel handle it (would mean source IP address is not guaranteed...)
		debug_log(DEBUG_WARN, "dns_forward_query_udp(): unable to bind to source IP address and/or random port\n");
	}

	entry->state = EVENT_UDP_INT_WRITING;
	entry->read_int_watcher.data = general_entry;
	entry->timeout_int_watcher.data = general_entry;
	entry->retries++;

	// Now generate a new TXID to forecome any poisoning:
	entry->buffer[0] = misc_crypto_random(256);
	entry->buffer[1] = misc_crypto_random(256);
	// XXX: do this platform safe (i.e. ntoh)
	entry->dns.dsttxid = (entry->buffer[0] << 8) + entry->buffer[1];

	ev_io_init(&entry->read_int_watcher, event_udp_int_cb, sock, EV_READ);
	ev_timer_init(&entry->timeout_int_watcher, event_udp_timeout_cb, 0., global_ip_internal_timeout);

	ev_io_start(event_default_loop, &entry->read_int_watcher);
	ev_timer_again(event_default_loop, &entry->timeout_int_watcher);

	debug_log(DEBUG_INFO, "dns_forward_query_udp(): forwarding query to authoritative name server (prev id = %d, new id = %d)\n",
			(entry->dns.type == DNS_DNSCURVE_STREAMLINED || entry->dns.type == DNS_NON_DNSCURVE) ? entry->dns.srctxid : entry->dns.srcinsidetxid,
			entry->dns.dsttxid);

	n = sendto(sock, entry->buffer, entry->packetsize, MSG_DONTWAIT,
			(struct sockaddr *) &global_target_address.sa, global_target_address_len);
	if (n == -1) {
		debug_log(DEBUG_ERROR, "dns_forward_query_udp(): unable to forward the query to authoritative name server (%s)\n", strerror(errno));
		goto wrong;
	}

	return 1;

wrong:
	return 0;
}
コード例 #3
0
ファイル: ip.c プロジェクト: vstakhov/curvedns
// Watch it, only to be used for sending queries to authoritative name server!
int ip_bind_random(int sock) {
	unsigned int i;
	anysin_t addr;
	socklen_t addrlen = sizeof(addr);

	memset(&addr, 0, sizeof(addr));

	// See to what kind of socket we have to bind:
	if (global_target_address.sa.sa_family == AF_INET6) {
		addr.sa.sa_family = AF_INET6;
		for (i = 0; i < 10; i++) {
			if (global_source_address.sa.sa_family != AF_UNSPEC) {
				memcpy(&(addr.sin6.sin6_addr),
					&(global_source_address.sin6.sin6_addr),
					sizeof(addr.sin6.sin6_addr));
			}
			addr.sin6.sin6_port = 1025 + misc_crypto_random(64510);
			if (bind(sock, (struct sockaddr *) &addr, addrlen) == 0)
				return 1;
		}
	} else {
		addr.sa.sa_family = AF_INET;
		for (i = 0; i < 10; i++) {
			if (global_source_address.sa.sa_family != AF_UNSPEC) {
				memcpy(&(addr.sin.sin_addr),
					&(global_source_address.sin.sin_addr),
					sizeof(addr.sin.sin_addr));
			}
			addr.sin.sin_port = 1025 + misc_crypto_random(64510);
			if (bind(sock, (struct sockaddr *) &addr, addrlen) == 0)
				return 1;
		}
	}

	return 0;
}