Tidy up pipe-to-parent code in DNS TCP path.

This commit is contained in:
Simon Kelley
2025-04-23 12:14:00 +01:00
parent 9e67099ce7
commit a458c2bfb0
3 changed files with 164 additions and 135 deletions

View File

@@ -799,10 +799,12 @@ void cache_end_insert(void)
char *name = cache_get_name(new_chain);
ssize_t m = strlen(name);
unsigned int flags = new_chain->flags;
unsigned char op = PIPE_OP_RR;
#ifdef HAVE_DNSSEC
u16 class = new_chain->uid;
#endif
read_write(daemon->pipe_to_parent, &op, sizeof(op), RW_WRITE);
read_write(daemon->pipe_to_parent, (unsigned char *)&m, sizeof(m), RW_WRITE);
read_write(daemon->pipe_to_parent, (unsigned char *)name, m, RW_WRITE);
read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->ttd, sizeof(new_chain->ttd), RW_WRITE);
@@ -838,12 +840,18 @@ void cache_end_insert(void)
/* signal end of cache insert in master process */
if (daemon->pipe_to_parent != -1)
{
ssize_t m = -1;
read_write(daemon->pipe_to_parent, (unsigned char *)&m, sizeof(m), RW_WRITE);
unsigned char op = PIPE_OP_END;
read_write(daemon->pipe_to_parent, &op, sizeof(op), RW_WRITE);
}
}
#ifdef HAVE_DNSSEC
void cache_update_hwm(void)
{
/* Sneak out possibly updated crypto HWM values. */
unsigned char op = PIPE_OP_STATS;
read_write(daemon->pipe_to_parent, &op, sizeof(op), RW_WRITE);
read_write(daemon->pipe_to_parent,
(unsigned char *)&daemon->metrics[METRIC_CRYPTO_HWM],
sizeof(daemon->metrics[METRIC_CRYPTO_HWM]), RW_WRITE);
@@ -853,12 +861,8 @@ void cache_end_insert(void)
read_write(daemon->pipe_to_parent,
(unsigned char *)&daemon->metrics[METRIC_WORK_HWM],
sizeof(daemon->metrics[METRIC_WORK_HWM]), RW_WRITE);
}
#endif
}
new_chain = NULL;
}
/* A marshalled cache entry arrives on fd, read, unmarshall and insert into cache of master process. */
int cache_recv_insert(time_t now, int fd)
@@ -869,18 +873,24 @@ int cache_recv_insert(time_t now, int fd)
time_t ttd;
unsigned int flags;
struct crec *crecp = NULL;
unsigned char op;
cache_start_insert();
while (1)
{
if (!read_write(fd, (unsigned char *)&m, sizeof(m), RW_READ))
if (!read_write(fd, &op, sizeof(op), RW_READ))
return 0;
if (m == -1)
switch (op)
{
case PIPE_OP_END:
cache_end_insert();
return 1;
#ifdef HAVE_DNSSEC
case PIPE_OP_STATS:
{
/* Sneak in possibly updated crypto HWM. */
unsigned int val;
@@ -896,16 +906,13 @@ int cache_recv_insert(time_t now, int fd)
return 0;
if (val > daemon->metrics[METRIC_WORK_HWM])
daemon->metrics[METRIC_WORK_HWM] = val;
#endif
cache_end_insert();
return 1;
}
#ifdef HAVE_DNSSEC
case PIPE_OP_RESULT:
{
/* UDP validation moved to TCP to avoid truncation.
Restart UDP validation process with the returned result. */
if (m == -2)
{
int status, uid, keycount, validatecount;
int *keycountp, *validatecountp;
size_t ret_len;
@@ -950,7 +957,9 @@ int cache_recv_insert(time_t now, int fd)
}
#endif
if (!read_write(fd, (unsigned char *)daemon->namebuff, m, RW_READ) ||
case PIPE_OP_RR:
if (!read_write(fd, (unsigned char *)&m, sizeof(m), RW_READ) ||
!read_write(fd, (unsigned char *)daemon->namebuff, m, RW_READ) ||
!read_write(fd, (unsigned char *)&ttd, sizeof(ttd), RW_READ) ||
!read_write(fd, (unsigned char *)&flags, sizeof(flags), RW_READ) ||
!read_write(fd, (unsigned char *)&addr, sizeof(addr), RW_READ))
@@ -1003,6 +1012,12 @@ int cache_recv_insert(time_t now, int fd)
#endif
crecp = really_insert(daemon->namebuff, &addr, class, now, ttl, flags);
}
/* loop reading RRs, since we don't want to go back to the poll() loop
and start processing other queries which might pollute the insertion
chain. The child will never block between the first OP_RR and the OP_END */
continue;
}
}
}

View File

@@ -2124,6 +2124,10 @@ static void do_tcp_connection(struct listener *listener, time_t now, int slot)
if (!option_bool(OPT_DEBUG))
{
#ifdef HAVE_DNSSEC
cache_update_hwm(); /* Sneak out possibly updated crypto HWM values. */
#endif
close(daemon->pipe_to_parent);
flush_log();
_exit(0);
@@ -2229,10 +2233,10 @@ int swap_to_tcp(struct frec *forward, time_t now, int status, struct dns_header
if (!option_bool(OPT_DEBUG))
{
ssize_t m = -2;
unsigned char op = PIPE_OP_RESULT;
/* tell our parent we're done, and what the result was then exit. */
read_write(daemon->pipe_to_parent, (unsigned char *)&m, sizeof(m), RW_WRITE);
read_write(daemon->pipe_to_parent, &op, sizeof(op), RW_WRITE);
read_write(daemon->pipe_to_parent, (unsigned char *)&status, sizeof(status), RW_WRITE);
read_write(daemon->pipe_to_parent, (unsigned char *)plen, sizeof(*plen), RW_WRITE);
read_write(daemon->pipe_to_parent, (unsigned char *)header, *plen, RW_WRITE);
@@ -2242,6 +2246,9 @@ int swap_to_tcp(struct frec *forward, time_t now, int status, struct dns_header
read_write(daemon->pipe_to_parent, (unsigned char *)&keycount, sizeof(keycount), RW_WRITE);
read_write(daemon->pipe_to_parent, (unsigned char *)validatecount, sizeof(*validatecount), RW_WRITE);
read_write(daemon->pipe_to_parent, (unsigned char *)&validatecount, sizeof(validatecount), RW_WRITE);
cache_update_hwm(); /* Sneak out possibly updated crypto HWM values. */
close(daemon->pipe_to_parent);
flush_log();

View File

@@ -537,6 +537,10 @@ struct crec {
#define SRC_HOSTS 2
#define SRC_AH 3
#define PIPE_OP_RR 1 /* Resource record */
#define PIPE_OP_END 2 /* Cache entry complete: commit */
#define PIPE_OP_RESULT 3 /* validation result. */
#define PIPE_OP_STATS 4 /* Update parent's stats */
/* struct sockaddr is not large enough to hold any address,
and specifically not big enough to hold an IPv6 address.
@@ -1354,6 +1358,9 @@ void cache_end_insert(void);
void cache_start_insert(void);
unsigned int cache_remove_uid(const unsigned int uid);
int cache_recv_insert(time_t now, int fd);
#ifdef HAVE_DNSSEC
void cache_update_hwm(void);
#endif
struct crec *cache_insert(char *name, union all_addr *addr, unsigned short class,
time_t now, unsigned long ttl, unsigned int flags);
void cache_reload(void);