Use a simpler arrangement for the all_addr union to avoid

the compiler padding it with an extra 8 bytes.

Use the F_KEYTAG flag in a a cache record to discriminate between
an arbitrary RR stored entirely in the addr union and one
which has a point to block storage.
This commit is contained in:
Simon Kelley
2023-04-01 21:35:26 +01:00
parent 3a601d06bd
commit a78487a4df
3 changed files with 84 additions and 51 deletions

View File

@@ -275,8 +275,8 @@ static void cache_blockdata_free(struct crec *crecp)
{
if (!(crecp->flags & F_NEG))
{
if (crecp->flags & F_RR && crecp->addr.rr.len == -1)
blockdata_free(crecp->addr.rr.u.block.rrdata);
if ((crecp->flags & F_RR) && (crecp->flags & F_KEYTAG))
blockdata_free(crecp->addr.rrblock.rrdata);
#ifdef HAVE_DNSSEC
else if (crecp->flags & F_DNSKEY)
blockdata_free(crecp->addr.key.keydata);
@@ -469,10 +469,20 @@ static struct crec *cache_scan_free(char *name, union all_addr *addr, unsigned s
{
if ((crecp->flags & F_FORWARD) && hostname_isequal(cache_get_name(crecp), name))
{
int rrmatch = 0;
if (crecp->flags & flags & F_RR)
{
unsigned short rrc = (crecp->flags & F_KEYTAG) ? crecp->addr.rrblock.rrtype : crecp->addr.rrdata.rrtype;
unsigned short rra = (flags & F_KEYTAG) ? addr->rrblock.rrtype : addr->rrdata.rrtype;
if (rrc == rra)
rrmatch = 1;
}
/* Don't delete DNSSEC in favour of a CNAME, they can co-exist */
if ((flags & crecp->flags & (F_IPV4 | F_IPV6 | F_RR | F_NXDOMAIN)) ||
if ((flags & crecp->flags & (F_IPV4 | F_IPV6 | F_NXDOMAIN)) ||
(((crecp->flags | flags) & F_CNAME) && !(crecp->flags & (F_DNSKEY | F_DS))) ||
((crecp->flags & flags & F_RR) && addr->rr.rrtype == crecp->addr.rr.rrtype))
rrmatch)
{
if (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG))
return crecp;
@@ -795,8 +805,8 @@ void cache_end_insert(void)
if (flags & F_RR)
{
/* A negative RR entry is possible and has no data, obviously. */
if (!(flags & F_NEG) && new_chain->addr.rr.len == -1)
blockdata_write(new_chain->addr.rr.u.block.rrdata, new_chain->addr.rr.u.block.datalen, daemon->pipe_to_parent);
if (!(flags & F_NEG) && (flags & F_KEYTAG))
blockdata_write(new_chain->addr.rrblock.rrdata, new_chain->addr.rrblock.datalen, daemon->pipe_to_parent);
}
#ifdef HAVE_DNSSEC
if (flags & F_DNSKEY)
@@ -869,8 +879,8 @@ int cache_recv_insert(time_t now, int fd)
if (!read_write(fd, (unsigned char *)&addr, sizeof(addr), 1))
return 0;
if ((flags & F_RR) && !(flags & F_NEG) &&
addr.rr.len == -1 && !(addr.rr.u.block.rrdata = blockdata_read(fd, addr.rr.u.block.datalen)))
if ((flags & F_RR) && !(flags & F_NEG) && (flags & F_KEYTAG)
&& !(addr.rrblock.rrdata = blockdata_read(fd, addr.rrblock.datalen)))
return 0;
#ifdef HAVE_DNSSEC
if (flags & F_DNSKEY)
@@ -1796,7 +1806,12 @@ static void dump_cache_entry(struct crec *cache, time_t now)
if ((cache->flags & F_CNAME) && !is_outdated_cname_pointer(cache))
a = sanitise(cache_get_cname_target(cache));
else if (cache->flags & F_RR)
sprintf(a, "%s", querystr(NULL, cache->addr.rr.rrtype));
{
if (cache->flags & F_KEYTAG)
sprintf(a, "%s", querystr(NULL, cache->addr.rrblock.rrtype));
else
sprintf(a, "%s", querystr(NULL, cache->addr.rrdata.rrtype));
}
#ifdef HAVE_DNSSEC
else if (cache->flags & F_DS)
{
@@ -2052,7 +2067,14 @@ void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg,
{
dest = daemon->addrbuff;
if (flags & F_KEYTAG)
if (flags & F_RR)
{
if (flags & F_KEYTAG)
dest = querystr(NULL, addr->rrblock.rrtype);
else
dest = querystr(NULL, addr->rrdata.rrtype);
}
else if (flags & F_KEYTAG)
sprintf(daemon->addrbuff, arg, addr->log.keytag, addr->log.algo, addr->log.digest);
else if (flags & F_RCODE)
{
@@ -2083,8 +2105,6 @@ void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg,
sprintf(portstring, "#%u", type);
}
}
else if (flags & F_RR)
dest = querystr(NULL, addr->rr.rrtype);
else
dest = arg;
}