File curvedns-axfr.patch of Package curvedns

diff -rNU3 curvedns-0.87-orig/dns.c curvedns-0.87-axfr/dns.c
--- curvedns-0.87-orig/dns.c	2010-12-28 09:32:54.000000000 +0100
+++ curvedns-0.87-axfr/dns.c	2012-08-02 12:53:06.000000000 +0200
@@ -157,15 +157,6 @@
 		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:
diff -rNU3 curvedns-0.87-orig/event.h curvedns-0.87-axfr/event.h
--- curvedns-0.87-orig/event.h	2010-12-28 09:32:54.000000000 +0100
+++ curvedns-0.87-axfr/event.h	2012-08-02 12:45:34.000000000 +0200
@@ -122,7 +122,8 @@
 	int intsock;
 	int extsock;
 	ev_io write_watcher;
-	ev_io read_watcher;
+	ev_io read_int_watcher;
+	ev_io read_ext_watcher;
 	ev_timer timeout_watcher;
 	event_tcp_state_t state;
 };
diff -rNU3 curvedns-0.87-orig/event_tcp.c curvedns-0.87-axfr/event_tcp.c
--- curvedns-0.87-orig/event_tcp.c	2010-12-28 09:32:54.000000000 +0100
+++ curvedns-0.87-axfr/event_tcp.c	2012-08-02 12:54:11.000000000 +0200
@@ -43,8 +43,10 @@
 	if (entry) {
 		if (ev_is_active(&entry->timeout_watcher))
 			ev_timer_stop(loop, &entry->timeout_watcher);
-		if (ev_is_active(&entry->read_watcher))
-			ev_io_stop(loop, &entry->read_watcher);
+		if (ev_is_active(&entry->read_int_watcher))
+			ev_io_stop(loop, &entry->read_int_watcher);
+		if (ev_is_active(&entry->read_ext_watcher))
+			ev_io_stop(loop, &entry->read_ext_watcher);
 		if (ev_is_active(&entry->write_watcher))
 			ev_io_stop(loop, &entry->write_watcher);
 		if (entry->extsock >= 0) {
@@ -195,7 +197,7 @@
 		entry->bufferat = 0;
 		entry->packetsize = 0;
 
-		ev_io_start(loop, &entry->read_watcher);
+		ev_io_start(loop, &entry->read_int_watcher);
 		ev_timer_again(loop, &entry->timeout_watcher);
 	} else {
 		debug_log(DEBUG_INFO, "event_tcp_write_cb(): we have sent the entire packet towards the client, packetsize = %zu, listening again\n", entry->packetsize);
@@ -208,7 +210,8 @@
 		entry->bufferat = 0;
 		entry->packetsize = 0;
 
-		ev_io_start(loop, &entry->read_watcher);
+		ev_io_start(loop, &entry->read_int_watcher);
+		ev_io_start(loop, &entry->read_ext_watcher);
 		ev_timer_again(loop, &entry->timeout_watcher);
 	}
 
@@ -235,7 +238,32 @@
 	if (entry->bufferat >= entry->bufferlen)
 		goto wrong;
 
-	if (entry->state == EVENT_TCP_INT_READING_INIT)	{
+	debug_log(DEBUG_DEBUG, "event_tcp_read_cb(): starting with state %d @ %d bytes\n",
+		  entry->state, entry->bufferat);
+
+	if (entry->bufferat == 0 && entry->intsock >= 0
+		&& (entry->state == EVENT_TCP_INT_READING_INIT
+		    || entry->state == EVENT_TCP_EXT_READING_INIT)) {
+		initial = 1;
+		/*
+		packetlen = recv(entry->intsock, buffer, 1, MSG_PEEK | MSG_DONTWAIT);
+		if (packetlen == 1) {
+			internal = 1;
+		} else {
+			packetlen = recv(entry->extsock, buffer, 1, MSG_PEEK | MSG_DONTWAIT);
+			if (packetlen == 1) {
+				internal = 0;
+			} else {
+				if (packetlen < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) return;
+				debug_log(DEBUG_WARN, "event_tcp_read_cb(): failed to receive TCP data\n");
+				goto wrong;
+			}
+		}
+		*/
+		internal = w == &entry->read_int_watcher;
+		ev_io_stop(loop, internal ? &entry->read_ext_watcher : &entry->read_int_watcher);
+		entry->state = internal ? EVENT_TCP_INT_READING_INIT : EVENT_TCP_EXT_READING_INIT;
+	} else if (entry->state == EVENT_TCP_INT_READING_INIT)	{
 		internal = 1; initial = 1;
 	} else if (entry->state == EVENT_TCP_INT_READING_MORE) {
 		internal = 1; initial = 0;
@@ -297,14 +325,9 @@
 	// Done with reading, so stop the watchers involved:
 	if (internal) {
 		// Stop listening on the internal connection:
-		ev_io_stop(loop, &entry->read_watcher);
+		ev_io_stop(loop, &entry->read_int_watcher);
 		ev_timer_stop(loop, &entry->timeout_watcher);
 
-		// We received the answer from the authoritative name server,
-		// so close this connection:
-		ip_tcp_close(entry->intsock);
-		entry->intsock = -1;
-
 		// Let's see what kind of packet we are dealing with:
 		if (!dns_analyze_reply_query(general_entry)) {
 			debug_log(DEBUG_WARN, "event_tcp_read_cb(): analyzing of DNS response failed\n");
@@ -323,14 +346,13 @@
 
 		ev_timer_set(&entry->timeout_watcher, 0., global_ip_tcp_external_timeout);
 		ev_io_set(&entry->write_watcher, entry->extsock, EV_WRITE);
-		ev_io_set(&entry->read_watcher, entry->extsock, EV_READ);
 
 		ev_io_start(loop, &entry->write_watcher);
 		ev_timer_again(loop, &entry->timeout_watcher);
 
 	} else {
 		// Reading from client done, stop the watchers + timeout:
-		ev_io_stop(loop, &entry->read_watcher);
+		ev_io_stop(loop, &entry->read_ext_watcher);
 		ev_timer_stop(loop, &entry->timeout_watcher);
 
 		// Let's see what kind of packet we are dealing with:
@@ -340,10 +362,22 @@
 		}
 
 		// Now forward the packet towards the authoritative name server:
-		if (!dns_forward_query_tcp(general_entry)) {
+		if (entry->intsock < 0) {
+		    if (!dns_forward_query_tcp(general_entry)) {
 			debug_log(DEBUG_WARN, "event_tcp_read_cb(): failed to forward query towards authoritative name server\n");
 			goto wrong;
+		    }
+		    ev_io_init(&entry->read_int_watcher, event_tcp_read_cb, entry->intsock, EV_READ);
 		}
+		// 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, "event_tcp_read_cb(): forwarding query to authoritative name server (prev id = %d, new id = %d)\n",
+			entry->dns.srctxid, entry->dns.dsttxid);
+
 
 		// Now get ready for sending a TCP query towards the authoritative name server:
 		entry->state = EVENT_TCP_INT_WRITING_INIT;
@@ -351,7 +385,6 @@
 
 		ev_timer_set(&entry->timeout_watcher, 0., global_ip_internal_timeout);
 		ev_io_set(&entry->write_watcher, entry->intsock, EV_WRITE);
-		ev_io_set(&entry->read_watcher, entry->intsock, EV_READ);
 
 		ev_io_start(loop, &entry->write_watcher);
 		ev_timer_again(loop, &entry->timeout_watcher);
@@ -394,6 +427,9 @@
 		debug_log(DEBUG_INFO, "event_tcp_accept_cb(): reached maximum number of TCP connections, temporarily waiting\n");
 		event_tcp_startstop_watchers(loop, 0);
 	}
+	if (!ip_nonblock(entry->extsock)) {
+		debug_log(DEBUG_WARN, "Failed to set O_NONBLOCK on socket (%s)\n", strerror(errno));
+	}
 
 	// We have a new connection, set up the buffer:
 	entry->buffer = (uint8_t *) malloc(global_ip_tcp_buffersize);
@@ -407,14 +443,15 @@
 	entry->intsock = -1;
 
 	// Set the general entry pointer in the watcher's data pointer:
-	entry->read_watcher.data = general_entry;
+	entry->read_int_watcher.data = general_entry;
+	entry->read_ext_watcher.data = general_entry;
 	entry->write_watcher.data = general_entry;
 	entry->timeout_watcher.data = general_entry;
 
 	// Initialize the timers (for timeouts), and the i/o watchers for the external socket:
 	ev_timer_init(&entry->timeout_watcher, event_tcp_timeout_cb, 0., global_ip_tcp_external_timeout);
 	ev_io_init(&entry->write_watcher, event_tcp_write_cb, entry->extsock, EV_WRITE);
-	ev_io_init(&entry->read_watcher, event_tcp_read_cb, entry->extsock, EV_READ);
+	ev_io_init(&entry->read_ext_watcher, event_tcp_read_cb, entry->extsock, EV_READ);
 
 	if (debug_level >= DEBUG_INFO) {
 		char s[52];
@@ -423,7 +460,7 @@
 	}
 
 	// Now start the read watcher and an associated timeout:
-	ev_io_start(loop, &entry->read_watcher);
+	ev_io_start(loop, &entry->read_ext_watcher);
 	ev_timer_again(loop, &entry->timeout_watcher);
 
 	return;
openSUSE Build Service is sponsored by