mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
Improve handling of truncated replies to DNSSEC queries.
Heretofore, when a validating the result of an external query triggers a DNSKEY or DS query and the result of that query is truncated, dnsmasq has forced the whole validation process to move to TCP by returning a truncated reply to the original requestor. This forces the original requestor to retry the query in TCP mode, and the DNSSEC subqueries also get made via TCP and everything works. Note that in general the actual answer being validated is not large enough to trigger truncation, and there's no reason not to return that answer via UDP if we can validate it successfully. It follows that a substandard client which can't do TCP queries will still work if the answer could be returned via UDP, but fails if it gets an artifically truncated answer and cannot move to TCP. This patch teaches dnsmasq to move to TCP for DNSSEC queries when validating UDP answers. That makes the substandard clients mentioned above work, and saves a round trip even for clients that can do TCP.
This commit is contained in:
@@ -747,6 +747,9 @@ struct dyndir {
|
||||
#define STAT_SECURE_WILDCARD 0x70000
|
||||
#define STAT_OK 0x80000
|
||||
#define STAT_ABANDONED 0x90000
|
||||
#define STAT_NEED_DS_QUERY 0xa0000
|
||||
#define STAT_NEED_KEY_QUERY 0xb0000
|
||||
#define STAT_ASYNC 0xc0000
|
||||
|
||||
#define DNSSEC_FAIL_NYV 0x0001 /* key not yet valid */
|
||||
#define DNSSEC_FAIL_EXP 0x0002 /* key expired */
|
||||
@@ -774,6 +777,7 @@ struct dyndir {
|
||||
#define FREC_TEST_PKTSZ 256
|
||||
#define FREC_HAS_EXTRADATA 512
|
||||
#define FREC_HAS_PHEADER 1024
|
||||
#define FREC_GONE_TO_TCP 2048
|
||||
|
||||
#define HASH_SIZE 32 /* SHA-256 digest size */
|
||||
|
||||
@@ -797,7 +801,7 @@ struct frec {
|
||||
struct blockdata *stash; /* Saved reply, whilst we validate */
|
||||
size_t stash_len;
|
||||
#ifdef HAVE_DNSSEC
|
||||
int class, work_counter, validate_counter;
|
||||
int uid, class, work_counter, validate_counter;
|
||||
struct frec *dependent; /* Query awaiting internally-generated DNSKEY or DS query */
|
||||
struct frec *next_dependent; /* list of above. */
|
||||
struct frec *blocking_query; /* Query which is blocking us. */
|
||||
@@ -1523,6 +1527,12 @@ int option_read_dynfile(char *file, int flags);
|
||||
/* forward.c */
|
||||
void reply_query(int fd, time_t now);
|
||||
void receive_query(struct listener *listen, time_t now);
|
||||
#ifdef HAVE_DNSSEC
|
||||
void pop_and_retry_query(struct frec *forward, int status, time_t now);
|
||||
int tcp_key_recurse(time_t now, int status, struct dns_header *header, size_t n,
|
||||
int class, char *name, char *keyname, struct server *server,
|
||||
int have_mark, unsigned int mark, int *keycount, int *validatecount);
|
||||
#endif
|
||||
unsigned char *tcp_request(int confd, time_t now,
|
||||
union mysockaddr *local_addr, struct in_addr netmask, int auth_dns);
|
||||
void server_gone(struct server *server);
|
||||
@@ -1642,6 +1652,10 @@ void queue_event(int event);
|
||||
void send_alarm(time_t event, time_t now);
|
||||
void send_event(int fd, int event, int data, char *msg);
|
||||
void clear_cache_and_reload(time_t now);
|
||||
#ifdef HAVE_DNSSEC
|
||||
int swap_to_tcp(struct frec *forward, time_t now, int status, struct dns_header *header,
|
||||
size_t plen, int class, struct server *server, int *keycount, int *validatecount);
|
||||
#endif
|
||||
|
||||
/* netlink.c */
|
||||
#ifdef HAVE_LINUX_NETWORK
|
||||
|
||||
Reference in New Issue
Block a user