From 3a052d55fbfca49d8d435cdd2110fb2667594c61 Mon Sep 17 00:00:00 2001 From: Simon Kelley Date: Sun, 8 Mar 2026 22:19:30 +0000 Subject: [PATCH] Fix regression handling non-QUERY requests over TCP. Regression introduced in 729c16a8ace49d472bc29cc37f87ca39ade920b6 --- src/forward.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/forward.c b/src/forward.c index 272bee9..7ea1d85 100644 --- a/src/forward.c +++ b/src/forward.c @@ -2442,10 +2442,10 @@ void tcp_request(int confd, time_t now, struct iovec *bigbuff, break; /* Now get the query into the normal UDP packet buffer. - Ignore queries long than this. If we're answering locally, + Ignore queries longer than this. If we're answering locally, copy the query into the output buffer, but for forwarding, tcp_talk() - wants the query in a a different buffer from the reply. - Note that we overwrote any saved UDP query - this onlt matters in debug mode. */ + wants the query in different buffer from the reply. + Note that we overwrote any saved UDP query - this only matters in debug mode. */ daemon->srv_save = NULL; if (!read_write(confd, (unsigned char *)&tcp_len, sizeof(tcp_len), RW_READ) || !(size = ntohs(tcp_len)) || size > (size_t)daemon->packet_buff_sz || @@ -2461,6 +2461,15 @@ void tcp_request(int confd, time_t now, struct iovec *bigbuff, /* header == query */ header = (struct dns_header *)daemon->packet; + + /* Add edns0 pheader to query */ + size = add_edns0_config(header, size, ((unsigned char *) header) + daemon->edns_pktsz, &peer_addr, now, &cacheable); + + /* Clear buffer to avoid risk of information disclosure. */ + memset(bigbuff->iov_base, 0, bigbuff->iov_len); + /* Copy query into output buffer for local answering */ + memcpy(out_header, header, size); + query_count++; /* log_query gets called indirectly all over the place, so @@ -2493,13 +2502,6 @@ void tcp_request(int confd, time_t now, struct iovec *bigbuff, do_bit = 1; /* do bit */ } - size = add_edns0_config(header, size, ((unsigned char *) header) + daemon->edns_pktsz, &peer_addr, now, &cacheable); - - /* Clear buffer to avoid risk of information disclosure. */ - memset(bigbuff->iov_base, 0, bigbuff->iov_len); - /* Copy query into output buffer for local answering */ - memcpy(out_header, header, size); - log_query_mysockaddr((auth_dns ? F_NOERR | F_AUTH : 0) | F_QUERY | F_FORWARD, daemon->namebuff, &peer_addr, NULL, qtype); @@ -2552,7 +2554,7 @@ void tcp_request(int confd, time_t now, struct iovec *bigbuff, else if (!allowed) { ede = EDE_BLOCKED; - m = answer_disallowed(header, size, (u32)mark, daemon->namebuff); + m = answer_disallowed(out_header, size, (u32)mark, daemon->namebuff); } #endif #ifdef HAVE_AUTH @@ -2568,7 +2570,7 @@ void tcp_request(int confd, time_t now, struct iovec *bigbuff, /* Do this by steam now we're not in the select() loop */ check_log_writer(1); - if (m == 0 && ede == EDE_UNSET) + if (!flags && m == 0 && ede == EDE_UNSET) { struct server *master; int start;