diff --git a/debian b/debian index 83e05da..05f03dc 160000 --- a/debian +++ b/debian @@ -1 +1 @@ -Subproject commit 83e05da8790e04c80dc13aa4e84c50972fad620d +Subproject commit 05f03dca943f5e7903d8d8131fbd1030239bacb7 diff --git a/src/cache.c b/src/cache.c index 3119b86..43dd094 100644 --- a/src/cache.c +++ b/src/cache.c @@ -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 diff --git a/src/dnsmasq.c b/src/dnsmasq.c index e4a45f8..e3d04ed 100644 --- a/src/dnsmasq.c +++ b/src/dnsmasq.c @@ -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(); diff --git a/src/forward.c b/src/forward.c index 737da1b..476ea25 100644 --- a/src/forward.c +++ b/src/forward.c @@ -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);