Commit d3a8b39c authored by Simon Kelley's avatar Simon Kelley

More EDNS0 packet-size tweaks.

parent 15379ea1
...@@ -91,8 +91,11 @@ int main (int argc, char **argv) ...@@ -91,8 +91,11 @@ int main (int argc, char **argv)
if (daemon->edns_pktsz < PACKETSZ) if (daemon->edns_pktsz < PACKETSZ)
daemon->edns_pktsz = PACKETSZ; daemon->edns_pktsz = PACKETSZ;
daemon->packet_buff_sz = daemon->edns_pktsz > DNSMASQ_PACKETSZ ? /* Min buffer size: we check after adding each record, so there must be
daemon->edns_pktsz : DNSMASQ_PACKETSZ; memory for the largest packet, and the largest record so the
min for DNS is PACKETSZ+MAXDNAME+RRFIXEDSZ which is < 1000.
This might be increased is EDNS packet size if greater than the minimum. */
daemon->packet_buff_sz = daemon->edns_pktsz + MAXDNAME + RRFIXEDSZ;
daemon->packet = safe_malloc(daemon->packet_buff_sz); daemon->packet = safe_malloc(daemon->packet_buff_sz);
daemon->addrbuff = safe_malloc(ADDRSTRLEN); daemon->addrbuff = safe_malloc(ADDRSTRLEN);
......
...@@ -179,13 +179,6 @@ struct event_desc { ...@@ -179,13 +179,6 @@ struct event_desc {
#define EC_MISC 5 #define EC_MISC 5
#define EC_INIT_OFFSET 10 #define EC_INIT_OFFSET 10
/* Min buffer size: we check after adding each record, so there must be
memory for the largest packet, and the largest record so the
min for DNS is PACKETSZ+MAXDNAME+RRFIXEDSZ which is < 1000.
This might be increased is EDNS packet size if greater than the minimum.
*/
#define DNSMASQ_PACKETSZ PACKETSZ+MAXDNAME+RRFIXEDSZ
/* Trust the compiler dead-code eliminator.... */ /* Trust the compiler dead-code eliminator.... */
#define option_bool(x) (((x) < 32) ? daemon->options & (1u << (x)) : daemon->options2 & (1u << ((x) - 32))) #define option_bool(x) (((x) < 32) ? daemon->options & (1u << (x)) : daemon->options2 & (1u << ((x) - 32)))
...@@ -594,6 +587,7 @@ struct hostsfile { ...@@ -594,6 +587,7 @@ struct hostsfile {
#define FREC_DO_QUESTION 64 #define FREC_DO_QUESTION 64
#define FREC_ADDED_PHEADER 128 #define FREC_ADDED_PHEADER 128
#define FREC_TEST_PKTSZ 256 #define FREC_TEST_PKTSZ 256
#define FREC_HAS_EXTRADATA 512
#ifdef HAVE_DNSSEC #ifdef HAVE_DNSSEC
#define HASH_SIZE 20 /* SHA-1 digest size */ #define HASH_SIZE 20 /* SHA-1 digest size */
......
...@@ -389,13 +389,14 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr, ...@@ -389,13 +389,14 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
{ {
struct server *firstsentto = start; struct server *firstsentto = start;
int forwarded = 0; int forwarded = 0;
size_t edns0_len;
/* If a query is retried, use the log_id for the retry when logging the answer. */ /* If a query is retried, use the log_id for the retry when logging the answer. */
forward->log_id = daemon->log_id; forward->log_id = daemon->log_id;
if (option_bool(OPT_ADD_MAC)) if (option_bool(OPT_ADD_MAC))
{ {
size_t new = add_mac(header, plen, ((char *) header) + daemon->packet_buff_sz, &forward->source); size_t new = add_mac(header, plen, ((char *) header) + PACKETSZ, &forward->source);
if (new != plen) if (new != plen)
{ {
plen = new; plen = new;
...@@ -405,7 +406,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr, ...@@ -405,7 +406,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
if (option_bool(OPT_CLIENT_SUBNET)) if (option_bool(OPT_CLIENT_SUBNET))
{ {
size_t new = add_source_addr(header, plen, ((char *) header) + daemon->packet_buff_sz, &forward->source); size_t new = add_source_addr(header, plen, ((char *) header) + PACKETSZ, &forward->source);
if (new != plen) if (new != plen)
{ {
plen = new; plen = new;
...@@ -416,7 +417,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr, ...@@ -416,7 +417,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
#ifdef HAVE_DNSSEC #ifdef HAVE_DNSSEC
if (option_bool(OPT_DNSSEC_VALID)) if (option_bool(OPT_DNSSEC_VALID))
{ {
size_t new = add_do_bit(header, plen, ((char *) header) + daemon->packet_buff_sz); size_t new = add_do_bit(header, plen, ((char *) header) + PACKETSZ);
if (new != plen) if (new != plen)
forward->flags |= FREC_ADDED_PHEADER; forward->flags |= FREC_ADDED_PHEADER;
...@@ -430,6 +431,10 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr, ...@@ -430,6 +431,10 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
} }
#endif #endif
/* If we're sending an EDNS0 with any options, we can't recreate the query from a reply. */
if (find_pseudoheader(header, plen, &edns0_len, NULL, NULL, NULL) && edns0_len > 11)
forward->flags |= FREC_HAS_EXTRADATA;
while (1) while (1)
{ {
...@@ -769,9 +774,12 @@ void reply_query(int fd, int family, time_t now) ...@@ -769,9 +774,12 @@ void reply_query(int fd, int family, time_t now)
check_for_ignored_address(header, n, daemon->ignore_addr)) check_for_ignored_address(header, n, daemon->ignore_addr))
return; return;
/* Note: if we send extra options in the EDNS0 header, we can't recreate
the query from the reply. */
if (RCODE(header) == REFUSED && if (RCODE(header) == REFUSED &&
!option_bool(OPT_ORDER) && !option_bool(OPT_ORDER) &&
forward->forwardall == 0) forward->forwardall == 0 &&
!(forward->flags & FREC_HAS_EXTRADATA))
/* for broken servers, attempt to send to another one. */ /* for broken servers, attempt to send to another one. */
{ {
unsigned char *pheader; unsigned char *pheader;
...@@ -919,13 +927,13 @@ void reply_query(int fd, int family, time_t now) ...@@ -919,13 +927,13 @@ void reply_query(int fd, int family, time_t now)
if (status == STAT_NEED_KEY) if (status == STAT_NEED_KEY)
{ {
new->flags |= FREC_DNSKEY_QUERY; new->flags |= FREC_DNSKEY_QUERY;
nn = dnssec_generate_query(header, ((char *) header) + daemon->packet_buff_sz, nn = dnssec_generate_query(header, ((char *) header) + server->edns_pktsz,
daemon->keyname, forward->class, T_DNSKEY, &server->addr, server->edns_pktsz); daemon->keyname, forward->class, T_DNSKEY, &server->addr, server->edns_pktsz);
} }
else else
{ {
new->flags |= FREC_DS_QUERY; new->flags |= FREC_DS_QUERY;
nn = dnssec_generate_query(header,((char *) header) + daemon->packet_buff_sz, nn = dnssec_generate_query(header,((char *) header) + server->edns_pktsz,
daemon->keyname, forward->class, T_DS, &server->addr, server->edns_pktsz); daemon->keyname, forward->class, T_DS, &server->addr, server->edns_pktsz);
} }
if ((hash = hash_questions(header, nn, daemon->namebuff))) if ((hash = hash_questions(header, nn, daemon->namebuff)))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment