Tidy address-union handling: move class into explicit argument.

This moves the class argument to cache-insert into an argument,
rather then overloading a union in the address argument. Note that
tha class is NOT stored in the cache other than for DS/DNSKEY entries,
so must always be C_IN except for these. The data-extraction code
ensures this as it only attempts to cache C_IN class records.
This commit is contained in:
Simon Kelley
2018-12-31 23:56:33 +00:00
parent bde46476ee
commit 65a01b71bb
4 changed files with 34 additions and 50 deletions

View File

@@ -26,7 +26,7 @@ static union bigname *big_free = NULL;
static int bignames_left, hash_size; static int bignames_left, hash_size;
static void make_non_terminals(struct crec *source); static void make_non_terminals(struct crec *source);
static struct crec *really_insert(char *name, struct all_addr *addr, static struct crec *really_insert(char *name, struct all_addr *addr, unsigned short class,
time_t now, unsigned long ttl, unsigned short flags); time_t now, unsigned long ttl, unsigned short flags);
/* type->string mapping: this is also used by the name-hash function as a mixing table. */ /* type->string mapping: this is also used by the name-hash function as a mixing table. */
@@ -330,8 +330,8 @@ static int is_expired(time_t now, struct crec *crecp)
return 1; return 1;
} }
static struct crec *cache_scan_free(char *name, struct all_addr *addr, time_t now, unsigned short flags, static struct crec *cache_scan_free(char *name, struct all_addr *addr, unsigned short class, time_t now,
struct crec **target_crec, unsigned int *target_uid) unsigned short flags, struct crec **target_crec, unsigned int *target_uid)
{ {
/* Scan and remove old entries. /* Scan and remove old entries.
If (flags & F_FORWARD) then remove any forward entries for name and any expired If (flags & F_FORWARD) then remove any forward entries for name and any expired
@@ -350,6 +350,8 @@ static struct crec *cache_scan_free(char *name, struct all_addr *addr, time_t no
This entry will get re-used with the same name, to preserve CNAMEs. */ This entry will get re-used with the same name, to preserve CNAMEs. */
struct crec *crecp, **up; struct crec *crecp, **up;
(void)class;
if (flags & F_FORWARD) if (flags & F_FORWARD)
{ {
@@ -381,7 +383,7 @@ static struct crec *cache_scan_free(char *name, struct all_addr *addr, time_t no
#ifdef HAVE_DNSSEC #ifdef HAVE_DNSSEC
/* Deletion has to be class-sensitive for DS and DNSKEY */ /* Deletion has to be class-sensitive for DS and DNSKEY */
if ((flags & crecp->flags & (F_DNSKEY | F_DS)) && crecp->uid == addr->addr.dnssec.class) if ((flags & crecp->flags & (F_DNSKEY | F_DS)) && crecp->uid == class)
{ {
if (crecp->flags & F_CONFIG) if (crecp->flags & F_CONFIG)
return crecp; return crecp;
@@ -464,7 +466,7 @@ void cache_start_insert(void)
insert_error = 0; insert_error = 0;
} }
struct crec *cache_insert(char *name, struct all_addr *addr, struct crec *cache_insert(char *name, struct all_addr *addr, unsigned short class,
time_t now, unsigned long ttl, unsigned short flags) time_t now, unsigned long ttl, unsigned short flags)
{ {
/* Don't log DNSSEC records here, done elsewhere */ /* Don't log DNSSEC records here, done elsewhere */
@@ -478,11 +480,11 @@ struct crec *cache_insert(char *name, struct all_addr *addr,
ttl = daemon->min_cache_ttl; ttl = daemon->min_cache_ttl;
} }
return really_insert(name, addr, now, ttl, flags); return really_insert(name, addr, class, now, ttl, flags);
} }
static struct crec *really_insert(char *name, struct all_addr *addr, static struct crec *really_insert(char *name, struct all_addr *addr, unsigned short class,
time_t now, unsigned long ttl, unsigned short flags) time_t now, unsigned long ttl, unsigned short flags)
{ {
struct crec *new, *target_crec = NULL; struct crec *new, *target_crec = NULL;
@@ -497,7 +499,7 @@ static struct crec *really_insert(char *name, struct all_addr *addr,
/* First remove any expired entries and entries for the name/address we /* First remove any expired entries and entries for the name/address we
are currently inserting. */ are currently inserting. */
if ((new = cache_scan_free(name, addr, now, flags, &target_crec, &target_uid))) if ((new = cache_scan_free(name, addr, class, now, flags, &target_crec, &target_uid)))
{ {
/* We're trying to insert a record over one from /* We're trying to insert a record over one from
/etc/hosts or DHCP, or other config. If the /etc/hosts or DHCP, or other config. If the
@@ -553,21 +555,14 @@ static struct crec *really_insert(char *name, struct all_addr *addr,
if (freed_all) if (freed_all)
{ {
struct all_addr free_addr = new->addr.addr;; /* For DNSSEC records, uid holds class. */
#ifdef HAVE_DNSSEC
/* For DNSSEC records, addr holds class. */
if (new->flags & (F_DS | F_DNSKEY))
free_addr.addr.dnssec.class = new->uid;
#endif
free_avail = 1; /* Must be free space now. */ free_avail = 1; /* Must be free space now. */
cache_scan_free(cache_get_name(new), &free_addr, now, new->flags, NULL, NULL); cache_scan_free(cache_get_name(new), &new->addr.addr, new->uid, now, new->flags, NULL, NULL);
daemon->metrics[METRIC_DNS_CACHE_LIVE_FREED]++; daemon->metrics[METRIC_DNS_CACHE_LIVE_FREED]++;
} }
else else
{ {
cache_scan_free(NULL, NULL, now, 0, NULL, NULL); cache_scan_free(NULL, NULL, class, now, 0, NULL, NULL);
freed_all = 1; freed_all = 1;
} }
} }
@@ -615,15 +610,13 @@ static struct crec *really_insert(char *name, struct all_addr *addr,
else else
*cache_get_name(new) = 0; *cache_get_name(new) = 0;
if (addr)
{
#ifdef HAVE_DNSSEC #ifdef HAVE_DNSSEC
if (flags & (F_DS | F_DNSKEY)) if (flags & (F_DS | F_DNSKEY))
new->uid = addr->addr.dnssec.class; new->uid = class;
else
#endif #endif
new->addr.addr = *addr;
} if (addr)
new->addr.addr = *addr;
new->ttd = now + (time_t)ttl; new->ttd = now + (time_t)ttl;
new->next = new_chain; new->next = new_chain;
@@ -747,11 +740,11 @@ int cache_recv_insert(time_t now, int fd)
{ {
if (!read_write(fd, (unsigned char *)&addr, sizeof(addr), 1)) if (!read_write(fd, (unsigned char *)&addr, sizeof(addr), 1))
return 0; return 0;
crecp = really_insert(daemon->namebuff, &addr, now, ttl, flags); crecp = really_insert(daemon->namebuff, &addr, C_IN, now, ttl, flags);
} }
else if (flags & F_CNAME) else if (flags & F_CNAME)
{ {
struct crec *newc = really_insert(daemon->namebuff, NULL, now, ttl, flags); struct crec *newc = really_insert(daemon->namebuff, NULL, C_IN, now, ttl, flags);
/* This relies on the fact the the target of a CNAME immediately preceeds /* This relies on the fact the the target of a CNAME immediately preceeds
it because of the order of extraction in extract_addresses, and it because of the order of extraction in extract_addresses, and
the order reversal on the new_chain. */ the order reversal on the new_chain. */
@@ -780,10 +773,8 @@ int cache_recv_insert(time_t now, int fd)
if (!read_write(fd, (unsigned char *)&class, sizeof(class), 1)) if (!read_write(fd, (unsigned char *)&class, sizeof(class), 1))
return 0; return 0;
/* Cache needs to known class for DNSSEC stuff */
addr.addr.dnssec.class = class; crecp = really_insert(daemon->namebuff, NULL, class, now, ttl, flags);
crecp = really_insert(daemon->namebuff, &addr, now, ttl, flags);
if (flags & F_DNSKEY) if (flags & F_DNSKEY)
{ {
@@ -1463,7 +1454,7 @@ void cache_add_dhcp_entry(char *host_name, int prot,
} }
else if (!(crec->flags & F_DHCP)) else if (!(crec->flags & F_DHCP))
{ {
cache_scan_free(host_name, NULL, 0, crec->flags & (flags | F_CNAME | F_FORWARD), NULL, NULL); cache_scan_free(host_name, NULL, C_IN, 0, crec->flags & (flags | F_CNAME | F_FORWARD), NULL, NULL);
/* scan_free deletes all addresses associated with name */ /* scan_free deletes all addresses associated with name */
break; break;
} }
@@ -1490,7 +1481,7 @@ void cache_add_dhcp_entry(char *host_name, int prot,
if (crec->flags & F_NEG) if (crec->flags & F_NEG)
{ {
flags |= F_REVERSE; flags |= F_REVERSE;
cache_scan_free(NULL, (struct all_addr *)host_address, 0, flags, NULL, NULL); cache_scan_free(NULL, (struct all_addr *)host_address, C_IN, 0, flags, NULL, NULL);
} }
} }
else else

View File

@@ -1144,7 +1144,7 @@ struct crec *cache_find_by_name(struct crec *crecp,
void cache_end_insert(void); void cache_end_insert(void);
void cache_start_insert(void); void cache_start_insert(void);
int cache_recv_insert(time_t now, int fd); int cache_recv_insert(time_t now, int fd);
struct crec *cache_insert(char *name, struct all_addr *addr, struct crec *cache_insert(char *name, struct all_addr *addr, unsigned short class,
time_t now, unsigned long ttl, unsigned short flags); time_t now, unsigned long ttl, unsigned short flags);
void cache_reload(void); void cache_reload(void);
void cache_add_dhcp_entry(char *host_name, int prot, struct all_addr *host_address, time_t ttd); void cache_add_dhcp_entry(char *host_name, int prot, struct all_addr *host_address, time_t ttd);

View File

@@ -798,12 +798,9 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
algo = *p++; algo = *p++;
keytag = dnskey_keytag(algo, flags, p, rdlen - 4); keytag = dnskey_keytag(algo, flags, p, rdlen - 4);
/* Cache needs to known class for DNSSEC stuff */
a.addr.dnssec.class = class;
if ((key = blockdata_alloc((char*)p, rdlen - 4))) if ((key = blockdata_alloc((char*)p, rdlen - 4)))
{ {
if (!(recp1 = cache_insert(name, &a, now, ttl, F_FORWARD | F_DNSKEY | F_DNSSECOK))) if (!(recp1 = cache_insert(name, &a, class, now, ttl, F_FORWARD | F_DNSKEY | F_DNSSECOK)))
{ {
blockdata_free(key); blockdata_free(key);
return STAT_BOGUS; return STAT_BOGUS;
@@ -927,12 +924,9 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
algo = *p++; algo = *p++;
digest = *p++; digest = *p++;
/* Cache needs to known class for DNSSEC stuff */
a.addr.dnssec.class = class;
if ((key = blockdata_alloc((char*)p, rdlen - 4))) if ((key = blockdata_alloc((char*)p, rdlen - 4)))
{ {
if (!(crecp = cache_insert(name, &a, now, ttl, F_FORWARD | F_DS | F_DNSSECOK))) if (!(crecp = cache_insert(name, NULL, class, now, ttl, F_FORWARD | F_DS | F_DNSSECOK)))
{ {
blockdata_free(key); blockdata_free(key);
return STAT_BOGUS; return STAT_BOGUS;
@@ -1021,8 +1015,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
{ {
cache_start_insert(); cache_start_insert();
a.addr.dnssec.class = class; if (!cache_insert(name, NULL, class, now, ttl, flags))
if (!cache_insert(name, &a, now, ttl, flags))
return STAT_BOGUS; return STAT_BOGUS;
cache_end_insert(); cache_end_insert();

View File

@@ -701,7 +701,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
goto cname_loop; goto cname_loop;
} }
cache_insert(name, &addr, now, cttl, name_encoding | secflag | F_REVERSE); cache_insert(name, &addr, C_IN, now, cttl, name_encoding | secflag | F_REVERSE);
found = 1; found = 1;
} }
@@ -719,7 +719,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
ttl = find_soa(header, qlen, NULL, doctored); ttl = find_soa(header, qlen, NULL, doctored);
} }
if (ttl) if (ttl)
cache_insert(NULL, &addr, now, ttl, name_encoding | F_REVERSE | F_NEG | flags | (secure ? F_DNSSECOK : 0)); cache_insert(NULL, &addr, C_IN, now, ttl, name_encoding | F_REVERSE | F_NEG | flags | (secure ? F_DNSSECOK : 0));
} }
} }
else else
@@ -773,7 +773,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
{ {
if (!cname_count--) if (!cname_count--)
return 0; /* looped CNAMES */ return 0; /* looped CNAMES */
newc = cache_insert(name, NULL, now, attl, F_CNAME | F_FORWARD | secflag); newc = cache_insert(name, NULL, C_IN, now, attl, F_CNAME | F_FORWARD | secflag);
if (newc) if (newc)
{ {
newc->addr.cname.target.cache = NULL; newc->addr.cname.target.cache = NULL;
@@ -833,7 +833,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
} }
#endif #endif
newc = cache_insert(name, &addr, now, attl, flags | F_FORWARD | secflag); newc = cache_insert(name, &addr, C_IN, now, attl, flags | F_FORWARD | secflag);
if (newc && cpp) if (newc && cpp)
{ {
next_uid(newc); next_uid(newc);
@@ -860,7 +860,7 @@ int extract_addresses(struct dns_header *header, size_t qlen, char *name, time_t
pointing at this, inherit its TTL */ pointing at this, inherit its TTL */
if (ttl || cpp) if (ttl || cpp)
{ {
newc = cache_insert(name, NULL, now, ttl ? ttl : cttl, F_FORWARD | F_NEG | flags | (secure ? F_DNSSECOK : 0)); newc = cache_insert(name, NULL, C_IN, now, ttl ? ttl : cttl, F_FORWARD | F_NEG | flags | (secure ? F_DNSSECOK : 0));
if (newc && cpp) if (newc && cpp)
{ {
next_uid(newc); next_uid(newc);
@@ -1054,7 +1054,7 @@ int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
/* Found a bogus address. Insert that info here, since there no SOA record /* Found a bogus address. Insert that info here, since there no SOA record
to get the ttl from in the normal processing */ to get the ttl from in the normal processing */
cache_start_insert(); cache_start_insert();
cache_insert(name, NULL, now, ttl, F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN); cache_insert(name, NULL, C_IN, now, ttl, F_IPV4 | F_FORWARD | F_NEG | F_NXDOMAIN);
cache_end_insert(); cache_end_insert();
return 1; return 1;