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