Add missing EDNS0 section.
EDNS0 section missing in replies to EDNS0-containing queries where
answer generated from --local=/<domain>/
diff --git a/CHANGELOG b/CHANGELOG
index 792ef3d..3aca0dd 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -45,6 +45,10 @@
Fix crash on startup with a --synth-domain which has no prefix.
Introduced in 2.79. Thanks to Andreas Engel for the bug report.
+ Fix missing EDNS0 section in some replies generated by local
+ DNS configuration which confused systemd-resolvd. Thanks to
+ Steve Dodd for characterising the problem.
+
version 2.79
Fix parsing of CNAME arguments, which are confused by extra spaces.
diff --git a/src/forward.c b/src/forward.c
index c692555..b25df30 100644
--- a/src/forward.c
+++ b/src/forward.c
@@ -246,9 +246,9 @@
unsigned int crc = questions_crc(header, plen, daemon->namebuff);
void *hash = &crc;
#endif
- unsigned int gotname = extract_request(header, plen, daemon->namebuff, NULL);
-
- (void)do_bit;
+ unsigned int gotname = extract_request(header, plen, daemon->namebuff, NULL);
+ unsigned char *oph = find_pseudoheader(header, plen, NULL, NULL, NULL, NULL);
+ (void)do_bit;
/* may be no servers available. */
if (forward || (hash && (forward = lookup_frec_by_sender(ntohs(header->id), udpaddr, hash))))
@@ -399,7 +399,6 @@
struct server *firstsentto = start;
int subnet, forwarded = 0;
size_t edns0_len;
- unsigned char *oph = find_pseudoheader(header, plen, NULL, NULL, NULL, NULL);
unsigned char *pheader;
/* If a query is retried, use the log_id for the retry when logging the answer. */
@@ -554,6 +553,8 @@
if (udpfd != -1)
{
plen = setup_reply(header, plen, addrp, flags, daemon->local_ttl);
+ if (oph)
+ plen = add_pseudoheader(header, plen, ((unsigned char *) header) + PACKETSZ, daemon->edns_pktsz, 0, NULL, 0, do_bit, 0);
send_from(udpfd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND), (char *)header, plen, udpaddr, dst_addr, dst_iface);
}
@@ -2104,7 +2105,11 @@
/* In case of local answer or no connections made. */
if (m == 0)
- m = setup_reply(header, (unsigned int)size, addrp, flags, daemon->local_ttl);
+ {
+ m = setup_reply(header, (unsigned int)size, addrp, flags, daemon->local_ttl);
+ if (have_pseudoheader)
+ m = add_pseudoheader(header, m, ((unsigned char *) header) + 65536, daemon->edns_pktsz, 0, NULL, 0, do_bit, 0);
+ }
}
}