mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-10-29 12:50:47 +00:00
Add --cache-rr to enable caching of arbitrary RR types.
This commit is contained in:
9 files changed
+416
-174
No files matched your search
+37
-8
@@ -29,6 +29,7 @@ static void make_non_terminals(struct crec *source);
|
||||
static struct crec *really_insert(char *name, union all_addr *addr, unsigned short class,
|
||||
time_t now, unsigned long ttl, unsigned int flags);
|
||||
static void dump_cache_entry(struct crec *cache, time_t now);
|
||||
static char *querystr(char *desc, unsigned short type);
|
||||
|
||||
/* type->string mapping: this is also used by the name-hash function as a mixing table. */
|
||||
/* taken from https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml */
|
||||
@@ -133,6 +134,17 @@ static void cache_link(struct crec *crecp);
|
||||
static void rehash(int size);
|
||||
static void cache_hash(struct crec *crecp);
|
||||
|
||||
unsigned short rrtype(char *in)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < (sizeof(typestr)/sizeof(typestr[0])); i++)
|
||||
if (strcasecmp(in, typestr[i].name) == 0)
|
||||
return typestr[i].type;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void next_uid(struct crec *crecp)
|
||||
{
|
||||
static unsigned int uid = 0;
|
||||
@@ -265,6 +277,8 @@ static void cache_blockdata_free(struct crec *crecp)
|
||||
{
|
||||
if (crecp->flags & F_SRV)
|
||||
blockdata_free(crecp->addr.srv.target);
|
||||
else if (crecp->flags & F_RR)
|
||||
blockdata_free(crecp->addr.rr.rrdata);
|
||||
#ifdef HAVE_DNSSEC
|
||||
else if (crecp->flags & F_DNSKEY)
|
||||
blockdata_free(crecp->addr.key.keydata);
|
||||
@@ -459,7 +473,8 @@ static struct crec *cache_scan_free(char *name, union all_addr *addr, unsigned s
|
||||
{
|
||||
/* Don't delete DNSSEC in favour of a CNAME, they can co-exist */
|
||||
if ((flags & crecp->flags & (F_IPV4 | F_IPV6 | F_SRV | F_NXDOMAIN)) ||
|
||||
(((crecp->flags | flags) & F_CNAME) && !(crecp->flags & (F_DNSKEY | F_DS))))
|
||||
(((crecp->flags | flags) & F_CNAME) && !(crecp->flags & (F_DNSKEY | F_DS))) ||
|
||||
((crecp->flags & flags & F_RR) && addr->rr.rrtype == crecp->addr.rr.rrtype))
|
||||
{
|
||||
if (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG))
|
||||
return crecp;
|
||||
@@ -776,7 +791,7 @@ void cache_end_insert(void)
|
||||
read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->ttd, sizeof(new_chain->ttd), 0);
|
||||
read_write(daemon->pipe_to_parent, (unsigned char *)&flags, sizeof(flags), 0);
|
||||
|
||||
if (flags & (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS | F_SRV))
|
||||
if (flags & (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS | F_SRV | F_RR))
|
||||
read_write(daemon->pipe_to_parent, (unsigned char *)&new_chain->addr, sizeof(new_chain->addr), 0);
|
||||
if (flags & F_SRV)
|
||||
{
|
||||
@@ -784,6 +799,12 @@ void cache_end_insert(void)
|
||||
if (!(flags & F_NEG))
|
||||
blockdata_write(new_chain->addr.srv.target, new_chain->addr.srv.targetlen, daemon->pipe_to_parent);
|
||||
}
|
||||
if (flags & F_RR)
|
||||
{
|
||||
/* A negative RR entry is possible and has no data, obviously. */
|
||||
if (!(flags & F_NEG))
|
||||
blockdata_write(new_chain->addr.rr.rrdata, new_chain->addr.rr.datalen, daemon->pipe_to_parent);
|
||||
}
|
||||
#ifdef HAVE_DNSSEC
|
||||
if (flags & F_DNSKEY)
|
||||
{
|
||||
@@ -848,16 +869,18 @@ int cache_recv_insert(time_t now, int fd)
|
||||
|
||||
ttl = difftime(ttd, now);
|
||||
|
||||
if (flags & (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS | F_SRV))
|
||||
if (flags & (F_IPV4 | F_IPV6 | F_DNSKEY | F_DS | F_SRV | F_RR))
|
||||
{
|
||||
unsigned short class = C_IN;
|
||||
|
||||
|
||||
if (!read_write(fd, (unsigned char *)&addr, sizeof(addr), 1))
|
||||
return 0;
|
||||
|
||||
|
||||
if ((flags & F_SRV) && !(flags & F_NEG) && !(addr.srv.target = blockdata_read(fd, addr.srv.targetlen)))
|
||||
return 0;
|
||||
|
||||
|
||||
if ((flags & F_RR) && !(flags & F_NEG) && !(addr.rr.rrdata = blockdata_read(fd, addr.rr.datalen)))
|
||||
return 0;
|
||||
#ifdef HAVE_DNSSEC
|
||||
if (flags & F_DNSKEY)
|
||||
{
|
||||
@@ -1587,7 +1610,7 @@ static void make_non_terminals(struct crec *source)
|
||||
if (!is_outdated_cname_pointer(crecp) &&
|
||||
(crecp->flags & F_FORWARD) &&
|
||||
(crecp->flags & type) &&
|
||||
!(crecp->flags & (F_IPV4 | F_IPV6 | F_CNAME | F_SRV | F_DNSKEY | F_DS)) &&
|
||||
!(crecp->flags & (F_IPV4 | F_IPV6 | F_CNAME | F_SRV | F_DNSKEY | F_DS | F_RR)) &&
|
||||
hostname_isequal(name, cache_get_name(crecp)))
|
||||
{
|
||||
*up = crecp->hash_next;
|
||||
@@ -1644,7 +1667,7 @@ static void make_non_terminals(struct crec *source)
|
||||
|
||||
if (crecp)
|
||||
{
|
||||
crecp->flags = (source->flags | F_NAMEP) & ~(F_IPV4 | F_IPV6 | F_CNAME | F_SRV | F_DNSKEY | F_DS | F_REVERSE);
|
||||
crecp->flags = (source->flags | F_NAMEP) & ~(F_IPV4 | F_IPV6 | F_CNAME | F_SRV | F_RR | F_DNSKEY | F_DS | F_REVERSE);
|
||||
if (!(crecp->flags & F_IMMORTAL))
|
||||
crecp->ttd = source->ttd;
|
||||
crecp->name.namep = name;
|
||||
@@ -1792,6 +1815,8 @@ static void dump_cache_entry(struct crec *cache, time_t now)
|
||||
blockdata_retrieve(cache->addr.srv.target, targetlen, a + len);
|
||||
a[len + targetlen] = 0;
|
||||
}
|
||||
else if (cache->flags & F_RR)
|
||||
sprintf(a, "%s", querystr(NULL, cache->addr.rr.rrtype));
|
||||
#ifdef HAVE_DNSSEC
|
||||
else if (cache->flags & F_DS)
|
||||
{
|
||||
@@ -1820,6 +1845,8 @@ static void dump_cache_entry(struct crec *cache, time_t now)
|
||||
t = "C";
|
||||
else if (cache->flags & F_SRV)
|
||||
t = "V";
|
||||
else if (cache->flags & F_RR)
|
||||
t = "T";
|
||||
#ifdef HAVE_DNSSEC
|
||||
else if (cache->flags & F_DS)
|
||||
t = "S";
|
||||
@@ -2078,6 +2105,8 @@ 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;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user