From 60b68069cf8bde6f2201ece5735e1c8cf68378f3 Mon Sep 17 00:00:00 2001 From: Simon Kelley Date: Wed, 8 Jan 2014 12:10:28 +0000 Subject: [PATCH] Rationalise DNS packet-buffer size calculations. --- src/dnsmasq.c | 7 ++++++- src/dnsmasq.h | 2 +- src/dnssec.c | 4 ++-- src/forward.c | 18 ++++++++++-------- 4 files changed, 19 insertions(+), 12 deletions(-) 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 @@ int main (int argc, char **argv) #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 @@ int in_zone(struct auth_zone *zone, char *name, char **cut); #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 @@ static int digestalg_add_rdata(int sigtype, struct dns_header *header, size_t pk 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 @@ size_t dnssec_generate_query(struct dns_header *header, char *name, int class, i 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 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr, 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 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr, #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 @@ void reply_query(int fd, int family, time_t now) 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 @@ void reply_query(int fd, int family, time_t now) 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 @@ void receive_query(struct listener *listen, time_t now) #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 @@ void receive_query(struct listener *listen, time_t now) 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) -- 2.39.2