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

@@ -779,7 +779,7 @@ struct frec {
union all_addr dest;
unsigned int iface, log_id;
int fd;
unsigned short orig_id;
unsigned short orig_id, udp_pkt_size;
struct frec_src *next;
} frec_src;
struct server *sentto; /* NULL means free */
@@ -1395,8 +1395,7 @@ void report_addresses(struct dns_header *header, size_t len, u32 mark);
#endif
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);
int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
time_t now);
int check_for_ignored_address(struct dns_header *header, size_t qlen);
@@ -1419,7 +1418,7 @@ int in_zone(struct auth_zone *zone, char *name, char **cut);
/* dnssec.c */
#ifdef HAVE_DNSSEC
size_t dnssec_generate_query(struct dns_header *header, unsigned char *end, char *name, int class, int id, int type, int edns_pktsz);
size_t dnssec_generate_query(struct dns_header *header, unsigned char *end, char *name, int class, int id, int type);
int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, char *name,
char *keyname, int class, int *validate_count);
int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char *name,