Large refactor of EDNS0 UDP packet size handling.

This was kinda strange before, with a lot of cargo-cult copied code,
and no clear strategy.

Now it works like this:

When talking upstream we always add a pseudoheader, and set the
UDP packet size to --edns-packet-max unless we've had problems
talking to a server, when it's reduced to 1280 if that fixes things.

Answering queries from downstream, we get the answer (either from
upstream or local data) If local data won't fit the advertised size
(or 512 if there's not pseudoheader) return truncated. If upstream
returns truncated, do likewise. If upstream is OK, but the answer is
too big for downstream, truncate the answer.
This commit is contained in:
Simon Kelley
2024-11-23 22:38:41 +00:00
parent e778a28eee
commit e5e8c14d87
6 changed files with 157 additions and 184 deletions

View File

@@ -1316,7 +1316,7 @@ static int check_bad_address(struct dns_header *header, size_t qlen, struct bogu
GETSHORT(qtype, p);
GETSHORT(qclass, p);
GETLONG(ttl, p);
GETSHORT(rdlen, p)
GETSHORT(rdlen, p);
if (ttlp)
*ttlp = ttl;
@@ -1565,8 +1565,7 @@ static int cache_validated(const struct crec *crecp)
/* return zero if we can't answer from cache, or packet size if we can */
size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
struct in_addr local_addr, struct in_addr local_netmask,
time_t now, int ad_reqd, int do_bit, int have_pseudoheader,
int *stale, int *filtered)
time_t now, int ad_reqd, int do_bit, int *stale, int *filtered)
{
char *name = daemon->namebuff;
unsigned char *p, *ansp;
@@ -2342,10 +2341,6 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
len = ansp - (unsigned char *)header;
/* Advertise our packet size limit in our reply */
if (have_pseudoheader)
len = add_pseudoheader(header, len, (unsigned char *)limit, daemon->edns_pktsz, 0, NULL, 0, do_bit, 0);
if (ad_reqd && sec_data)
header->hb4 |= HB4_AD;
else