From 4b5ea12e90024ade5033b3b83a8b2620035952ba Mon Sep 17 00:00:00 2001 From: Simon Kelley Date: Mon, 22 Apr 2013 10:18:26 +0100 Subject: [PATCH] Send TCP DNS messages in one write() call. Stops TCP stream fragmenting. This is an optimisation, not a bugfix. Thanks to Jim Bos for spotting it. --- src/forward.c | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/src/forward.c b/src/forward.c index 1ea25dd..77d6849 100644 --- a/src/forward.c +++ b/src/forward.c @@ -880,9 +880,12 @@ unsigned char *tcp_request(int confd, time_t now, unsigned short qtype; unsigned int gotname; unsigned char c1, c2; - /* Max TCP packet + slop */ - unsigned char *packet = whine_malloc(65536 + MAXDNAME + RRFIXEDSZ); - struct dns_header *header; + /* Max TCP packet + slop + size */ + unsigned char *packet = whine_malloc(65536 + MAXDNAME + RRFIXEDSZ + sizeof(u16)); + unsigned char *payload = &packet[2]; + /* largest field in header is 16-bits, so this is still sufficiently aligned */ + struct dns_header *header = (struct dns_header *)payload; + u16 *length = (u16 *)packet; struct server *last_server; struct in_addr dst_addr_4; union mysockaddr peer_addr; @@ -896,14 +899,12 @@ unsigned char *tcp_request(int confd, time_t now, if (!packet || !read_write(confd, &c1, 1, 1) || !read_write(confd, &c2, 1, 1) || !(size = c1 << 8 | c2) || - !read_write(confd, packet, size, 1)) + !read_write(confd, payload, size, 1)) return packet; if (size < (int)sizeof(struct dns_header)) continue; - header = (struct dns_header *)packet; - /* save state of "cd" flag in query */ checking_disabled = header->hb4 & HB4_CD; @@ -1020,12 +1021,9 @@ unsigned char *tcp_request(int confd, time_t now, #endif } - c1 = size >> 8; - c2 = size; + *length = htons(size); - if (!read_write(last_server->tcpfd, &c1, 1, 0) || - !read_write(last_server->tcpfd, &c2, 1, 0) || - !read_write(last_server->tcpfd, packet, size, 0) || + if (!read_write(last_server->tcpfd, packet, size + sizeof(u16), 0) || !read_write(last_server->tcpfd, &c1, 1, 1) || !read_write(last_server->tcpfd, &c2, 1, 1)) { @@ -1035,7 +1033,7 @@ unsigned char *tcp_request(int confd, time_t now, } m = (c1 << 8) | c2; - if (!read_write(last_server->tcpfd, packet, m, 1)) + if (!read_write(last_server->tcpfd, payload, m, 1)) return packet; if (!gotname) @@ -1071,12 +1069,9 @@ unsigned char *tcp_request(int confd, time_t now, check_log_writer(NULL); - c1 = m>>8; - c2 = m; - if (m == 0 || - !read_write(confd, &c1, 1, 0) || - !read_write(confd, &c2, 1, 0) || - !read_write(confd, packet, m, 0)) + *length = htons(m); + + if (m == 0 || !read_write(confd, packet, m + sizeof(u16), 0)) return packet; } } -- 1.8.1.4