From 65a01b71bb433c9466e4c78a73a8d8ed218ed4e8 Mon Sep 17 00:00:00 2001 From: Simon Kelley Date: Mon, 31 Dec 2018 23:56:33 +0000 Subject: [PATCH 19/32] 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. Signed-off-by: Kevin Darbyshire-Bryant --- src/cache.c | 57 ++++++++++++++++++++++----------------------------- src/dnsmasq.h | 2 +- src/dnssec.c | 13 +++--------- src/rfc1035.c | 12 +++++------ 4 files changed, 34 insertions(+), 50 deletions(-) --- a/src/cache.c +++ b/src/cache.c @@ -26,7 +26,7 @@ static union bigname *big_free = NULL; static int bignames_left, hash_size; 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); /* 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 return 1; } -static struct crec *cache_scan_free(char *name, struct all_addr *addr, time_t now, unsigned short flags, - struct crec **target_crec, unsigned int *target_uid) +static struct crec *cache_scan_free(char *name, struct all_addr *addr, unsigned short class, time_t now, + unsigned short flags, struct crec **target_crec, unsigned int *target_uid) { /* Scan and remove old entries. 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 This entry will get re-used with the same name, to preserve CNAMEs. */ struct crec *crecp, **up; + + (void)class; if (flags & F_FORWARD) { @@ -381,7 +383,7 @@ static struct crec *cache_scan_free(char #ifdef HAVE_DNSSEC /* 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) return crecp; @@ -464,7 +466,7 @@ void cache_start_insert(void) 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) { /* Don't log DNSSEC records here, done elsewhere */ @@ -478,11 +480,11 @@ struct crec *cache_insert(char *name, st 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) { struct crec *new, *target_crec = NULL; @@ -497,7 +499,7 @@ static struct crec *really_insert(char * /* First remove any expired entries and entries for the name/address we 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 /etc/hosts or DHCP, or other config. If the @@ -553,21 +555,14 @@ static struct crec *really_insert(char * if (freed_all) { - struct all_addr free_addr = new->addr.addr;; - -#ifdef HAVE_DNSSEC - /* For DNSSEC records, addr holds class. */ - if (new->flags & (F_DS | F_DNSKEY)) - free_addr.addr.dnssec.class = new->uid; -#endif - + /* For DNSSEC records, uid holds class. */ 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]++; } else { - cache_scan_free(NULL, NULL, now, 0, NULL, NULL); + cache_scan_free(NULL, NULL, class, now, 0, NULL, NULL); freed_all = 1; } } @@ -615,15 +610,13 @@ static struct crec *really_insert(char * else *cache_get_name(new) = 0; - if (addr) - { #ifdef HAVE_DNSSEC - if (flags & (F_DS | F_DNSKEY)) - new->uid = addr->addr.dnssec.class; - else + if (flags & (F_DS | F_DNSKEY)) + new->uid = class; #endif - new->addr.addr = *addr; - } + + if (addr) + new->addr.addr = *addr; new->ttd = now + (time_t)ttl; 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)) 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) { - 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 it because of the order of extraction in extract_addresses, and 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)) return 0; - /* Cache needs to known class for DNSSEC stuff */ - addr.addr.dnssec.class = class; - - crecp = really_insert(daemon->namebuff, &addr, now, ttl, flags); + + crecp = really_insert(daemon->namebuff, NULL, class, now, ttl, flags); if (flags & F_DNSKEY) { @@ -1463,7 +1454,7 @@ void cache_add_dhcp_entry(char *host_nam } 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 */ break; } @@ -1490,7 +1481,7 @@ void cache_add_dhcp_entry(char *host_nam if (crec->flags & F_NEG) { 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 --- a/src/dnsmasq.h +++ b/src/dnsmasq.h @@ -1144,7 +1144,7 @@ struct crec *cache_find_by_name(struct c void cache_end_insert(void); void cache_start_insert(void); 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); void cache_reload(void); void cache_add_dhcp_entry(char *host_name, int prot, struct all_addr *host_address, time_t ttd); --- a/src/dnssec.c +++ b/src/dnssec.c @@ -798,12 +798,9 @@ int dnssec_validate_by_ds(time_t now, st algo = *p++; 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 (!(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); return STAT_BOGUS; @@ -927,12 +924,9 @@ int dnssec_validate_ds(time_t now, struc algo = *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 (!(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); return STAT_BOGUS; @@ -1021,8 +1015,7 @@ int dnssec_validate_ds(time_t now, struc { cache_start_insert(); - a.addr.dnssec.class = class; - if (!cache_insert(name, &a, now, ttl, flags)) + if (!cache_insert(name, NULL, class, now, ttl, flags)) return STAT_BOGUS; cache_end_insert(); --- a/src/rfc1035.c +++ b/src/rfc1035.c @@ -701,7 +701,7 @@ int extract_addresses(struct dns_header 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; } @@ -719,7 +719,7 @@ int extract_addresses(struct dns_header ttl = find_soa(header, qlen, NULL, doctored); } 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 @@ -773,7 +773,7 @@ int extract_addresses(struct dns_header { if (!cname_count--) 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) { newc->addr.cname.target.cache = NULL; @@ -833,7 +833,7 @@ int extract_addresses(struct dns_header } #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) { next_uid(newc); @@ -860,7 +860,7 @@ int extract_addresses(struct dns_header pointing at this, inherit its TTL */ 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) { next_uid(newc); @@ -1054,7 +1054,7 @@ int check_for_bogus_wildcard(struct dns_ /* Found a bogus address. Insert that info here, since there no SOA record to get the ttl from in the normal processing */ 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(); return 1;