Fix DNSSEC work counting when swapping from UDP to TCP

This commit is contained in:
Simon Kelley
2024-09-23 16:45:12 +01:00
parent f5cdb007d8
commit e9a7cd0a50
4 changed files with 26 additions and 4 deletions

2
debian

Submodule debian updated: 83e05da879...05f03dca94

View File

@@ -896,7 +896,8 @@ int cache_recv_insert(time_t now, int fd)
Restart UDP validation process with the returned result. */ Restart UDP validation process with the returned result. */
if (m == -2) if (m == -2)
{ {
int status, uid; int status, uid, keycount, validatecount;
int *keycountp, *validatecountp;
struct frec *forward; struct frec *forward;
if (!read_write(fd, (unsigned char *)&status, sizeof(status), 1)) 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; return 0;
if (!read_write(fd, (unsigned char *)&uid, sizeof(uid), 1)) if (!read_write(fd, (unsigned char *)&uid, sizeof(uid), 1))
return 0; 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 /* There's a tiny chance that the frec may have been freed
and reused before the TCP process returns. Detect that with and reused before the TCP process returns. Detect that with
the uid field which is unique modulo 2^32 for each use. */ the uid field which is unique modulo 2^32 for each use. */
if (uid == forward->uid) 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; return 1;
} }
#endif #endif

View 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 *)&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, 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 *)&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); close(daemon->pipe_to_parent);
flush_log(); flush_log();

View 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) 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); 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 */ /* 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, 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); header, forward->stash_len, forward->class, forward->sentto, &orig->work_counter, &orig->validate_counter);