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;