]> git.ipfire.org Git - people/ms/dnsmasq.git/commitdiff
More EDNS0 packet-size tweaks.
authorSimon Kelley <simon@thekelleys.org.uk>
Wed, 23 Dec 2015 12:27:37 +0000 (12:27 +0000)
committerSimon Kelley <simon@thekelleys.org.uk>
Wed, 23 Dec 2015 12:27:37 +0000 (12:27 +0000)
src/dnsmasq.c
src/dnsmasq.h
src/forward.c

index 81254f67f4d0e79b2ce4427ffe94064867655fbf..45761ccd89bec1bf5039b337219ff4f2e9001822 100644 (file)
@@ -91,8 +91,11 @@ int main (int argc, char **argv)
   if (daemon->edns_pktsz < PACKETSZ)
     daemon->edns_pktsz = PACKETSZ;
 
-  daemon->packet_buff_sz = daemon->edns_pktsz > DNSMASQ_PACKETSZ ? 
-    daemon->edns_pktsz : DNSMASQ_PACKETSZ;
+  /* 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. */ 
+  daemon->packet_buff_sz = daemon->edns_pktsz + MAXDNAME + RRFIXEDSZ;
   daemon->packet = safe_malloc(daemon->packet_buff_sz);
   
   daemon->addrbuff = safe_malloc(ADDRSTRLEN);
index 4503a2d5739aedce0eb4712c3b72687ae7ab6f65..1c94f2a152392c1b42ed15f12ac56c2e7908c7f2 100644 (file)
@@ -179,13 +179,6 @@ struct event_desc {
 #define EC_MISC        5
 #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.... */
 #define option_bool(x) (((x) < 32) ? daemon->options & (1u << (x)) : daemon->options2 & (1u << ((x) - 32)))
 
@@ -594,6 +587,7 @@ struct hostsfile {
 #define FREC_DO_QUESTION       64
 #define FREC_ADDED_PHEADER    128
 #define FREC_TEST_PKTSZ       256
+#define FREC_HAS_EXTRADATA    512        
 
 #ifdef HAVE_DNSSEC
 #define HASH_SIZE 20 /* SHA-1 digest size */
index e1766b939f53af834b30586472e0c2ca37df474c..c0e4d9aa31813703838115aaff03e396dc44c3da 100644 (file)
@@ -389,13 +389,14 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
     {
       struct server *firstsentto = start;
       int forwarded = 0;
-      
+      size_t edns0_len;
+
       /* If a query is retried, use the log_id for the retry when logging the answer. */
       forward->log_id = daemon->log_id;
       
       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)
            {
              plen = new;
@@ -405,7 +406,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
 
       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)
            {
              plen = new;
@@ -416,7 +417,7 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
 #ifdef HAVE_DNSSEC
       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)
            forward->flags |= FREC_ADDED_PHEADER;
@@ -430,6 +431,10 @@ static int forward_query(int udpfd, union mysockaddr *udpaddr,
 
        }
 #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)
        { 
@@ -769,9 +774,12 @@ void reply_query(int fd, int family, time_t now)
       check_for_ignored_address(header, n, daemon->ignore_addr))
     return;
 
+  /* Note: if we send extra options in the EDNS0 header, we can't recreate
+     the query from the reply. */
   if (RCODE(header) == REFUSED &&
       !option_bool(OPT_ORDER) &&
-      forward->forwardall == 0)
+      forward->forwardall == 0 &&
+      !(forward->flags & FREC_HAS_EXTRADATA))
     /* for broken servers, attempt to send to another one. */
     {
       unsigned char *pheader;
@@ -919,13 +927,13 @@ 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, ((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);
                        }
                      else 
                        {
                          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);
                        }
                      if ((hash = hash_questions(header, nn, daemon->namebuff)))