{
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);
{
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;
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)
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)
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)
{
{
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)
{
sprintf(portstring, "#%u", type);
}
}
- else if (flags & F_RR)
- dest = querystr(NULL, addr->rr.rrtype);
else
dest = arg;
}
if (!CHECK_LEN(header, p1, qlen, ardlen))
return 2; /* bad packet */
- addr.rr.rrtype = aqtype;
-
/* If the data has no names and is small enough, store it in
the crec address field rather than allocate a block. */
- if (*rrdesc == -1 && ardlen <= RR_IMDATALEN)
+ if (*rrdesc == -1 && ardlen <= (int)RR_IMDATALEN)
{
- addr.rr.len = (char)ardlen;
- if (ardlen != 0)
- memcpy(addr.rr.u.data, p1, ardlen);
+ addr.rrdata.rrtype = aqtype;
+ addr.rrdata.datalen = (char)ardlen;
+ if (ardlen != 0)
+ memcpy(addr.rrdata.data, p1, ardlen);
}
else
{
- addr.rr.len = -1;
- addr.rr.u.block.datalen = 0;
+ addr.rrblock.rrtype = aqtype;
+ addr.rrblock.datalen = 0;
+ flags |= F_KEYTAG; /* discriminates between rrdata and rrblock */
/* The RR data may include names, and those names may include
compression, which will be rendered meaningless when
Here we go through a description of the packet type to
find the names, and extract them to a c-string and then
re-encode them to standalone DNS format without compression. */
- if (!(addr.rr.u.block.rrdata = blockdata_alloc(NULL, 0)))
+ if (!(addr.rrblock.rrdata = blockdata_alloc(NULL, 0)))
return 0;
do
{
if (desc == -1)
{
/* Copy the rest of the RR and end. */
- if (!blockdata_expand(addr.rr.u.block.rrdata, addr.rr.u.block.datalen, (char *)p1, endrr - p1))
+ if (!blockdata_expand(addr.rrblock.rrdata, addr.rrblock.datalen, (char *)p1, endrr - p1))
return 0;
- addr.rr.u.block.datalen += endrr - p1;
+ addr.rrblock.datalen += endrr - p1;
}
else if (desc == 0)
{
return 2;
len = to_wire(name);
- if (!blockdata_expand(addr.rr.u.block.rrdata, addr.rr.u.block.datalen, name, len))
+ if (!blockdata_expand(addr.rrblock.rrdata, addr.rrblock.datalen, name, len))
return 0;
- addr.rr.u.block.datalen += len;
+ addr.rrblock.datalen += len;
}
else
{
/* desc is length of a block of data to be used as-is */
if (desc > endrr - p1)
desc = endrr - p1;
- if (!blockdata_expand(addr.rr.u.block.rrdata, addr.rr.u.block.datalen, (char *)p1, desc))
+ if (!blockdata_expand(addr.rrblock.rrdata, addr.rrblock.datalen, (char *)p1, desc))
return 0;
- addr.rr.u.block.datalen += desc;
+ addr.rrblock.datalen += desc;
p1 += desc;
}
} while (desc != -1);
ttl = cttl;
if (flags & F_RR)
- addr.rr.rrtype = qtype;
+ addr.rrdata.rrtype = qtype;
newc = cache_insert(name, &addr, C_IN, now, ttl, F_FORWARD | F_NEG | flags | (secure ? F_DNSSECOK : 0));
if (newc && cpp)
do
{
int flags = crecp->flags;
+ unsigned short rrtype;
+
+ if (flags & F_KEYTAG)
+ rrtype = crecp->addr.rrblock.rrtype;
+ else
+ rrtype = crecp->addr.rrdata.rrtype;
- if ((flags & F_NXDOMAIN) || crecp->addr.rr.rrtype == qtype)
+ if ((flags & F_NXDOMAIN) || rrtype == qtype)
{
if (crec_isstale(crecp, now))
{
if (!dryrun)
{
- char *rrdata = crecp->addr.rr.u.data;
- unsigned short rrlen = crecp->addr.rr.len;
-
+ char *rrdata = NULL;
+ unsigned short rrlen = 0;
+
if (!(flags & F_NEG))
{
- if (crecp->addr.rr.len == -1)
+ if (flags & F_KEYTAG)
+ {
+ rrlen = crecp->addr.rrblock.datalen;
+ rrdata = blockdata_retrieve(crecp->addr.rrblock.rrdata, crecp->addr.rrblock.datalen, NULL);
+ }
+ else
{
- rrlen = crecp->addr.rr.u.block.datalen;
- rrdata = blockdata_retrieve(crecp->addr.rr.u.block.rrdata, crecp->addr.rr.u.block.datalen, NULL);
+ rrlen = crecp->addr.rrdata.datalen;
+ rrdata = crecp->addr.rrdata.data;
}
-
- if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
- crec_ttl(crecp, now), NULL, qtype, C_IN, "t",
- rrlen, rrdata))
- anscount++;
}
+ if (!(flags & F_NEG) && add_resource_record(header, limit, &trunc, nameoffset, &ansp,
+ crec_ttl(crecp, now), NULL, qtype, C_IN, "t",
+ rrlen, rrdata))
+ anscount++;
+
/* log after cache insertion as log_txt mangles rrdata */
if (qtype == T_TXT && !(crecp->flags & F_NEG))
log_txt(name, (unsigned char *)rrdata, rrlen, crecp->flags & F_DNSSECOK);