Fix DNSSEC work counting when swapping from UDP to TCP
authorSimon Kelley <simon@thekelleys.org.uk>
Mon, 23 Sep 2024 15:45:12 +0000 (16:45 +0100)
committerSimon Kelley <simon@thekelleys.org.uk>
Fri, 4 Oct 2024 16:20:33 +0000 (17:20 +0100)
debian
src/cache.c
src/dnsmasq.c
src/forward.c

diff --git a/debian b/debian
index 83e05da..05f03dc 160000 (submodule)
--- a/debian
+++ b/debian
@@ -1 +1 @@
-Subproject commit 83e05da8790e04c80dc13aa4e84c50972fad620d
+Subproject commit 05f03dca943f5e7903d8d8131fbd1030239bacb7
index 3119b86..43dd094 100644 (file)
@@ -896,7 +896,8 @@ int cache_recv_insert(time_t now, int fd)
         Restart UDP validation process with the returned result. */
       if (m == -2)
        {
-         int status, uid;
+         int status, uid, keycount, validatecount;
+         int *keycountp, *validatecountp;
          struct frec *forward;
          
          if (!read_write(fd, (unsigned char *)&status, sizeof(status), 1))
@@ -905,13 +906,27 @@ int cache_recv_insert(time_t now, int fd)
            return 0;
          if (!read_write(fd, (unsigned char *)&uid, sizeof(uid), 1))
            return 0;
-
+         if (!read_write(fd, (unsigned char *)&keycount, sizeof(keycount), 1))
+           return 0;
+         if (!read_write(fd, (unsigned char *)&keycountp, sizeof(keycountp), 1))
+           return 0;
+         if (!read_write(fd, (unsigned char *)&validatecount, sizeof(validatecount), 1))
+           return 0;
+         if (!read_write(fd, (unsigned char *)&validatecountp, sizeof(validatecountp), 1))
+           return 0;
+         
          /* There's a tiny chance that the frec may have been freed 
             and reused before the TCP process returns. Detect that with
             the uid field which is unique modulo 2^32 for each use. */
          if (uid == forward->uid)
-           pop_and_retry_query(forward, status, now);
+           {
+             /* repatriate the work counters from the child process. */
+             *keycountp = keycount;
+             *validatecountp = validatecount;
 
+             pop_and_retry_query(forward, status, now);
+           }
          return 1;
        }
 #endif
index e4a45f8..e3d04ed 100644 (file)
@@ -2169,6 +2169,10 @@ int swap_to_tcp(struct frec *forward, time_t now, int status, struct dns_header
        read_write(daemon->pipe_to_parent, (unsigned char *)&status, sizeof(status), 0);
        read_write(daemon->pipe_to_parent, (unsigned char *)&forward, sizeof(forward), 0);
        read_write(daemon->pipe_to_parent, (unsigned char *)&forward->uid, sizeof(forward->uid), 0);
+       read_write(daemon->pipe_to_parent, (unsigned char *)keycount, sizeof(*keycount), 0);
+       read_write(daemon->pipe_to_parent, (unsigned char *)&keycount, sizeof(keycount), 0);
+       read_write(daemon->pipe_to_parent, (unsigned char *)validatecount, sizeof(*validatecount), 0);
+       read_write(daemon->pipe_to_parent, (unsigned char *)&validatecount, sizeof(validatecount), 0);
        close(daemon->pipe_to_parent);
        
        flush_log();
index 737da1b..476ea25 100644 (file)
@@ -924,6 +924,9 @@ static void dnssec_validate(struct frec *forward, struct dns_header *header,
          if  (extract_name(header, plen, &p, daemon->namebuff, 0, 4) == 1)
            log_query(F_UPSTREAM | F_NOEXTRA, daemon->namebuff, NULL, "truncated", (forward->flags & FREC_DNSKEY_QUERY) ? T_DNSKEY : T_DS);
          
+         /* Don't count failed UDP attempt AND TCP */
+         orig->work_counter++;
+
          /* NOTE: Can't move connection marks from UDP to TCP */
          status = swap_to_tcp(forward, now, (forward->flags & FREC_DNSKEY_QUERY) ? STAT_NEED_KEY_QUERY : STAT_NEED_DS_QUERY,
                               header, forward->stash_len, forward->class, forward->sentto, &orig->work_counter, &orig->validate_counter);