Rationalise DNS packet-buffer size calculations.
diff --git a/src/dnsmasq.c b/src/dnsmasq.c
index 3e5f51e..27928fe 100644
--- a/src/dnsmasq.c
+++ b/src/dnsmasq.c
@@ -90,7 +90,12 @@
#endif
if (daemon->edns_pktsz < PACKETSZ)
- daemon->edns_pktsz = option_bool(OPT_DNSSEC_VALID) ? EDNS_PKTSZ : PACKETSZ;
+ daemon->edns_pktsz = PACKETSZ;
+#ifdef HAVE_DNSSEC
+ /* Enforce min packet big enough for DNSSEC */
+ if (option_bool(OPT_DNSSEC_VALID) && daemon->edns_pktsz < EDNS_PKTSZ)
+ daemon->edns_pktsz = EDNS_PKTSZ;
+#endif
daemon->packet_buff_sz = daemon->edns_pktsz > DNSMASQ_PACKETSZ ?
daemon->edns_pktsz : DNSMASQ_PACKETSZ;
daemon->packet = safe_malloc(daemon->packet_buff_sz);
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
index 044c865..7f6dd7e 100644
--- a/src/dnsmasq.h
+++ b/src/dnsmasq.h
@@ -1048,7 +1048,7 @@
#endif
/* dnssec.c */
-size_t dnssec_generate_query(struct dns_header *header, char *name, int class, int type, union mysockaddr *addr);
+size_t dnssec_generate_query(struct dns_header *header, char *end, char *name, int class, int type, union mysockaddr *addr);
int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t n, char *name, char *keyname, int class);
int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class);
int validate_rrset(time_t now, struct dns_header *header, size_t plen, int class,
diff --git a/src/dnssec.c b/src/dnssec.c
index 2e82b16..f0f709d 100644
--- a/src/dnssec.c
+++ b/src/dnssec.c
@@ -479,7 +479,7 @@
return 1;
}
-size_t dnssec_generate_query(struct dns_header *header, char *name, int class, int type, union mysockaddr *addr)
+size_t dnssec_generate_query(struct dns_header *header, char *end, char *name, int class, int type, union mysockaddr *addr)
{
unsigned char *p;
char types[20];
@@ -511,7 +511,7 @@
PUTSHORT(type, p);
PUTSHORT(class, p);
- return add_do_bit(header, p - (unsigned char *)header, ((char *) header) + PACKETSZ);
+ return add_do_bit(header, p - (unsigned char *)header, end);
}
/* The DNS packet is expected to contain the answer to a DNSKEY query.
diff --git a/src/forward.c b/src/forward.c
index f254fe1..9ae64d6 100644
--- a/src/forward.c
+++ b/src/forward.c
@@ -330,11 +330,11 @@
int forwarded = 0;
if (option_bool(OPT_ADD_MAC))
- plen = add_mac(header, plen, ((char *) header) + PACKETSZ, &forward->source);
+ plen = add_mac(header, plen, ((char *) header) + daemon->packet_buff_sz, &forward->source);
if (option_bool(OPT_CLIENT_SUBNET))
{
- size_t new = add_source_addr(header, plen, ((char *) header) + PACKETSZ, &forward->source);
+ size_t new = add_source_addr(header, plen, ((char *) header) + daemon->packet_buff_sz, &forward->source);
if (new != plen)
{
plen = new;
@@ -345,7 +345,7 @@
#ifdef HAVE_DNSSEC
if (option_bool(OPT_DNSSEC_VALID))
{
- plen = add_do_bit(header, plen, ((char *) header) + PACKETSZ);
+ plen = add_do_bit(header, plen, ((char *) header) + daemon->packet_buff_sz);
header->hb4 |= HB4_CD;
}
#endif
@@ -585,7 +585,7 @@
union mysockaddr serveraddr;
struct frec *forward;
socklen_t addrlen = sizeof(serveraddr);
- ssize_t n = recvfrom(fd, daemon->packet, daemon->edns_pktsz, 0, &serveraddr.sa, &addrlen);
+ ssize_t n = recvfrom(fd, daemon->packet, daemon->packet_buff_sz, 0, &serveraddr.sa, &addrlen);
size_t nn;
struct server *server;
@@ -732,12 +732,14 @@
if (status == STAT_NEED_KEY)
{
new->flags |= FREC_DNSKEY_QUERY;
- nn = dnssec_generate_query(header, daemon->keyname, forward->class, T_DNSKEY, &server->addr);
+ nn = dnssec_generate_query(header, ((char *) header) + daemon->packet_buff_sz,
+ daemon->keyname, forward->class, T_DNSKEY, &server->addr);
}
else if (status == STAT_NEED_DS)
{
new->flags |= FREC_DS_QUERY;
- nn = dnssec_generate_query(header, daemon->keyname, forward->class, T_DS, &server->addr);
+ nn = dnssec_generate_query(header,((char *) header) + daemon->packet_buff_sz,
+ daemon->keyname, forward->class, T_DS, &server->addr);
}
new->crc = questions_crc(header, nn, daemon->namebuff);
new->new_id = get_id(new->crc);
@@ -1064,7 +1066,7 @@
#ifdef HAVE_AUTH
if (auth_dns)
{
- m = answer_auth(header, ((char *) header) + PACKETSZ, (size_t)n, now, &source_addr, local_auth);
+ m = answer_auth(header, ((char *) header) + daemon->packet_buff_sz, (size_t)n, now, &source_addr, local_auth);
if (m >= 1)
{
send_from(listen->fd, option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND),
@@ -1075,7 +1077,7 @@
else
#endif
{
- m = answer_request(header, ((char *) header) + PACKETSZ, (size_t)n,
+ m = answer_request(header, ((char *) header) + daemon->packet_buff_sz, (size_t)n,
dst_addr_4, netmask, now);
if (m >= 1)