diff options
Diffstat (limited to 'package/network/services/dnsmasq/patches/0021-Remove-nested-struct-union-in-cache-records-and-all_.patch')
-rw-r--r-- | package/network/services/dnsmasq/patches/0021-Remove-nested-struct-union-in-cache-records-and-all_.patch | 2316 |
1 files changed, 2316 insertions, 0 deletions
diff --git a/package/network/services/dnsmasq/patches/0021-Remove-nested-struct-union-in-cache-records-and-all_.patch b/package/network/services/dnsmasq/patches/0021-Remove-nested-struct-union-in-cache-records-and-all_.patch new file mode 100644 index 0000000000..4377cc1562 --- /dev/null +++ b/package/network/services/dnsmasq/patches/0021-Remove-nested-struct-union-in-cache-records-and-all_.patch @@ -0,0 +1,2316 @@ +From cc921df9ceac79acf9f1c477d015a3d88275422d Mon Sep 17 00:00:00 2001 +From: Simon Kelley <simon@thekelleys.org.uk> +Date: Wed, 2 Jan 2019 22:48:59 +0000 +Subject: [PATCH 21/30] Remove nested struct/union in cache records and + all_addr. + +Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> +--- + src/arp.c | 18 ++++----- + src/auth.c | 36 ++++++++--------- + src/bpf.c | 10 ++--- + src/cache.c | 98 +++++++++++++++++++++++----------------------- + src/conntrack.c | 6 +-- + src/dbus.c | 24 ++++++------ + src/dhcp-common.c | 14 +++---- + src/dhcp.c | 20 +++++----- + src/dhcp6.c | 2 +- + src/dnsmasq.c | 6 +-- + src/dnsmasq.h | 99 ++++++++++++++++++++++++----------------------- + src/dnssec.c | 56 +++++++++++++-------------- + src/domain.c | 32 +++++++-------- + src/forward.c | 88 ++++++++++++++++++++--------------------- + src/helper.c | 6 +-- + src/ipset.c | 10 ++--- + src/lease.c | 22 +++++------ + src/network.c | 36 ++++++++--------- + src/option.c | 16 ++++---- + src/rfc1035.c | 46 +++++++++++----------- + src/rfc3315.c | 12 +++--- + src/tables.c | 6 +-- + src/tftp.c | 8 ++-- + 23 files changed, 336 insertions(+), 335 deletions(-) + +--- a/src/arp.c ++++ b/src/arp.c +@@ -28,7 +28,7 @@ struct arp_record { + unsigned short hwlen, status; + int family; + unsigned char hwaddr[DHCP_CHADDR_MAX]; +- struct all_addr addr; ++ union all_addr addr; + struct arp_record *next; + }; + +@@ -52,12 +52,12 @@ static int filter_mac(int family, char * + + if (family == AF_INET) + { +- if (arp->addr.addr.addr4.s_addr != ((struct in_addr *)addrp)->s_addr) ++ if (arp->addr.addr4.s_addr != ((struct in_addr *)addrp)->s_addr) + continue; + } + else + { +- if (!IN6_ARE_ADDR_EQUAL(&arp->addr.addr.addr6, (struct in6_addr *)addrp)) ++ if (!IN6_ARE_ADDR_EQUAL(&arp->addr.addr6, (struct in6_addr *)addrp)) + continue; + } + +@@ -95,9 +95,9 @@ static int filter_mac(int family, char * + arp->family = family; + memcpy(arp->hwaddr, mac, maclen); + if (family == AF_INET) +- arp->addr.addr.addr4.s_addr = ((struct in_addr *)addrp)->s_addr; ++ arp->addr.addr4.s_addr = ((struct in_addr *)addrp)->s_addr; + else +- memcpy(&arp->addr.addr.addr6, addrp, IN6ADDRSZ); ++ memcpy(&arp->addr.addr6, addrp, IN6ADDRSZ); + } + + return 1; +@@ -124,11 +124,11 @@ int find_mac(union mysockaddr *addr, uns + continue; + + if (arp->family == AF_INET && +- arp->addr.addr.addr4.s_addr != addr->in.sin_addr.s_addr) ++ arp->addr.addr4.s_addr != addr->in.sin_addr.s_addr) + continue; + + if (arp->family == AF_INET6 && +- !IN6_ARE_ADDR_EQUAL(&arp->addr.addr.addr6, &addr->in6.sin6_addr)) ++ !IN6_ARE_ADDR_EQUAL(&arp->addr.addr6, &addr->in6.sin6_addr)) + continue; + + /* Only accept positive entries unless in lazy mode. */ +@@ -191,9 +191,9 @@ int find_mac(union mysockaddr *addr, uns + arp->hwlen = 0; + + if (addr->sa.sa_family == AF_INET) +- arp->addr.addr.addr4.s_addr = addr->in.sin_addr.s_addr; ++ arp->addr.addr4.s_addr = addr->in.sin_addr.s_addr; + else +- memcpy(&arp->addr.addr.addr6, &addr->in6.sin6_addr, IN6ADDRSZ); ++ memcpy(&arp->addr.addr6, &addr->in6.sin6_addr, IN6ADDRSZ); + } + + return 0; +--- a/src/auth.c ++++ b/src/auth.c +@@ -18,22 +18,22 @@ + + #ifdef HAVE_AUTH + +-static struct addrlist *find_addrlist(struct addrlist *list, int flag, struct all_addr *addr_u) ++static struct addrlist *find_addrlist(struct addrlist *list, int flag, union all_addr *addr_u) + { + do { + if (!(list->flags & ADDRLIST_IPV6)) + { +- struct in_addr netmask, addr = addr_u->addr.addr4; ++ struct in_addr netmask, addr = addr_u->addr4; + + if (!(flag & F_IPV4)) + continue; + + netmask.s_addr = htonl(~(in_addr_t)0 << (32 - list->prefixlen)); + +- if (is_same_net(addr, list->addr.addr.addr4, netmask)) ++ if (is_same_net(addr, list->addr.addr4, netmask)) + return list; + } +- else if (is_same_net6(&(addr_u->addr.addr6), &list->addr.addr.addr6, list->prefixlen)) ++ else if (is_same_net6(&(addr_u->addr6), &list->addr.addr6, list->prefixlen)) + return list; + + } while ((list = list->next)); +@@ -41,7 +41,7 @@ static struct addrlist *find_addrlist(st + return NULL; + } + +-static struct addrlist *find_subnet(struct auth_zone *zone, int flag, struct all_addr *addr_u) ++static struct addrlist *find_subnet(struct auth_zone *zone, int flag, union all_addr *addr_u) + { + if (!zone->subnet) + return NULL; +@@ -49,7 +49,7 @@ static struct addrlist *find_subnet(stru + return find_addrlist(zone->subnet, flag, addr_u); + } + +-static struct addrlist *find_exclude(struct auth_zone *zone, int flag, struct all_addr *addr_u) ++static struct addrlist *find_exclude(struct auth_zone *zone, int flag, union all_addr *addr_u) + { + if (!zone->exclude) + return NULL; +@@ -57,7 +57,7 @@ static struct addrlist *find_exclude(str + return find_addrlist(zone->exclude, flag, addr_u); + } + +-static int filter_zone(struct auth_zone *zone, int flag, struct all_addr *addr_u) ++static int filter_zone(struct auth_zone *zone, int flag, union all_addr *addr_u) + { + if (find_exclude(zone, flag, addr_u)) + return 0; +@@ -113,7 +113,7 @@ size_t answer_auth(struct dns_header *he + struct txt_record *txt; + struct interface_name *intr; + struct naptr *na; +- struct all_addr addr; ++ union all_addr addr; + struct cname *a, *candidate; + unsigned int wclen; + +@@ -178,7 +178,7 @@ size_t answer_auth(struct dns_header *he + struct addrlist *addrlist; + + for (addrlist = intr->addr; addrlist; addrlist = addrlist->next) +- if (!(addrlist->flags & ADDRLIST_IPV6) && addr.addr.addr4.s_addr == addrlist->addr.addr.addr4.s_addr) ++ if (!(addrlist->flags & ADDRLIST_IPV6) && addr.addr4.s_addr == addrlist->addr.addr4.s_addr) + break; + + if (addrlist) +@@ -193,7 +193,7 @@ size_t answer_auth(struct dns_header *he + struct addrlist *addrlist; + + for (addrlist = intr->addr; addrlist; addrlist = addrlist->next) +- if ((addrlist->flags & ADDRLIST_IPV6) && IN6_ARE_ADDR_EQUAL(&addr.addr.addr6, &addrlist->addr.addr.addr6)) ++ if ((addrlist->flags & ADDRLIST_IPV6) && IN6_ARE_ADDR_EQUAL(&addr.addr6, &addrlist->addr.addr6)) + break; + + if (addrlist) +@@ -468,10 +468,10 @@ size_t answer_auth(struct dns_header *he + { + nxdomain = 0; + if ((crecp->flags & flag) && +- (local_query || filter_zone(zone, flag, &(crecp->addr.addr)))) ++ (local_query || filter_zone(zone, flag, &(crecp->addr)))) + { + *cut = '.'; /* restore domain part */ +- log_query(crecp->flags, name, &crecp->addr.addr, record_source(crecp->uid)); ++ log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid)); + *cut = 0; /* remove domain part */ + found = 1; + if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, +@@ -491,9 +491,9 @@ size_t answer_auth(struct dns_header *he + do + { + nxdomain = 0; +- if ((crecp->flags & flag) && (local_query || filter_zone(zone, flag, &(crecp->addr.addr)))) ++ if ((crecp->flags & flag) && (local_query || filter_zone(zone, flag, &(crecp->addr)))) + { +- log_query(crecp->flags, name, &crecp->addr.addr, record_source(crecp->uid)); ++ log_query(crecp->flags, name, &crecp->addr, record_source(crecp->uid)); + found = 1; + if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, + daemon->auth_ttl, NULL, qtype, C_IN, +@@ -580,7 +580,7 @@ size_t answer_auth(struct dns_header *he + + if (!(subnet->flags & ADDRLIST_IPV6)) + { +- in_addr_t a = ntohl(subnet->addr.addr.addr4.s_addr) >> 8; ++ in_addr_t a = ntohl(subnet->addr.addr4.s_addr) >> 8; + char *p = name; + + if (subnet->prefixlen >= 24) +@@ -599,7 +599,7 @@ size_t answer_auth(struct dns_header *he + + for (i = subnet->prefixlen-1; i >= 0; i -= 4) + { +- int dig = ((unsigned char *)&subnet->addr.addr.addr6)[i>>3]; ++ int dig = ((unsigned char *)&subnet->addr.addr6)[i>>3]; + p += sprintf(p, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4); + } + p += sprintf(p, "ip6.arpa"); +@@ -783,7 +783,7 @@ size_t answer_auth(struct dns_header *he + { + char *cache_name = cache_get_name(crecp); + if (!strchr(cache_name, '.') && +- (local_query || filter_zone(zone, (crecp->flags & (F_IPV6 | F_IPV4)), &(crecp->addr.addr))) && ++ (local_query || filter_zone(zone, (crecp->flags & (F_IPV6 | F_IPV4)), &(crecp->addr))) && + add_resource_record(header, limit, &trunc, -axfroffset, &ansp, + daemon->auth_ttl, NULL, (crecp->flags & F_IPV6) ? T_AAAA : T_A, C_IN, + (crecp->flags & F_IPV4) ? "4" : "6", cache_name, &crecp->addr)) +@@ -794,7 +794,7 @@ size_t answer_auth(struct dns_header *he + { + strcpy(name, cache_get_name(crecp)); + if (in_zone(zone, name, &cut) && +- (local_query || filter_zone(zone, (crecp->flags & (F_IPV6 | F_IPV4)), &(crecp->addr.addr)))) ++ (local_query || filter_zone(zone, (crecp->flags & (F_IPV6 | F_IPV4)), &(crecp->addr)))) + { + if (cut) + *cut = 0; +--- a/src/bpf.c ++++ b/src/bpf.c +@@ -42,7 +42,7 @@ + + #ifdef HAVE_BSD_NETWORK + static int del_family = 0; +-static struct all_addr del_addr; ++static union all_addr del_addr; + #endif + + #if defined(HAVE_BSD_NETWORK) && !defined(__APPLE__) +@@ -139,7 +139,7 @@ int iface_enumerate(int family, void *pa + struct in_addr addr, netmask, broadcast; + addr = ((struct sockaddr_in *) addrs->ifa_addr)->sin_addr; + #ifdef HAVE_BSD_NETWORK +- if (del_family == AF_INET && del_addr.addr.addr4.s_addr == addr.s_addr) ++ if (del_family == AF_INET && del_addr.addr4.s_addr == addr.s_addr) + continue; + #endif + netmask = ((struct sockaddr_in *) addrs->ifa_netmask)->sin_addr; +@@ -159,7 +159,7 @@ int iface_enumerate(int family, void *pa + u32 valid = 0xffffffff, preferred = 0xffffffff; + int flags = 0; + #ifdef HAVE_BSD_NETWORK +- if (del_family == AF_INET6 && IN6_ARE_ADDR_EQUAL(&del_addr.addr.addr6, addr)) ++ if (del_family == AF_INET6 && IN6_ARE_ADDR_EQUAL(&del_addr.addr6, addr)) + continue; + #endif + #if defined(HAVE_BSD_NETWORK) && !defined(__APPLE__) +@@ -422,9 +422,9 @@ void route_sock(void) + { + del_family = sa->sa_family; + if (del_family == AF_INET) +- del_addr.addr.addr4 = ((struct sockaddr_in *)sa)->sin_addr; ++ del_addr.addr4 = ((struct sockaddr_in *)sa)->sin_addr; + else if (del_family == AF_INET6) +- del_addr.addr.addr6 = ((struct sockaddr_in6 *)sa)->sin6_addr; ++ del_addr.addr6 = ((struct sockaddr_in6 *)sa)->sin6_addr; + else + del_family = 0; + } +--- 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, unsigned short class, ++static struct crec *really_insert(char *name, union 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. */ +@@ -202,9 +202,9 @@ static void cache_hash(struct crec *crec + static void cache_blockdata_free(struct crec *crecp) + { + if (crecp->flags & F_DNSKEY) +- blockdata_free(crecp->addr.addr.addr.key.keydata); ++ blockdata_free(crecp->addr.key.keydata); + else if ((crecp->flags & F_DS) && !(crecp->flags & F_NEG)) +- blockdata_free(crecp->addr.addr.addr.ds.keydata); ++ blockdata_free(crecp->addr.ds.keydata); + } + #endif + +@@ -330,7 +330,7 @@ static int is_expired(time_t now, struct + return 1; + } + +-static struct crec *cache_scan_free(char *name, struct all_addr *addr, unsigned short class, time_t now, ++static struct crec *cache_scan_free(char *name, union 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. +@@ -430,7 +430,7 @@ static struct crec *cache_scan_free(char + else if (!(crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) && + (flags & crecp->flags & F_REVERSE) && + (flags & crecp->flags & (F_IPV4 | F_IPV6)) && +- memcmp(&crecp->addr.addr, addr, addrlen) == 0) ++ memcmp(&crecp->addr, addr, addrlen) == 0) + { + *up = crecp->hash_next; + cache_unlink(crecp); +@@ -466,7 +466,7 @@ void cache_start_insert(void) + insert_error = 0; + } + +-struct crec *cache_insert(char *name, struct all_addr *addr, unsigned short class, ++struct crec *cache_insert(char *name, union all_addr *addr, unsigned short class, + time_t now, unsigned long ttl, unsigned short flags) + { + /* Don't log DNSSEC records here, done elsewhere */ +@@ -484,7 +484,7 @@ struct crec *cache_insert(char *name, st + } + + +-static struct crec *really_insert(char *name, struct all_addr *addr, unsigned short class, ++static struct crec *really_insert(char *name, union all_addr *addr, unsigned short class, + time_t now, unsigned long ttl, unsigned short flags) + { + struct crec *new, *target_crec = NULL; +@@ -509,10 +509,10 @@ static struct crec *really_insert(char * + if ((flags & (F_IPV4 | F_IPV6)) && (flags & F_FORWARD) && addr) + { + if ((flags & F_IPV4) && (new->flags & F_IPV4) && +- new->addr.addr.addr.addr4.s_addr == addr->addr.addr4.s_addr) ++ new->addr.addr4.s_addr == addr->addr4.s_addr) + return new; + else if ((flags & F_IPV6) && (new->flags & F_IPV6) && +- IN6_ARE_ADDR_EQUAL(&new->addr.addr.addr.addr6, &addr->addr.addr6)) ++ IN6_ARE_ADDR_EQUAL(&new->addr.addr6, &addr->addr6)) + return new; + } + +@@ -557,7 +557,7 @@ static struct crec *really_insert(char * + { + /* For DNSSEC records, uid holds class. */ + free_avail = 1; /* Must be free space now. */ +- cache_scan_free(cache_get_name(new), &new->addr.addr, new->uid, now, new->flags, NULL, NULL); ++ cache_scan_free(cache_get_name(new), &new->addr, new->uid, now, new->flags, NULL, NULL); + daemon->metrics[METRIC_DNS_CACHE_LIVE_FREED]++; + } + else +@@ -616,7 +616,7 @@ static struct crec *really_insert(char * + #endif + + if (addr) +- new->addr.addr = *addr; ++ new->addr = *addr; + + new->ttd = now + (time_t)ttl; + new->next = new_chain; +@@ -665,14 +665,14 @@ void cache_end_insert(void) + if (flags & F_DNSKEY) + { + read_write(daemon->pipe_to_parent, (unsigned char *)&class, sizeof(class), 0); +- blockdata_write(new_chain->addr.addr.addr.key.keydata, new_chain->addr.addr.addr.key.keylen, daemon->pipe_to_parent); ++ blockdata_write(new_chain->addr.key.keydata, new_chain->addr.key.keylen, daemon->pipe_to_parent); + } + else if (flags & F_DS) + { + read_write(daemon->pipe_to_parent, (unsigned char *)&class, sizeof(class), 0); + /* A negative DS entry is possible and has no data, obviously. */ + if (!(flags & F_NEG)) +- blockdata_write(new_chain->addr.addr.addr.ds.keydata, new_chain->addr.addr.addr.ds.keylen, daemon->pipe_to_parent); ++ blockdata_write(new_chain->addr.ds.keydata, new_chain->addr.ds.keylen, daemon->pipe_to_parent); + } + #endif + } +@@ -696,7 +696,7 @@ void cache_end_insert(void) + int cache_recv_insert(time_t now, int fd) + { + ssize_t m; +- struct all_addr addr; ++ union all_addr addr; + unsigned long ttl; + time_t ttd; + unsigned short flags; +@@ -736,14 +736,14 @@ int cache_recv_insert(time_t now, int fd + if (flags & F_DNSKEY) + { + if (!read_write(fd, (unsigned char *)&class, sizeof(class), 1) || +- !(addr.addr.key.keydata = blockdata_read(fd, addr.addr.key.keylen))) ++ !(addr.key.keydata = blockdata_read(fd, addr.key.keylen))) + return 0; + } + else if (flags & F_DS) + { + if (!read_write(fd, (unsigned char *)&class, sizeof(class), 1) || + (flags & F_NEG) || +- !(addr.addr.key.keydata = blockdata_read(fd, addr.addr.key.keylen))) ++ !(addr.key.keydata = blockdata_read(fd, addr.key.keylen))) + return 0; + } + #endif +@@ -876,7 +876,7 @@ struct crec *cache_find_by_name(struct c + return NULL; + } + +-struct crec *cache_find_by_addr(struct crec *crecp, struct all_addr *addr, ++struct crec *cache_find_by_addr(struct crec *crecp, union all_addr *addr, + time_t now, unsigned int prot) + { + struct crec *ans; +@@ -900,7 +900,7 @@ struct crec *cache_find_by_addr(struct c + if (!is_expired(now, crecp)) + { + if ((crecp->flags & prot) && +- memcmp(&crecp->addr.addr, addr, addrlen) == 0) ++ memcmp(&crecp->addr, addr, addrlen) == 0) + { + if (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG)) + { +@@ -931,7 +931,7 @@ struct crec *cache_find_by_addr(struct c + if (ans && + (ans->flags & F_REVERSE) && + (ans->flags & prot) && +- memcmp(&ans->addr.addr, addr, addrlen) == 0) ++ memcmp(&ans->addr, addr, addrlen) == 0) + return ans; + + return NULL; +@@ -961,7 +961,7 @@ static void add_hosts_cname(struct crec + } + } + +-static void add_hosts_entry(struct crec *cache, struct all_addr *addr, int addrlen, ++static void add_hosts_entry(struct crec *cache, union all_addr *addr, int addrlen, + unsigned int index, struct crec **rhash, int hashsz) + { + struct crec *lookup = cache_find_by_name(NULL, cache_get_name(cache), 0, cache->flags & (F_IPV4 | F_IPV6)); +@@ -972,7 +972,7 @@ static void add_hosts_entry(struct crec + if (lookup && (lookup->flags & F_HOSTS)) + { + nameexists = 1; +- if (memcmp(&lookup->addr.addr, addr, addrlen) == 0) ++ if (memcmp(&lookup->addr, addr, addrlen) == 0) + { + free(cache); + return; +@@ -1004,7 +1004,7 @@ static void add_hosts_entry(struct crec + + for (lookup = rhash[j]; lookup; lookup = lookup->next) + if ((lookup->flags & cache->flags & (F_IPV4 | F_IPV6)) && +- memcmp(&lookup->addr.addr, addr, addrlen) == 0) ++ memcmp(&lookup->addr, addr, addrlen) == 0) + { + cache->flags &= ~F_REVERSE; + break; +@@ -1026,7 +1026,7 @@ static void add_hosts_entry(struct crec + } + + cache->uid = index; +- memcpy(&cache->addr.addr, addr, addrlen); ++ memcpy(&cache->addr, addr, addrlen); + cache_hash(cache); + make_non_terminals(cache); + +@@ -1088,7 +1088,7 @@ int read_hostsfile(char *filename, unsig + char *token = daemon->namebuff, *domain_suffix = NULL; + int addr_count = 0, name_count = cache_size, lineno = 0; + unsigned short flags = 0; +- struct all_addr addr; ++ union all_addr addr; + int atnl, addrlen = 0; + + if (!f) +@@ -1107,13 +1107,13 @@ int read_hostsfile(char *filename, unsig + { + flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV4; + addrlen = INADDRSZ; +- domain_suffix = get_domain(addr.addr.addr4); ++ domain_suffix = get_domain(addr.addr4); + } + else if (inet_pton(AF_INET6, token, &addr) > 0) + { + flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV6; + addrlen = IN6ADDRSZ; +- domain_suffix = get_domain6(&addr.addr.addr6); ++ domain_suffix = get_domain6(&addr.addr6); + } + else + { +@@ -1246,15 +1246,15 @@ void cache_reload(void) + #ifdef HAVE_DNSSEC + for (ds = daemon->ds; ds; ds = ds->next) + if ((cache = whine_malloc(SIZEOF_POINTER_CREC)) && +- (cache->addr.addr.addr.ds.keydata = blockdata_alloc(ds->digest, ds->digestlen))) ++ (cache->addr.ds.keydata = blockdata_alloc(ds->digest, ds->digestlen))) + { + cache->flags = F_FORWARD | F_IMMORTAL | F_DS | F_CONFIG | F_NAMEP; + cache->ttd = daemon->local_ttl; + cache->name.namep = ds->name; +- cache->addr.addr.addr.ds.keylen = ds->digestlen; +- cache->addr.addr.addr.ds.algo = ds->algo; +- cache->addr.addr.addr.ds.keytag = ds->keytag; +- cache->addr.addr.addr.ds.digest = ds->digest_type; ++ cache->addr.ds.keylen = ds->digestlen; ++ cache->addr.ds.algo = ds->algo; ++ cache->addr.ds.keytag = ds->keytag; ++ cache->addr.ds.digest = ds->digest_type; + cache->uid = ds->class; + cache_hash(cache); + make_non_terminals(cache); +@@ -1277,7 +1277,7 @@ void cache_reload(void) + cache->name.namep = nl->name; + cache->ttd = hr->ttl; + cache->flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV4 | F_NAMEP | F_CONFIG; +- add_hosts_entry(cache, (struct all_addr *)&hr->addr, INADDRSZ, SRC_CONFIG, (struct crec **)daemon->packet, revhashsz); ++ add_hosts_entry(cache, (union all_addr *)&hr->addr, INADDRSZ, SRC_CONFIG, (struct crec **)daemon->packet, revhashsz); + } + + if (!IN6_IS_ADDR_UNSPECIFIED(&hr->addr6) && +@@ -1286,7 +1286,7 @@ void cache_reload(void) + cache->name.namep = nl->name; + cache->ttd = hr->ttl; + cache->flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV6 | F_NAMEP | F_CONFIG; +- add_hosts_entry(cache, (struct all_addr *)&hr->addr6, IN6ADDRSZ, SRC_CONFIG, (struct crec **)daemon->packet, revhashsz); ++ add_hosts_entry(cache, (union all_addr *)&hr->addr6, IN6ADDRSZ, SRC_CONFIG, (struct crec **)daemon->packet, revhashsz); + } + } + +@@ -1320,7 +1320,7 @@ struct in_addr a_record_from_hosts(char + + while ((crecp = cache_find_by_name(crecp, name, now, F_IPV4))) + if (crecp->flags & F_HOSTS) +- return *(struct in_addr *)&crecp->addr; ++ return crecp->addr.addr4; + + my_syslog(MS_DHCP | LOG_WARNING, _("No IPv4 address found for %s"), name); + +@@ -1379,7 +1379,7 @@ static void add_dhcp_cname(struct crec * + } + + void cache_add_dhcp_entry(char *host_name, int prot, +- struct all_addr *host_address, time_t ttd) ++ union all_addr *host_address, time_t ttd) + { + struct crec *crec = NULL, *fail_crec = NULL; + unsigned short flags = F_IPV4; +@@ -1403,7 +1403,7 @@ void cache_add_dhcp_entry(char *host_nam + my_syslog(MS_DHCP | LOG_WARNING, + _("%s is a CNAME, not giving it to the DHCP lease of %s"), + host_name, daemon->addrbuff); +- else if (memcmp(&crec->addr.addr, host_address, addrlen) == 0) ++ else if (memcmp(&crec->addr, host_address, addrlen) == 0) + in_hosts = 1; + else + fail_crec = crec; +@@ -1423,7 +1423,7 @@ void cache_add_dhcp_entry(char *host_nam + /* Name in hosts, address doesn't match */ + if (fail_crec) + { +- inet_ntop(prot, &fail_crec->addr.addr, daemon->namebuff, MAXDNAME); ++ inet_ntop(prot, &fail_crec->addr, daemon->namebuff, MAXDNAME); + my_syslog(MS_DHCP | LOG_WARNING, + _("not giving name %s to the DHCP lease of %s because " + "the name exists in %s with address %s"), +@@ -1432,12 +1432,12 @@ void cache_add_dhcp_entry(char *host_nam + return; + } + +- if ((crec = cache_find_by_addr(NULL, (struct all_addr *)host_address, 0, flags))) ++ if ((crec = cache_find_by_addr(NULL, (union all_addr *)host_address, 0, flags))) + { + if (crec->flags & F_NEG) + { + flags |= F_REVERSE; +- cache_scan_free(NULL, (struct all_addr *)host_address, C_IN, 0, flags, NULL, NULL); ++ cache_scan_free(NULL, (union all_addr *)host_address, C_IN, 0, flags, NULL, NULL); + } + } + else +@@ -1455,7 +1455,7 @@ void cache_add_dhcp_entry(char *host_nam + crec->flags |= F_IMMORTAL; + else + crec->ttd = ttd; +- crec->addr.addr = *host_address; ++ crec->addr = *host_address; + crec->name.namep = host_name; + crec->uid = UID_NONE; + cache_hash(crec); +@@ -1731,20 +1731,20 @@ void dump_cache(time_t now) + else if (cache->flags & F_DS) + { + if (!(cache->flags & F_NEG)) +- sprintf(a, "%5u %3u %3u", cache->addr.addr.addr.ds.keytag, +- cache->addr.addr.addr.ds.algo, cache->addr.addr.addr.ds.digest); ++ sprintf(a, "%5u %3u %3u", cache->addr.ds.keytag, ++ cache->addr.ds.algo, cache->addr.ds.digest); + } + else if (cache->flags & F_DNSKEY) +- sprintf(a, "%5u %3u %3u", cache->addr.addr.addr.key.keytag, +- cache->addr.addr.addr.key.algo, cache->addr.addr.addr.key.flags); ++ sprintf(a, "%5u %3u %3u", cache->addr.key.keytag, ++ cache->addr.key.algo, cache->addr.key.flags); + #endif + else if (!(cache->flags & F_NEG) || !(cache->flags & F_FORWARD)) + { + a = daemon->addrbuff; + if (cache->flags & F_IPV4) +- inet_ntop(AF_INET, &cache->addr.addr, a, ADDRSTRLEN); ++ inet_ntop(AF_INET, &cache->addr, a, ADDRSTRLEN); + else if (cache->flags & F_IPV6) +- inet_ntop(AF_INET6, &cache->addr.addr, a, ADDRSTRLEN); ++ inet_ntop(AF_INET6, &cache->addr, a, ADDRSTRLEN); + } + + if (cache->flags & F_IPV4) +@@ -1857,7 +1857,7 @@ char *querystr(char *desc, unsigned shor + return buff ? buff : ""; + } + +-void log_query(unsigned int flags, char *name, struct all_addr *addr, char *arg) ++void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg) + { + char *source, *dest = daemon->addrbuff; + char *verb = "is"; +@@ -1870,10 +1870,10 @@ void log_query(unsigned int flags, char + if (addr) + { + if (flags & F_KEYTAG) +- sprintf(daemon->addrbuff, arg, addr->addr.log.keytag, addr->addr.log.algo, addr->addr.log.digest); ++ sprintf(daemon->addrbuff, arg, addr->log.keytag, addr->log.algo, addr->log.digest); + else if (flags & F_RCODE) + { +- unsigned int rcode = addr->addr.log.rcode; ++ unsigned int rcode = addr->log.rcode; + + if (rcode == SERVFAIL) + dest = "SERVFAIL"; +--- a/src/conntrack.c ++++ b/src/conntrack.c +@@ -24,7 +24,7 @@ static int gotit = 0; /* yuck */ + + static int callback(enum nf_conntrack_msg_type type, struct nf_conntrack *ct, void *data); + +-int get_incoming_mark(union mysockaddr *peer_addr, struct all_addr *local_addr, int istcp, unsigned int *markp) ++int get_incoming_mark(union mysockaddr *peer_addr, union all_addr *local_addr, int istcp, unsigned int *markp) + { + struct nf_conntrack *ct; + struct nfct_handle *h; +@@ -41,14 +41,14 @@ int get_incoming_mark(union mysockaddr * + nfct_set_attr_u8(ct, ATTR_L3PROTO, AF_INET6); + nfct_set_attr(ct, ATTR_IPV6_SRC, peer_addr->in6.sin6_addr.s6_addr); + nfct_set_attr_u16(ct, ATTR_PORT_SRC, peer_addr->in6.sin6_port); +- nfct_set_attr(ct, ATTR_IPV6_DST, local_addr->addr.addr6.s6_addr); ++ nfct_set_attr(ct, ATTR_IPV6_DST, local_addr->addr6.s6_addr); + } + else + { + nfct_set_attr_u8(ct, ATTR_L3PROTO, AF_INET); + nfct_set_attr_u32(ct, ATTR_IPV4_SRC, peer_addr->in.sin_addr.s_addr); + nfct_set_attr_u16(ct, ATTR_PORT_SRC, peer_addr->in.sin_port); +- nfct_set_attr_u32(ct, ATTR_IPV4_DST, local_addr->addr.addr4.s_addr); ++ nfct_set_attr_u32(ct, ATTR_IPV4_DST, local_addr->addr4.s_addr); + } + + +--- a/src/dbus.c ++++ b/src/dbus.c +@@ -456,7 +456,7 @@ static DBusMessage *dbus_add_lease(DBusM + int clid_len, hostname_len, hw_len, hw_type; + dbus_uint32_t expires, ia_id; + dbus_bool_t is_temporary; +- struct all_addr addr; ++ union all_addr addr; + time_t now = dnsmasq_time(); + unsigned char dhcp_chaddr[DHCP_CHADDR_MAX]; + +@@ -526,20 +526,20 @@ static DBusMessage *dbus_add_lease(DBusM + + dbus_message_iter_get_basic(&iter, &is_temporary); + +- if (inet_pton(AF_INET, ipaddr, &addr.addr.addr4)) ++ if (inet_pton(AF_INET, ipaddr, &addr.addr4)) + { + if (ia_id != 0 || is_temporary) + return dbus_message_new_error(message, DBUS_ERROR_INVALID_ARGS, + "ia_id and is_temporary must be zero for IPv4 lease"); + +- if (!(lease = lease_find_by_addr(addr.addr.addr4))) +- lease = lease4_allocate(addr.addr.addr4); ++ if (!(lease = lease_find_by_addr(addr.addr4))) ++ lease = lease4_allocate(addr.addr4); + } + #ifdef HAVE_DHCP6 +- else if (inet_pton(AF_INET6, ipaddr, &addr.addr.addr6)) ++ else if (inet_pton(AF_INET6, ipaddr, &addr.addr6)) + { +- if (!(lease = lease6_find_by_addr(&addr.addr.addr6, 128, 0))) +- lease = lease6_allocate(&addr.addr.addr6, ++ if (!(lease = lease6_find_by_addr(&addr.addr6, 128, 0))) ++ lease = lease6_allocate(&addr.addr6, + is_temporary ? LEASE_TA : LEASE_NA); + lease_set_iaid(lease, ia_id); + } +@@ -570,7 +570,7 @@ static DBusMessage *dbus_del_lease(DBusM + DBusMessageIter iter; + const char *ipaddr; + DBusMessage *reply; +- struct all_addr addr; ++ union all_addr addr; + dbus_bool_t ret = 1; + time_t now = dnsmasq_time(); + +@@ -584,11 +584,11 @@ static DBusMessage *dbus_del_lease(DBusM + + dbus_message_iter_get_basic(&iter, &ipaddr); + +- if (inet_pton(AF_INET, ipaddr, &addr.addr.addr4)) +- lease = lease_find_by_addr(addr.addr.addr4); ++ if (inet_pton(AF_INET, ipaddr, &addr.addr4)) ++ lease = lease_find_by_addr(addr.addr4); + #ifdef HAVE_DHCP6 +- else if (inet_pton(AF_INET6, ipaddr, &addr.addr.addr6)) +- lease = lease6_find_by_addr(&addr.addr.addr6, 128, 0); ++ else if (inet_pton(AF_INET6, ipaddr, &addr.addr6)) ++ lease = lease6_find_by_addr(&addr.addr6, 128, 0); + #endif + else + return dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS, +--- a/src/dhcp-common.c ++++ b/src/dhcp-common.c +@@ -403,30 +403,30 @@ void dhcp_update_configs(struct dhcp_con + crec = cache_find_by_name(crec, config->hostname, 0, cacheflags); + if (!crec) + continue; /* should be never */ +- inet_ntop(prot, &crec->addr.addr, daemon->addrbuff, ADDRSTRLEN); ++ inet_ntop(prot, &crec->addr, daemon->addrbuff, ADDRSTRLEN); + my_syslog(MS_DHCP | LOG_WARNING, _("%s has more than one address in hostsfile, using %s for DHCP"), + config->hostname, daemon->addrbuff); + } + + if (prot == AF_INET && +- (!(conf_tmp = config_find_by_address(configs, crec->addr.addr.addr.addr4)) || conf_tmp == config)) ++ (!(conf_tmp = config_find_by_address(configs, crec->addr.addr4)) || conf_tmp == config)) + { +- config->addr = crec->addr.addr.addr.addr4; ++ config->addr = crec->addr.addr4; + config->flags |= CONFIG_ADDR | CONFIG_ADDR_HOSTS; + continue; + } + + #ifdef HAVE_DHCP6 + if (prot == AF_INET6 && +- (!(conf_tmp = config_find_by_address6(configs, &crec->addr.addr.addr.addr6, 128, 0)) || conf_tmp == config)) ++ (!(conf_tmp = config_find_by_address6(configs, &crec->addr.addr6, 128, 0)) || conf_tmp == config)) + { +- memcpy(&config->addr6, &crec->addr.addr.addr.addr6, IN6ADDRSZ); ++ memcpy(&config->addr6, &crec->addr.addr6, IN6ADDRSZ); + config->flags |= CONFIG_ADDR6 | CONFIG_ADDR_HOSTS; + continue; + } + #endif + +- inet_ntop(prot, &crec->addr.addr, daemon->addrbuff, ADDRSTRLEN); ++ inet_ntop(prot, &crec->addr, daemon->addrbuff, ADDRSTRLEN); + my_syslog(MS_DHCP | LOG_WARNING, _("duplicate IP address %s (%s) in dhcp-config directive"), + daemon->addrbuff, config->hostname); + +@@ -693,7 +693,7 @@ char *option_string(int prot, unsigned i + + if (ot[o].size & OT_ADDR_LIST) + { +- struct all_addr addr; ++ union all_addr addr; + int addr_len = INADDRSZ; + + #ifdef HAVE_DHCP6 +--- a/src/dhcp.c ++++ b/src/dhcp.c +@@ -310,7 +310,7 @@ void dhcp_packet(time_t now, int pxe_fd) + parm.relay_local.s_addr = 0; + parm.ind = iface_index; + +- if (!iface_check(AF_INET, (struct all_addr *)&iface_addr, ifr.ifr_name, NULL)) ++ if (!iface_check(AF_INET, (union all_addr *)&iface_addr, ifr.ifr_name, NULL)) + { + /* If we failed to match the primary address of the interface, see if we've got a --listen-address + for a secondary */ +@@ -558,7 +558,7 @@ static int complete_context(struct in_ad + } + + for (relay = daemon->relay4; relay; relay = relay->next) +- if (if_index == param->ind && relay->local.addr.addr4.s_addr == local.s_addr && relay->current == relay && ++ if (if_index == param->ind && relay->local.addr4.s_addr == local.s_addr && relay->current == relay && + (param->relay_local.s_addr == 0 || param->relay_local.s_addr == local.s_addr)) + { + relay->current = param->relay; +@@ -984,7 +984,7 @@ char *host_from_dns(struct in_addr addr) + if (daemon->port == 0) + return NULL; /* DNS disabled. */ + +- lookup = cache_find_by_addr(NULL, (struct all_addr *)&addr, 0, F_IPV4); ++ lookup = cache_find_by_addr(NULL, (union all_addr *)&addr, 0, F_IPV4); + + if (lookup && (lookup->flags & F_HOSTS)) + { +@@ -1013,25 +1013,25 @@ char *host_from_dns(struct in_addr addr) + static int relay_upstream4(struct dhcp_relay *relay, struct dhcp_packet *mess, size_t sz, int iface_index) + { + /* ->local is same value for all relays on ->current chain */ +- struct all_addr from; ++ union all_addr from; + + if (mess->op != BOOTREQUEST) + return 0; + + /* source address == relay address */ +- from.addr.addr4 = relay->local.addr.addr4; ++ from.addr4 = relay->local.addr4; + + /* already gatewayed ? */ + if (mess->giaddr.s_addr) + { + /* if so check if by us, to stomp on loops. */ +- if (mess->giaddr.s_addr == relay->local.addr.addr4.s_addr) ++ if (mess->giaddr.s_addr == relay->local.addr4.s_addr) + return 1; + } + else + { + /* plug in our address */ +- mess->giaddr.s_addr = relay->local.addr.addr4.s_addr; ++ mess->giaddr.s_addr = relay->local.addr4.s_addr; + } + + if ((mess->hops++) > 20) +@@ -1042,7 +1042,7 @@ static int relay_upstream4(struct dhcp_ + union mysockaddr to; + + to.sa.sa_family = AF_INET; +- to.in.sin_addr = relay->server.addr.addr4; ++ to.in.sin_addr = relay->server.addr4; + to.in.sin_port = htons(daemon->dhcp_server_port); + + send_from(daemon->dhcpfd, 0, (char *)mess, sz, &to, &from, 0); +@@ -1050,7 +1050,7 @@ static int relay_upstream4(struct dhcp_ + if (option_bool(OPT_LOG_OPTS)) + { + inet_ntop(AF_INET, &relay->local, daemon->addrbuff, ADDRSTRLEN); +- my_syslog(MS_DHCP | LOG_INFO, _("DHCP relay %s -> %s"), daemon->addrbuff, inet_ntoa(relay->server.addr.addr4)); ++ my_syslog(MS_DHCP | LOG_INFO, _("DHCP relay %s -> %s"), daemon->addrbuff, inet_ntoa(relay->server.addr4)); + } + + /* Save this for replies */ +@@ -1070,7 +1070,7 @@ static struct dhcp_relay *relay_reply4(s + + for (relay = daemon->relay4; relay; relay = relay->next) + { +- if (mess->giaddr.s_addr == relay->local.addr.addr4.s_addr) ++ if (mess->giaddr.s_addr == relay->local.addr4.s_addr) + { + if (!relay->interface || wildcard_match(relay->interface, arrival_interface)) + return relay->iface_index != 0 ? relay : NULL; +--- a/src/dhcp6.c ++++ b/src/dhcp6.c +@@ -371,7 +371,7 @@ static int complete_context6(struct in6_ + } + + for (relay = daemon->relay6; relay; relay = relay->next) +- if (IN6_ARE_ADDR_EQUAL(local, &relay->local.addr.addr6) && relay->current == relay && ++ if (IN6_ARE_ADDR_EQUAL(local, &relay->local.addr6) && relay->current == relay && + (IN6_IS_ADDR_UNSPECIFIED(¶m->relay_local) || IN6_ARE_ADDR_EQUAL(local, ¶m->relay_local))) + { + relay->current = param->relay; +--- a/src/dnsmasq.c ++++ b/src/dnsmasq.c +@@ -1721,12 +1721,12 @@ static void check_dns_listeners(time_t n + if ((if_index = tcp_interface(confd, tcp_addr.sa.sa_family)) != 0 && + indextoname(listener->tcpfd, if_index, intr_name)) + { +- struct all_addr addr; ++ union all_addr addr; + + if (tcp_addr.sa.sa_family == AF_INET6) +- addr.addr.addr6 = tcp_addr.in6.sin6_addr; ++ addr.addr6 = tcp_addr.in6.sin6_addr; + else +- addr.addr.addr4 = tcp_addr.in.sin_addr; ++ addr.addr4 = tcp_addr.in.sin_addr; + + for (iface = daemon->interfaces; iface; iface = iface->next) + if (iface->index == if_index) +--- a/src/dnsmasq.h ++++ b/src/dnsmasq.h +@@ -273,28 +273,39 @@ struct event_desc { + #define MS_DHCP LOG_DAEMON + #define MS_SCRIPT LOG_MAIL + +-struct all_addr { +- union { +- struct in_addr addr4; +- struct in6_addr addr6; +- struct { +- struct blockdata *keydata; +- unsigned short keylen, flags, keytag; +- unsigned char algo; +- } key; +- struct { +- struct blockdata *keydata; +- unsigned short keylen, keytag; +- unsigned char algo; +- unsigned char digest; +- } ds; +- /* for log_query */ +- struct { +- unsigned short keytag, algo, digest, rcode; +- } log; +- } addr; ++/* Note that this is used widely as a container for IPv4/IPv6 addresses, ++ so for that reason, was well as to avoid wasting memory in almost every ++ cache entry, the other variants should not be larger than ++ sizeof(struct in6_addr) - 16 bytes. ++*/ ++union all_addr { ++ struct in_addr addr4; ++ struct in6_addr addr6; ++ struct { ++ union { ++ struct crec *cache; ++ struct interface_name *int_name; ++ } target; ++ unsigned int uid; /* 0 if union is interface-name */ ++ } cname; ++ struct { ++ struct blockdata *keydata; ++ unsigned short keylen, flags, keytag; ++ unsigned char algo; ++ } key; ++ struct { ++ struct blockdata *keydata; ++ unsigned short keylen, keytag; ++ unsigned char algo; ++ unsigned char digest; ++ } ds; ++ /* for log_query */ ++ struct { ++ unsigned short keytag, algo, digest, rcode; ++ } log; + }; + ++ + struct bogus_addr { + struct in_addr addr; + struct bogus_addr *next; +@@ -359,7 +370,7 @@ struct ds_config { + #define ADDRLIST_REVONLY 4 + + struct addrlist { +- struct all_addr addr; ++ union all_addr addr; + int flags, prefixlen; + struct addrlist *next; + }; +@@ -411,17 +422,7 @@ struct blockdata { + + struct crec { + struct crec *next, *prev, *hash_next; +- /* union is 16 bytes when doing IPv6, 8 bytes on 32 bit machines without IPv6 */ +- union { +- struct all_addr addr; +- struct { +- union { +- struct crec *cache; +- struct interface_name *int_name; +- } target; +- unsigned int uid; /* 0 if union is interface-name */ +- } cname; +- } addr; ++ union all_addr addr; + time_t ttd; /* time to die */ + /* used as class if DNSKEY/DS, index to source for F_HOSTS */ + unsigned int uid; +@@ -646,7 +647,7 @@ struct hostsfile { + + struct frec { + union mysockaddr source; +- struct all_addr dest; ++ union all_addr dest; + struct server *sentto; /* NULL means free */ + struct randfd *rfd4; + struct randfd *rfd6; +@@ -962,7 +963,7 @@ struct tftp_prefix { + }; + + struct dhcp_relay { +- struct all_addr local, server; ++ union all_addr local, server; + char *interface; /* Allowable interface for replies from server, and dest for IPv6 multicast */ + int iface_index; /* working - interface in which requests arrived, for return */ + struct dhcp_relay *current, *next; +@@ -1128,22 +1129,22 @@ extern struct daemon { + /* cache.c */ + void cache_init(void); + void next_uid(struct crec *crecp); +-void log_query(unsigned int flags, char *name, struct all_addr *addr, char *arg); ++void log_query(unsigned int flags, char *name, union all_addr *addr, char *arg); + char *record_source(unsigned int index); + char *querystr(char *desc, unsigned short type); + int cache_find_non_terminal(char *name, time_t now); + struct crec *cache_find_by_addr(struct crec *crecp, +- struct all_addr *addr, time_t now, ++ union all_addr *addr, time_t now, + unsigned int prot); + struct crec *cache_find_by_name(struct crec *crecp, + char *name, time_t now, unsigned int prot); + 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, unsigned short class, ++struct crec *cache_insert(char *name, union 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); ++void cache_add_dhcp_entry(char *host_name, int prot, union all_addr *host_address, time_t ttd); + struct in_addr a_record_from_hosts(char *name, time_t now); + void cache_unhash_dhcp(void); + void dump_cache(time_t now); +@@ -1170,8 +1171,8 @@ void blockdata_free(struct blockdata *bl + /* domain.c */ + char *get_domain(struct in_addr addr); + char *get_domain6(struct in6_addr *addr); +-int is_name_synthetic(int flags, char *name, struct all_addr *addr); +-int is_rev_synth(int flag, struct all_addr *addr, char *name); ++int is_name_synthetic(int flags, char *name, union all_addr *addr); ++int is_rev_synth(int flag, union all_addr *addr, char *name); + + /* rfc1035.c */ + int extract_name(struct dns_header *header, size_t plen, unsigned char **pp, +@@ -1182,7 +1183,7 @@ unsigned char *skip_section(unsigned cha + unsigned int extract_request(struct dns_header *header, size_t qlen, + char *name, unsigned short *typep); + size_t setup_reply(struct dns_header *header, size_t qlen, +- struct all_addr *addrp, unsigned int flags, ++ union all_addr *addrp, unsigned int flags, + unsigned long ttl); + int extract_addresses(struct dns_header *header, size_t qlen, char *name, + time_t now, char **ipsets, int is_sign, int check_rebind, +@@ -1203,7 +1204,7 @@ int add_resource_record(struct dns_heade + unsigned char *skip_questions(struct dns_header *header, size_t plen); + int extract_name(struct dns_header *header, size_t plen, unsigned char **pp, + char *name, int isExtract, int extrabytes); +-int in_arpa_name_2_addr(char *namein, struct all_addr *addrp); ++int in_arpa_name_2_addr(char *namein, union all_addr *addrp); + int private_net(struct in_addr addr, int ban_localhost); + + /* auth.c */ +@@ -1302,7 +1303,7 @@ unsigned char *tcp_request(int confd, ti + void server_gone(struct server *server); + struct frec *get_new_frec(time_t now, int *wait, int force); + int send_from(int fd, int nowild, char *packet, size_t len, +- union mysockaddr *to, struct all_addr *source, ++ union mysockaddr *to, union all_addr *source, + unsigned int iface); + void resend_query(void); + struct randfd *allocate_rfd(int family); +@@ -1329,9 +1330,9 @@ void warn_bound_listeners(void); + void warn_wild_labels(void); + void warn_int_names(void); + int is_dad_listeners(void); +-int iface_check(int family, struct all_addr *addr, char *name, int *auth); +-int loopback_exception(int fd, int family, struct all_addr *addr, char *name); +-int label_exception(int index, int family, struct all_addr *addr); ++int iface_check(int family, union all_addr *addr, char *name, int *auth); ++int loopback_exception(int fd, int family, union all_addr *addr, char *name); ++int label_exception(int index, int family, union all_addr *addr); + int fix_fd(int fd); + int tcp_interface(int fd, int af); + int set_ipv6pktinfo(int fd); +@@ -1461,7 +1462,7 @@ void ubus_event_bcast(const char *type, + /* ipset.c */ + #ifdef HAVE_IPSET + void ipset_init(void); +-int add_to_ipset(const char *setname, const struct all_addr *ipaddr, int flags, int remove); ++int add_to_ipset(const char *setname, const union all_addr *ipaddr, int flags, int remove); + #endif + + /* helper.c */ +@@ -1474,7 +1475,7 @@ void queue_script(int action, struct dhc + void queue_tftp(off_t file_len, char *filename, union mysockaddr *peer); + #endif + void queue_arp(int action, unsigned char *mac, int maclen, +- int family, struct all_addr *addr); ++ int family, union all_addr *addr); + int helper_buf_empty(void); + #endif + +@@ -1487,7 +1488,7 @@ int do_tftp_script_run(void); + + /* conntrack.c */ + #ifdef HAVE_CONNTRACK +-int get_incoming_mark(union mysockaddr *peer_addr, struct all_addr *local_addr, ++int get_incoming_mark(union mysockaddr *peer_addr, union all_addr *local_addr, + int istcp, unsigned int *markp); + #endif + +--- a/src/dnssec.c ++++ b/src/dnssec.c +@@ -628,10 +628,10 @@ static int validate_rrset(time_t now, st + { + /* iterate through all possible keys 4035 5.3.1 */ + for (; crecp; crecp = cache_find_by_name(crecp, keyname, now, F_DNSKEY)) +- if (crecp->addr.addr.addr.key.algo == algo && +- crecp->addr.addr.addr.key.keytag == key_tag && ++ if (crecp->addr.key.algo == algo && ++ crecp->addr.key.keytag == key_tag && + crecp->uid == (unsigned int)class && +- verify(crecp->addr.addr.addr.key.keydata, crecp->addr.addr.addr.key.keylen, sig, sig_len, digest, hash->digest_size, algo)) ++ verify(crecp->addr.key.keydata, crecp->addr.key.keylen, sig, sig_len, digest, hash->digest_size, algo)) + return (labels < name_labels) ? STAT_SECURE_WILDCARD : STAT_SECURE; + } + } +@@ -655,7 +655,7 @@ int dnssec_validate_by_ds(time_t now, st + struct crec *crecp, *recp1; + int rc, j, qtype, qclass, ttl, rdlen, flags, algo, valid, keytag; + struct blockdata *key; +- struct all_addr a; ++ union all_addr a; + + if (ntohs(header->qdcount) != 1 || + !extract_name(header, plen, &p, name, 1, 4)) +@@ -728,10 +728,10 @@ int dnssec_validate_by_ds(time_t now, st + const struct nettle_hash *hash; + int sigcnt, rrcnt; + +- if (recp1->addr.addr.addr.ds.algo == algo && +- recp1->addr.addr.addr.ds.keytag == keytag && ++ if (recp1->addr.ds.algo == algo && ++ recp1->addr.ds.keytag == keytag && + recp1->uid == (unsigned int)class && +- (hash = hash_find(ds_digest_name(recp1->addr.addr.addr.ds.digest))) && ++ (hash = hash_find(ds_digest_name(recp1->addr.ds.digest))) && + hash_init(hash, &ctx, &digest)) + + { +@@ -746,9 +746,9 @@ int dnssec_validate_by_ds(time_t now, st + from_wire(name); + + if (!(recp1->flags & F_NEG) && +- recp1->addr.addr.addr.ds.keylen == (int)hash->digest_size && +- (ds_digest = blockdata_retrieve(recp1->addr.addr.addr.ds.keydata, recp1->addr.addr.addr.ds.keylen, NULL)) && +- memcmp(ds_digest, digest, recp1->addr.addr.addr.ds.keylen) == 0 && ++ recp1->addr.ds.keylen == (int)hash->digest_size && ++ (ds_digest = blockdata_retrieve(recp1->addr.ds.keydata, recp1->addr.ds.keylen, NULL)) && ++ memcmp(ds_digest, digest, recp1->addr.ds.keylen) == 0 && + explore_rrset(header, plen, class, T_DNSKEY, name, keyname, &sigcnt, &rrcnt) && + sigcnt != 0 && rrcnt != 0 && + validate_rrset(now, header, plen, class, T_DNSKEY, sigcnt, rrcnt, name, keyname, +@@ -800,11 +800,11 @@ int dnssec_validate_by_ds(time_t now, st + + if ((key = blockdata_alloc((char*)p, rdlen - 4))) + { +- a.addr.key.keylen = rdlen - 4; +- a.addr.key.keydata = key; +- a.addr.key.algo = algo; +- a.addr.key.keytag = keytag; +- a.addr.key.flags = flags; ++ a.key.keylen = rdlen - 4; ++ a.key.keydata = key; ++ a.key.algo = algo; ++ a.key.keytag = keytag; ++ a.key.flags = flags; + + if (!cache_insert(name, &a, class, now, ttl, F_FORWARD | F_DNSKEY | F_DNSSECOK)) + { +@@ -813,8 +813,8 @@ int dnssec_validate_by_ds(time_t now, st + } + else + { +- a.addr.log.keytag = keytag; +- a.addr.log.algo = algo; ++ a.log.keytag = keytag; ++ a.log.algo = algo; + if (algo_digest_name(algo)) + log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DNSKEY keytag %hu, algo %hu"); + else +@@ -857,7 +857,7 @@ int dnssec_validate_ds(time_t now, struc + int qtype, qclass, rc, i, neganswer, nons; + int aclass, atype, rdlen; + unsigned long ttl; +- struct all_addr a; ++ union all_addr a; + + if (ntohs(header->qdcount) != 1 || + !(p = skip_name(p, header, plen, 4))) +@@ -925,11 +925,11 @@ int dnssec_validate_ds(time_t now, struc + + if ((key = blockdata_alloc((char*)p, rdlen - 4))) + { +- a.addr.ds.digest = digest; +- a.addr.ds.keydata = key; +- a.addr.ds.algo = algo; +- a.addr.ds.keytag = keytag; +- a.addr.ds.keylen = rdlen - 4; ++ a.ds.digest = digest; ++ a.ds.keydata = key; ++ a.ds.algo = algo; ++ a.ds.keytag = keytag; ++ a.ds.keylen = rdlen - 4; + + if (!cache_insert(name, &a, class, now, ttl, F_FORWARD | F_DS | F_DNSSECOK)) + { +@@ -938,9 +938,9 @@ int dnssec_validate_ds(time_t now, struc + } + else + { +- a.addr.log.keytag = keytag; +- a.addr.log.algo = algo; +- a.addr.log.digest = digest; ++ a.log.keytag = keytag; ++ a.log.algo = algo; ++ a.log.digest = digest; + if (ds_digest_name(digest) && algo_digest_name(algo)) + log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %hu, algo %hu, digest %hu"); + else +@@ -1710,8 +1710,8 @@ static int zone_status(char *name, int c + do + { + if (crecp->uid == (unsigned int)class && +- ds_digest_name(crecp->addr.addr.addr.ds.digest) && +- algo_digest_name(crecp->addr.addr.addr.ds.algo)) ++ ds_digest_name(crecp->addr.ds.digest) && ++ algo_digest_name(crecp->addr.ds.algo)) + break; + } + while ((crecp = cache_find_by_name(crecp, keyname, now, F_DS))); +--- a/src/domain.c ++++ b/src/domain.c +@@ -21,7 +21,7 @@ static struct cond_domain *search_domain + static struct cond_domain *search_domain6(struct in6_addr *addr, struct cond_domain *c); + + +-int is_name_synthetic(int flags, char *name, struct all_addr *addr) ++int is_name_synthetic(int flags, char *name, union all_addr *addr) + { + char *p; + struct cond_domain *c = NULL; +@@ -73,7 +73,7 @@ int is_name_synthetic(int flags, char *n + if (!c->is6 && + index <= ntohl(c->end.s_addr) - ntohl(c->start.s_addr)) + { +- addr->addr.addr4.s_addr = htonl(ntohl(c->start.s_addr) + index); ++ addr->addr4.s_addr = htonl(ntohl(c->start.s_addr) + index); + found = 1; + } + } +@@ -85,8 +85,8 @@ int is_name_synthetic(int flags, char *n + index <= addr6part(&c->end6) - addr6part(&c->start6)) + { + u64 start = addr6part(&c->start6); +- addr->addr.addr6 = c->start6; +- setaddr6part(&addr->addr.addr6, start + index); ++ addr->addr6 = c->start6; ++ setaddr6part(&addr->addr6, start + index); + found = 1; + } + } +@@ -139,16 +139,16 @@ int is_name_synthetic(int flags, char *n + if (prot == AF_INET) + { + if (!c->is6 && +- ntohl(addr->addr.addr4.s_addr) >= ntohl(c->start.s_addr) && +- ntohl(addr->addr.addr4.s_addr) <= ntohl(c->end.s_addr)) ++ ntohl(addr->addr4.s_addr) >= ntohl(c->start.s_addr) && ++ ntohl(addr->addr4.s_addr) <= ntohl(c->end.s_addr)) + found = 1; + } + else + { +- u64 addrpart = addr6part(&addr->addr.addr6); ++ u64 addrpart = addr6part(&addr->addr6); + + if (c->is6 && +- is_same_net6(&addr->addr.addr6, &c->start6, 64) && ++ is_same_net6(&addr->addr6, &c->start6, 64) && + addrpart >= addr6part(&c->start6) && + addrpart <= addr6part(&c->end6)) + found = 1; +@@ -173,18 +173,18 @@ int is_name_synthetic(int flags, char *n + } + + +-int is_rev_synth(int flag, struct all_addr *addr, char *name) ++int is_rev_synth(int flag, union all_addr *addr, char *name) + { + struct cond_domain *c; + +- if (flag & F_IPV4 && (c = search_domain(addr->addr.addr4, daemon->synth_domains))) ++ if (flag & F_IPV4 && (c = search_domain(addr->addr4, daemon->synth_domains))) + { + char *p; + + *name = 0; + if (c->indexed) + { +- unsigned int index = ntohl(addr->addr.addr4.s_addr) - ntohl(c->start.s_addr); ++ unsigned int index = ntohl(addr->addr4.s_addr) - ntohl(c->start.s_addr); + snprintf(name, MAXDNAME, "%s%u", c->prefix ? c->prefix : "", index); + } + else +@@ -192,7 +192,7 @@ int is_rev_synth(int flag, struct all_ad + if (c->prefix) + strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN); + +- inet_ntop(AF_INET, &addr->addr.addr4, name + strlen(name), ADDRSTRLEN); ++ inet_ntop(AF_INET, &addr->addr4, name + strlen(name), ADDRSTRLEN); + for (p = name; *p; p++) + if (*p == '.') + *p = '-'; +@@ -204,14 +204,14 @@ int is_rev_synth(int flag, struct all_ad + return 1; + } + +- if ((flag & F_IPV6) && (c = search_domain6(&addr->addr.addr6, daemon->synth_domains))) ++ if ((flag & F_IPV6) && (c = search_domain6(&addr->addr6, daemon->synth_domains))) + { + char *p; + + *name = 0; + if (c->indexed) + { +- u64 index = addr6part(&addr->addr.addr6) - addr6part(&c->start6); ++ u64 index = addr6part(&addr->addr6) - addr6part(&c->start6); + snprintf(name, MAXDNAME, "%s%llu", c->prefix ? c->prefix : "", index); + } + else +@@ -219,14 +219,14 @@ int is_rev_synth(int flag, struct all_ad + if (c->prefix) + strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN); + +- inet_ntop(AF_INET6, &addr->addr.addr6, name + strlen(name), ADDRSTRLEN); ++ inet_ntop(AF_INET6, &addr->addr6, name + strlen(name), ADDRSTRLEN); + + /* IPv6 presentation address can start with ":", but valid domain names + cannot start with "-" so prepend a zero in that case. */ + if (!c->prefix && *name == ':') + { + *name = '0'; +- inet_ntop(AF_INET6, &addr->addr.addr6, name+1, ADDRSTRLEN); ++ inet_ntop(AF_INET6, &addr->addr6, name+1, ADDRSTRLEN); + } + + /* V4-mapped have periods.... */ +--- a/src/forward.c ++++ b/src/forward.c +@@ -26,7 +26,7 @@ static void free_frec(struct frec *f); + /* Send a UDP packet with its source address set as "source" + unless nowild is true, when we just send it with the kernel default */ + int send_from(int fd, int nowild, char *packet, size_t len, +- union mysockaddr *to, struct all_addr *source, ++ union mysockaddr *to, union all_addr *source, + unsigned int iface) + { + struct msghdr msg; +@@ -64,13 +64,13 @@ int send_from(int fd, int nowild, char * + #if defined(HAVE_LINUX_NETWORK) + struct in_pktinfo p; + p.ipi_ifindex = 0; +- p.ipi_spec_dst = source->addr.addr4; ++ p.ipi_spec_dst = source->addr4; + memcpy(CMSG_DATA(cmptr), &p, sizeof(p)); + msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); + cmptr->cmsg_level = IPPROTO_IP; + cmptr->cmsg_type = IP_PKTINFO; + #elif defined(IP_SENDSRCADDR) +- memcpy(CMSG_DATA(cmptr), &(source->addr.addr4), sizeof(source->addr.addr4)); ++ memcpy(CMSG_DATA(cmptr), &(source->addr4), sizeof(source->addr4)); + msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in_addr)); + cmptr->cmsg_level = IPPROTO_IP; + cmptr->cmsg_type = IP_SENDSRCADDR; +@@ -80,7 +80,7 @@ int send_from(int fd, int nowild, char * + { + struct in6_pktinfo p; + p.ipi6_ifindex = iface; /* Need iface for IPv6 to handle link-local addrs */ +- p.ipi6_addr = source->addr.addr6; ++ p.ipi6_addr = source->addr6; + memcpy(CMSG_DATA(cmptr), &p, sizeof(p)); + msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo)); + cmptr->cmsg_type = daemon->v6pktinfo; +@@ -100,7 +100,7 @@ int send_from(int fd, int nowild, char * + return 1; + } + +-static unsigned int search_servers(time_t now, struct all_addr **addrpp, unsigned int qtype, ++static unsigned int search_servers(time_t now, union all_addr **addrpp, unsigned int qtype, + char *qdomain, int *type, char **domain, int *norebind) + + { +@@ -112,7 +112,7 @@ static unsigned int search_servers(time_ + unsigned int matchlen = 0; + struct server *serv; + unsigned int flags = 0; +- static struct all_addr zero; ++ static union all_addr zero; + + for (serv = daemon->servers; serv; serv=serv->next) + if (qtype == F_DNSSECOK && !(serv->flags & SERV_DO_DNSSEC)) +@@ -137,9 +137,9 @@ static unsigned int search_servers(time_ + { + flags = sflag; + if (serv->addr.sa.sa_family == AF_INET) +- *addrpp = (struct all_addr *)&serv->addr.in.sin_addr; ++ *addrpp = (union all_addr *)&serv->addr.in.sin_addr; + else +- *addrpp = (struct all_addr *)&serv->addr.in6.sin6_addr; ++ *addrpp = (union all_addr *)&serv->addr.in6.sin6_addr; + } + else if (!flags || (flags & F_NXDOMAIN)) + flags = F_NOERR; +@@ -195,9 +195,9 @@ static unsigned int search_servers(time_ + { + flags = sflag; + if (serv->addr.sa.sa_family == AF_INET) +- *addrpp = (struct all_addr *)&serv->addr.in.sin_addr; ++ *addrpp = (union all_addr *)&serv->addr.in.sin_addr; + else +- *addrpp = (struct all_addr *)&serv->addr.in6.sin6_addr; ++ *addrpp = (union all_addr *)&serv->addr.in6.sin6_addr; + } + else if (!flags || (flags & F_NXDOMAIN)) + flags = F_NOERR; +@@ -239,13 +239,13 @@ static unsigned int search_servers(time_ + } + + static int forward_query(int udpfd, union mysockaddr *udpaddr, +- struct all_addr *dst_addr, unsigned int dst_iface, ++ union all_addr *dst_addr, unsigned int dst_iface, + struct dns_header *header, size_t plen, time_t now, + struct frec *forward, int ad_reqd, int do_bit) + { + char *domain = NULL; + int type = SERV_DO_DNSSEC, norebind = 0; +- struct all_addr *addrp = NULL; ++ union all_addr *addrp = NULL; + unsigned int flags = 0; + struct server *start = NULL; + #ifdef HAVE_DNSSEC +@@ -289,9 +289,9 @@ static int forward_query(int udpfd, unio + PUTSHORT(SAFE_PKTSZ, pheader); + + if (forward->sentto->addr.sa.sa_family == AF_INET) +- log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, "retry", (struct all_addr *)&forward->sentto->addr.in.sin_addr, "dnssec"); ++ log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, "retry", (union all_addr *)&forward->sentto->addr.in.sin_addr, "dnssec"); + else +- log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, "retry", (struct all_addr *)&forward->sentto->addr.in6.sin6_addr, "dnssec"); ++ log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, "retry", (union all_addr *)&forward->sentto->addr.in6.sin6_addr, "dnssec"); + + + if (forward->sentto->sfd) +@@ -523,10 +523,10 @@ static int forward_query(int udpfd, unio + strcpy(daemon->namebuff, "query"); + if (start->addr.sa.sa_family == AF_INET) + log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff, +- (struct all_addr *)&start->addr.in.sin_addr, NULL); ++ (union all_addr *)&start->addr.in.sin_addr, NULL); + else + log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff, +- (struct all_addr *)&start->addr.in6.sin6_addr, NULL); ++ (union all_addr *)&start->addr.in6.sin6_addr, NULL); + start->queries++; + forwarded = 1; + forward->sentto = start; +@@ -657,8 +657,8 @@ static size_t process_reply(struct dns_h + + if (rcode != NOERROR && rcode != NXDOMAIN) + { +- struct all_addr a; +- a.addr.log.rcode = rcode; ++ union all_addr a; ++ a.log.rcode = rcode; + log_query(F_UPSTREAM | F_RCODE, "error", &a, NULL); + + return resize_packet(header, n, pheader, plen); +@@ -877,9 +877,9 @@ void reply_query(int fd, int family, tim + sa_len(&start->addr)))); + + if (start->addr.sa.sa_family == AF_INET) +- log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, "retry", (struct all_addr *)&start->addr.in.sin_addr, "dnssec"); ++ log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, "retry", (union all_addr *)&start->addr.in.sin_addr, "dnssec"); + else +- log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, "retry", (struct all_addr *)&start->addr.in6.sin6_addr, "dnssec"); ++ log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, "retry", (union all_addr *)&start->addr.in6.sin6_addr, "dnssec"); + + return; + } +@@ -1094,10 +1094,10 @@ void reply_query(int fd, int family, tim + daemon->keyname, forward->class, querytype, server->edns_pktsz); + + if (server->addr.sa.sa_family == AF_INET) +- log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, daemon->keyname, (struct all_addr *)&(server->addr.in.sin_addr), ++ log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, daemon->keyname, (union all_addr *)&(server->addr.in.sin_addr), + querystr("dnssec-query", querytype)); + else +- log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, daemon->keyname, (struct all_addr *)&(server->addr.in6.sin6_addr), ++ log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, daemon->keyname, (union all_addr *)&(server->addr.in6.sin6_addr), + querystr("dnssec-query", querytype)); + + if ((hash = hash_questions(header, nn, daemon->namebuff))) +@@ -1244,7 +1244,7 @@ void receive_query(struct listener *list + union mysockaddr source_addr; + unsigned char *pheader; + unsigned short type, udp_size = PACKETSZ; /* default if no EDNS0 */ +- struct all_addr dst_addr; ++ union all_addr dst_addr; + struct in_addr netmask, dst_addr_4; + size_t m; + ssize_t n; +@@ -1274,7 +1274,7 @@ void receive_query(struct listener *list + /* packet buffer overwritten */ + daemon->srv_save = NULL; + +- dst_addr_4.s_addr = dst_addr.addr.addr4.s_addr = 0; ++ dst_addr_4.s_addr = dst_addr.addr4.s_addr = 0; + netmask.s_addr = 0; + + if (option_bool(OPT_NOWILD) && listen->iface) +@@ -1283,7 +1283,7 @@ void receive_query(struct listener *list + + if (listen->family == AF_INET) + { +- dst_addr_4 = dst_addr.addr.addr4 = listen->iface->addr.in.sin_addr; ++ dst_addr_4 = dst_addr.addr4 = listen->iface->addr.in.sin_addr; + netmask = listen->iface->netmask; + } + } +@@ -1337,7 +1337,7 @@ void receive_query(struct listener *list + { + for (addr = daemon->interface_addrs; addr; addr = addr->next) + if ((addr->flags & ADDRLIST_IPV6) && +- is_same_net6(&addr->addr.addr.addr6, &source_addr.in6.sin6_addr, addr->prefixlen)) ++ is_same_net6(&addr->addr.addr6, &source_addr.in6.sin6_addr, addr->prefixlen)) + break; + } + else +@@ -1347,7 +1347,7 @@ void receive_query(struct listener *list + { + netmask.s_addr = htonl(~(in_addr_t)0 << (32 - addr->prefixlen)); + if (!(addr->flags & ADDRLIST_IPV6) && +- is_same_net(addr->addr.addr.addr4, source_addr.in.sin_addr, netmask)) ++ is_same_net(addr->addr.addr4, source_addr.in.sin_addr, netmask)) + break; + } + } +@@ -1380,7 +1380,7 @@ void receive_query(struct listener *list + struct in_pktinfo *p; + } p; + p.c = CMSG_DATA(cmptr); +- dst_addr_4 = dst_addr.addr.addr4 = p.p->ipi_spec_dst; ++ dst_addr_4 = dst_addr.addr4 = p.p->ipi_spec_dst; + if_index = p.p->ipi_ifindex; + } + #elif defined(IP_RECVDSTADDR) && defined(IP_RECVIF) +@@ -1398,7 +1398,7 @@ void receive_query(struct listener *list + } p; + p.c = CMSG_DATA(cmptr); + if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDSTADDR) +- dst_addr_4 = dst_addr.addr.addr4 = *(p.a); ++ dst_addr_4 = dst_addr.addr4 = *(p.a); + else if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF) + #ifdef HAVE_SOLARIS_NETWORK + if_index = *(p.i); +@@ -1420,7 +1420,7 @@ void receive_query(struct listener *list + } p; + p.c = CMSG_DATA(cmptr); + +- dst_addr.addr.addr6 = p.p->ipi6_addr; ++ dst_addr.addr6 = p.p->ipi6_addr; + if_index = p.p->ipi6_ifindex; + } + } +@@ -1486,10 +1486,10 @@ void receive_query(struct listener *list + + if (listen->family == AF_INET) + log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff, +- (struct all_addr *)&source_addr.in.sin_addr, types); ++ (union all_addr *)&source_addr.in.sin_addr, types); + else + log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff, +- (struct all_addr *)&source_addr.in6.sin6_addr, types); ++ (union all_addr *)&source_addr.in6.sin6_addr, types); + + #ifdef HAVE_AUTH + /* find queries for zones we're authoritative for, and answer them directly */ +@@ -1696,10 +1696,10 @@ static int tcp_key_recurse(time_t now, i + + + if (server->addr.sa.sa_family == AF_INET) +- log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, keyname, (struct all_addr *)&(server->addr.in.sin_addr), ++ log_query(F_NOEXTRA | F_DNSSEC | F_IPV4, keyname, (union all_addr *)&(server->addr.in.sin_addr), + querystr("dnssec-query", new_status == STAT_NEED_KEY ? T_DNSKEY : T_DS)); + else +- log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, keyname, (struct all_addr *)&(server->addr.in6.sin6_addr), ++ log_query(F_NOEXTRA | F_DNSSEC | F_IPV6, keyname, (union all_addr *)&(server->addr.in6.sin6_addr), + querystr("dnssec-query", new_status == STAT_NEED_KEY ? T_DNSKEY : T_DS)); + + server->flags |= SERV_GOT_TCP; +@@ -1764,12 +1764,12 @@ unsigned char *tcp_request(int confd, ti + /* Get connection mark of incoming query to set on outgoing connections. */ + if (option_bool(OPT_CONNTRACK)) + { +- struct all_addr local; ++ union all_addr local; + + if (local_addr->sa.sa_family == AF_INET6) +- local.addr.addr6 = local_addr->in6.sin6_addr; ++ local.addr6 = local_addr->in6.sin6_addr; + else +- local.addr.addr4 = local_addr->in.sin_addr; ++ local.addr4 = local_addr->in.sin_addr; + + have_mark = get_incoming_mark(&peer_addr, &local, 1, &mark); + } +@@ -1784,7 +1784,7 @@ unsigned char *tcp_request(int confd, ti + { + for (addr = daemon->interface_addrs; addr; addr = addr->next) + if ((addr->flags & ADDRLIST_IPV6) && +- is_same_net6(&addr->addr.addr.addr6, &peer_addr.in6.sin6_addr, addr->prefixlen)) ++ is_same_net6(&addr->addr.addr6, &peer_addr.in6.sin6_addr, addr->prefixlen)) + break; + } + else +@@ -1794,7 +1794,7 @@ unsigned char *tcp_request(int confd, ti + { + netmask.s_addr = htonl(~(in_addr_t)0 << (32 - addr->prefixlen)); + if (!(addr->flags & ADDRLIST_IPV6) && +- is_same_net(addr->addr.addr.addr4, peer_addr.in.sin_addr, netmask)) ++ is_same_net(addr->addr.addr4, peer_addr.in.sin_addr, netmask)) + break; + } + } +@@ -1841,10 +1841,10 @@ unsigned char *tcp_request(int confd, ti + + if (peer_addr.sa.sa_family == AF_INET) + log_query(F_QUERY | F_IPV4 | F_FORWARD, daemon->namebuff, +- (struct all_addr *)&peer_addr.in.sin_addr, types); ++ (union all_addr *)&peer_addr.in.sin_addr, types); + else + log_query(F_QUERY | F_IPV6 | F_FORWARD, daemon->namebuff, +- (struct all_addr *)&peer_addr.in6.sin6_addr, types); ++ (union all_addr *)&peer_addr.in6.sin6_addr, types); + + #ifdef HAVE_AUTH + /* find queries for zones we're authoritative for, and answer them directly */ +@@ -1900,7 +1900,7 @@ unsigned char *tcp_request(int confd, ti + if (m == 0) + { + unsigned int flags = 0; +- struct all_addr *addrp = NULL; ++ union all_addr *addrp = NULL; + int type = SERV_DO_DNSSEC; + char *domain = NULL; + unsigned char *oph = find_pseudoheader(header, size, NULL, NULL, NULL, NULL); +@@ -2019,10 +2019,10 @@ unsigned char *tcp_request(int confd, ti + + if (last_server->addr.sa.sa_family == AF_INET) + log_query(F_SERVER | F_IPV4 | F_FORWARD, daemon->namebuff, +- (struct all_addr *)&last_server->addr.in.sin_addr, NULL); ++ (union all_addr *)&last_server->addr.in.sin_addr, NULL); + else + log_query(F_SERVER | F_IPV6 | F_FORWARD, daemon->namebuff, +- (struct all_addr *)&last_server->addr.in6.sin6_addr, NULL); ++ (union all_addr *)&last_server->addr.in6.sin6_addr, NULL); + + #ifdef HAVE_DNSSEC + if (option_bool(OPT_DNSSEC_VALID) && !checking_disabled && (last_server->flags & SERV_DO_DNSSEC)) +--- a/src/helper.c ++++ b/src/helper.c +@@ -831,7 +831,7 @@ void queue_tftp(off_t file_len, char *fi + } + #endif + +-void queue_arp(int action, unsigned char *mac, int maclen, int family, struct all_addr *addr) ++void queue_arp(int action, unsigned char *mac, int maclen, int family, union all_addr *addr) + { + /* no script */ + if (daemon->helperfd == -1) +@@ -844,9 +844,9 @@ void queue_arp(int action, unsigned char + buf->hwaddr_len = maclen; + buf->hwaddr_type = ARPHRD_ETHER; + if ((buf->flags = family) == AF_INET) +- buf->addr = addr->addr.addr4; ++ buf->addr = addr->addr4; + else +- buf->addr6 = addr->addr.addr6; ++ buf->addr6 = addr->addr6; + + memcpy(buf->hwaddr, mac, maclen); + +--- a/src/ipset.c ++++ b/src/ipset.c +@@ -114,7 +114,7 @@ void ipset_init(void) + die (_("failed to create IPset control socket: %s"), NULL, EC_MISC); + } + +-static int new_add_to_ipset(const char *setname, const struct all_addr *ipaddr, int af, int remove) ++static int new_add_to_ipset(const char *setname, const union all_addr *ipaddr, int af, int remove) + { + struct nlmsghdr *nlh; + struct my_nfgenmsg *nfg; +@@ -152,7 +152,7 @@ static int new_add_to_ipset(const char * + nested[1]->nla_type = NLA_F_NESTED | IPSET_ATTR_IP; + add_attr(nlh, + (af == AF_INET ? IPSET_ATTR_IPADDR_IPV4 : IPSET_ATTR_IPADDR_IPV6) | NLA_F_NET_BYTEORDER, +- addrsz, &ipaddr->addr); ++ addrsz, ipaddr); + nested[1]->nla_len = (void *)buffer + NL_ALIGN(nlh->nlmsg_len) - (void *)nested[1]; + nested[0]->nla_len = (void *)buffer + NL_ALIGN(nlh->nlmsg_len) - (void *)nested[0]; + +@@ -163,7 +163,7 @@ static int new_add_to_ipset(const char * + } + + +-static int old_add_to_ipset(const char *setname, const struct all_addr *ipaddr, int remove) ++static int old_add_to_ipset(const char *setname, const union all_addr *ipaddr, int remove) + { + socklen_t size; + struct ip_set_req_adt_get { +@@ -195,7 +195,7 @@ static int old_add_to_ipset(const char * + return -1; + req_adt.op = remove ? 0x102 : 0x101; + req_adt.index = req_adt_get.set.index; +- req_adt.ip = ntohl(ipaddr->addr.addr4.s_addr); ++ req_adt.ip = ntohl(ipaddr->addr4.s_addr); + if (setsockopt(ipset_sock, SOL_IP, 83, &req_adt, sizeof(req_adt)) < 0) + return -1; + +@@ -204,7 +204,7 @@ static int old_add_to_ipset(const char * + + + +-int add_to_ipset(const char *setname, const struct all_addr *ipaddr, int flags, int remove) ++int add_to_ipset(const char *setname, const union all_addr *ipaddr, int flags, int remove) + { + int ret = 0, af = AF_INET; + +--- a/src/lease.c ++++ b/src/lease.c +@@ -24,7 +24,7 @@ static int dns_dirty, file_dirty, leases + static int read_leases(time_t now, FILE *leasestream) + { + unsigned long ei; +- struct all_addr addr; ++ union all_addr addr; + struct dhcp_lease *lease; + int clid_len, hw_len, hw_type; + int items; +@@ -62,9 +62,9 @@ static int read_leases(time_t now, FILE + daemon->namebuff, daemon->dhcp_buff, daemon->packet) != 3) + return 0; + +- if (inet_pton(AF_INET, daemon->namebuff, &addr.addr.addr4)) ++ if (inet_pton(AF_INET, daemon->namebuff, &addr.addr4)) + { +- if ((lease = lease4_allocate(addr.addr.addr4))) ++ if ((lease = lease4_allocate(addr.addr4))) + domain = get_domain(lease->addr); + + hw_len = parse_hex(daemon->dhcp_buff2, (unsigned char *)daemon->dhcp_buff2, DHCP_CHADDR_MAX, NULL, &hw_type); +@@ -73,7 +73,7 @@ static int read_leases(time_t now, FILE + hw_type = ARPHRD_ETHER; + } + #ifdef HAVE_DHCP6 +- else if (inet_pton(AF_INET6, daemon->namebuff, &addr.addr.addr6)) ++ else if (inet_pton(AF_INET6, daemon->namebuff, &addr.addr6)) + { + char *s = daemon->dhcp_buff2; + int lease_type = LEASE_NA; +@@ -84,7 +84,7 @@ static int read_leases(time_t now, FILE + s++; + } + +- if ((lease = lease6_allocate(&addr.addr.addr6, lease_type))) ++ if ((lease = lease6_allocate(&addr.addr6, lease_type))) + { + lease_set_iaid(lease, strtoul(s, NULL, 10)); + domain = get_domain6(&lease->addr6); +@@ -514,28 +514,28 @@ void lease_update_dns(int force) + if (slaac->backoff == 0) + { + if (lease->fqdn) +- cache_add_dhcp_entry(lease->fqdn, AF_INET6, (struct all_addr *)&slaac->addr, lease->expires); ++ cache_add_dhcp_entry(lease->fqdn, AF_INET6, (union all_addr *)&slaac->addr, lease->expires); + if (!option_bool(OPT_DHCP_FQDN) && lease->hostname) +- cache_add_dhcp_entry(lease->hostname, AF_INET6, (struct all_addr *)&slaac->addr, lease->expires); ++ cache_add_dhcp_entry(lease->hostname, AF_INET6, (union all_addr *)&slaac->addr, lease->expires); + } + } + + if (lease->fqdn) + cache_add_dhcp_entry(lease->fqdn, prot, +- prot == AF_INET ? (struct all_addr *)&lease->addr : (struct all_addr *)&lease->addr6, ++ prot == AF_INET ? (union all_addr *)&lease->addr : (union all_addr *)&lease->addr6, + lease->expires); + + if (!option_bool(OPT_DHCP_FQDN) && lease->hostname) + cache_add_dhcp_entry(lease->hostname, prot, +- prot == AF_INET ? (struct all_addr *)&lease->addr : (struct all_addr *)&lease->addr6, ++ prot == AF_INET ? (union all_addr *)&lease->addr : (union all_addr *)&lease->addr6, + lease->expires); + + #else + if (lease->fqdn) +- cache_add_dhcp_entry(lease->fqdn, prot, (struct all_addr *)&lease->addr, lease->expires); ++ cache_add_dhcp_entry(lease->fqdn, prot, (union all_addr *)&lease->addr, lease->expires); + + if (!option_bool(OPT_DHCP_FQDN) && lease->hostname) +- cache_add_dhcp_entry(lease->hostname, prot, (struct all_addr *)&lease->addr, lease->expires); ++ cache_add_dhcp_entry(lease->hostname, prot, (union all_addr *)&lease->addr, lease->expires); + #endif + } + +--- a/src/network.c ++++ b/src/network.c +@@ -109,7 +109,7 @@ int indextoname(int fd, int index, char + + #endif + +-int iface_check(int family, struct all_addr *addr, char *name, int *auth) ++int iface_check(int family, union all_addr *addr, char *name, int *auth) + { + struct iname *tmp; + int ret = 1, match_addr = 0; +@@ -135,11 +135,11 @@ int iface_check(int family, struct all_a + if (tmp->addr.sa.sa_family == family) + { + if (family == AF_INET && +- tmp->addr.in.sin_addr.s_addr == addr->addr.addr4.s_addr) ++ tmp->addr.in.sin_addr.s_addr == addr->addr4.s_addr) + ret = match_addr = tmp->used = 1; + else if (family == AF_INET6 && + IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, +- &addr->addr.addr6)) ++ &addr->addr6)) + ret = match_addr = tmp->used = 1; + } + } +@@ -158,10 +158,10 @@ int iface_check(int family, struct all_a + break; + } + else if (addr && tmp->addr.sa.sa_family == AF_INET && family == AF_INET && +- tmp->addr.in.sin_addr.s_addr == addr->addr.addr4.s_addr) ++ tmp->addr.in.sin_addr.s_addr == addr->addr4.s_addr) + break; + else if (addr && tmp->addr.sa.sa_family == AF_INET6 && family == AF_INET6 && +- IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, &addr->addr.addr6)) ++ IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, &addr->addr6)) + break; + + if (tmp && auth) +@@ -179,7 +179,7 @@ int iface_check(int family, struct all_a + an interface other than the loopback. Accept packet if it arrived via a loopback + interface, even when we're not accepting packets that way, as long as the destination + address is one we're believing. Interface list must be up-to-date before calling. */ +-int loopback_exception(int fd, int family, struct all_addr *addr, char *name) ++int loopback_exception(int fd, int family, union all_addr *addr, char *name) + { + struct ifreq ifr; + struct irec *iface; +@@ -193,10 +193,10 @@ int loopback_exception(int fd, int famil + { + if (family == AF_INET) + { +- if (iface->addr.in.sin_addr.s_addr == addr->addr.addr4.s_addr) ++ if (iface->addr.in.sin_addr.s_addr == addr->addr4.s_addr) + return 1; + } +- else if (IN6_ARE_ADDR_EQUAL(&iface->addr.in6.sin6_addr, &addr->addr.addr6)) ++ else if (IN6_ARE_ADDR_EQUAL(&iface->addr.in6.sin6_addr, &addr->addr6)) + return 1; + } + } +@@ -207,7 +207,7 @@ int loopback_exception(int fd, int famil + on the relevant address, but the name of the arrival interface, derived from the + index won't match the config. Check that we found an interface address for the arrival + interface: daemon->interfaces must be up-to-date. */ +-int label_exception(int index, int family, struct all_addr *addr) ++int label_exception(int index, int family, union all_addr *addr) + { + struct irec *iface; + +@@ -217,7 +217,7 @@ int label_exception(int index, int famil + + for (iface = daemon->interfaces; iface; iface = iface->next) + if (iface->index == index && iface->addr.sa.sa_family == AF_INET && +- iface->addr.in.sin_addr.s_addr == addr->addr.addr4.s_addr) ++ iface->addr.in.sin_addr.s_addr == addr->addr4.s_addr) + return 1; + + return 0; +@@ -282,12 +282,12 @@ static int iface_allowed(struct iface_pa + + if (addr->sa.sa_family == AF_INET) + { +- al->addr.addr.addr4 = addr->in.sin_addr; ++ al->addr.addr4 = addr->in.sin_addr; + al->flags = 0; + } + else + { +- al->addr.addr.addr6 = addr->in6.sin6_addr; ++ al->addr.addr6 = addr->in6.sin6_addr; + al->flags = ADDRLIST_IPV6; + } + } +@@ -321,7 +321,7 @@ static int iface_allowed(struct iface_pa + al->next = zone->subnet; + zone->subnet = al; + al->prefixlen = prefixlen; +- al->addr.addr.addr4 = addr->in.sin_addr; ++ al->addr.addr4 = addr->in.sin_addr; + al->flags = 0; + } + } +@@ -341,7 +341,7 @@ static int iface_allowed(struct iface_pa + al->next = zone->subnet; + zone->subnet = al; + al->prefixlen = prefixlen; +- al->addr.addr.addr6 = addr->in6.sin6_addr; ++ al->addr.addr6 = addr->in6.sin6_addr; + al->flags = ADDRLIST_IPV6; + } + } +@@ -369,12 +369,12 @@ static int iface_allowed(struct iface_pa + + if (addr->sa.sa_family == AF_INET) + { +- al->addr.addr.addr4 = addr->in.sin_addr; ++ al->addr.addr4 = addr->in.sin_addr; + al->flags = 0; + } + else + { +- al->addr.addr.addr6 = addr->in6.sin6_addr; ++ al->addr.addr6 = addr->in6.sin6_addr; + al->flags = ADDRLIST_IPV6; + /* Privacy addresses and addresses still undergoing DAD and deprecated addresses + don't appear in forward queries, but will in reverse ones. */ +@@ -419,11 +419,11 @@ static int iface_allowed(struct iface_pa + } + + if (addr->sa.sa_family == AF_INET && +- !iface_check(AF_INET, (struct all_addr *)&addr->in.sin_addr, label, &auth_dns)) ++ !iface_check(AF_INET, (union all_addr *)&addr->in.sin_addr, label, &auth_dns)) + return 1; + + if (addr->sa.sa_family == AF_INET6 && +- !iface_check(AF_INET6, (struct all_addr *)&addr->in6.sin6_addr, label, &auth_dns)) ++ !iface_check(AF_INET6, (union all_addr *)&addr->in6.sin6_addr, label, &auth_dns)) + return 1; + + #ifdef HAVE_DHCP +--- a/src/option.c ++++ b/src/option.c +@@ -2064,7 +2064,7 @@ static int one_opt(int option, char *arg + int is_exclude = 0; + char *prefix; + struct addrlist *subnet = NULL; +- struct all_addr addr; ++ union all_addr addr; + + comma = split(arg); + prefix = split_chr(arg, '/'); +@@ -2078,13 +2078,13 @@ static int one_opt(int option, char *arg + arg = arg+8; + } + +- if (inet_pton(AF_INET, arg, &addr.addr.addr4)) ++ if (inet_pton(AF_INET, arg, &addr.addr4)) + { + subnet = opt_malloc(sizeof(struct addrlist)); + subnet->prefixlen = (prefixlen == 0) ? 24 : prefixlen; + subnet->flags = ADDRLIST_LITERAL; + } +- else if (inet_pton(AF_INET6, arg, &addr.addr.addr6)) ++ else if (inet_pton(AF_INET6, arg, &addr.addr6)) + { + subnet = opt_malloc(sizeof(struct addrlist)); + subnet->prefixlen = (prefixlen == 0) ? 64 : prefixlen; +@@ -4268,7 +4268,7 @@ err: + + while (arg) + { +- struct all_addr addr; ++ union all_addr addr; + char *dig; + + for (dig = arg; *dig != 0; dig++) +@@ -4276,10 +4276,10 @@ err: + break; + if (*dig == 0) + new->ttl = atoi(arg); +- else if (inet_pton(AF_INET, arg, &addr)) +- new->addr = addr.addr.addr4; +- else if (inet_pton(AF_INET6, arg, &addr)) +- new->addr6 = addr.addr.addr6; ++ else if (inet_pton(AF_INET, arg, &addr.addr4)) ++ new->addr = addr.addr4; ++ else if (inet_pton(AF_INET6, arg, &addr.addr6)) ++ new->addr6 = addr.addr6; + else + { + int nomem; +--- a/src/rfc1035.c ++++ b/src/rfc1035.c +@@ -143,7 +143,7 @@ int extract_name(struct dns_header *head + + /* Max size of input string (for IPv6) is 75 chars.) */ + #define MAXARPANAME 75 +-int in_arpa_name_2_addr(char *namein, struct all_addr *addrp) ++int in_arpa_name_2_addr(char *namein, union all_addr *addrp) + { + int j; + char name[MAXARPANAME+1], *cp1; +@@ -153,7 +153,7 @@ int in_arpa_name_2_addr(char *namein, st + if (strlen(namein) > MAXARPANAME) + return 0; + +- memset(addrp, 0, sizeof(struct all_addr)); ++ memset(addrp, 0, sizeof(union all_addr)); + + /* turn name into a series of asciiz strings */ + /* j counts no. of labels */ +@@ -234,7 +234,7 @@ int in_arpa_name_2_addr(char *namein, st + if (*(cp1+1) || !isxdigit((unsigned char)*cp1)) + return 0; + +- for (j = sizeof(struct all_addr)-1; j>0; j--) ++ for (j = sizeof(struct in6_addr)-1; j>0; j--) + addr[j] = (addr[j] >> 4) | (addr[j-1] << 4); + addr[0] = (addr[0] >> 4) | (strtol(cp1, NULL, 16) << 4); + } +@@ -585,7 +585,7 @@ int extract_addresses(struct dns_header + unsigned char *p, *p1, *endrr, *namep; + int i, j, qtype, qclass, aqtype, aqclass, ardlen, res, searched_soa = 0; + unsigned long ttl = 0; +- struct all_addr addr; ++ union all_addr addr; + #ifdef HAVE_IPSET + char **ipsets_cur; + #else +@@ -808,14 +808,14 @@ int extract_addresses(struct dns_header + if (check_rebind) + { + if ((flags & F_IPV4) && +- private_net(addr.addr.addr4, !option_bool(OPT_LOCAL_REBIND))) ++ private_net(addr.addr4, !option_bool(OPT_LOCAL_REBIND))) + return 1; + + if ((flags & F_IPV6) && +- IN6_IS_ADDR_V4MAPPED(&addr.addr.addr6)) ++ IN6_IS_ADDR_V4MAPPED(&addr.addr6)) + { + struct in_addr v4; +- v4.s_addr = ((const uint32_t *) (&addr.addr.addr6))[3]; ++ v4.s_addr = ((const uint32_t *) (&addr.addr6))[3]; + if (private_net(v4, !option_bool(OPT_LOCAL_REBIND))) + return 1; + } +@@ -928,7 +928,7 @@ unsigned int extract_request(struct dns_ + } + + size_t setup_reply(struct dns_header *header, size_t qlen, +- struct all_addr *addrp, unsigned int flags, unsigned long ttl) ++ union all_addr *addrp, unsigned int flags, unsigned long ttl) + { + unsigned char *p; + +@@ -949,8 +949,8 @@ size_t setup_reply(struct dns_header *he + SET_RCODE(header, NXDOMAIN); + else if (flags == F_SERVFAIL) + { +- struct all_addr a; +- a.addr.log.rcode = SERVFAIL; ++ union all_addr a; ++ a.log.rcode = SERVFAIL; + log_query(F_CONFIG | F_RCODE, "error", &a, NULL); + SET_RCODE(header, SERVFAIL); + } +@@ -974,8 +974,8 @@ size_t setup_reply(struct dns_header *he + } + else /* nowhere to forward to */ + { +- struct all_addr a; +- a.addr.log.rcode = REFUSED; ++ union all_addr a; ++ a.log.rcode = REFUSED; + log_query(F_CONFIG | F_RCODE, "error", &a, NULL); + SET_RCODE(header, REFUSED); + } +@@ -1277,7 +1277,7 @@ size_t answer_request(struct dns_header + char *name = daemon->namebuff; + unsigned char *p, *ansp; + unsigned int qtype, qclass; +- struct all_addr addr; ++ union all_addr addr; + int nameoffset; + unsigned short flag; + int q, ans, anscount = 0, addncount = 0; +@@ -1374,7 +1374,7 @@ size_t answer_request(struct dns_header + notimp = 1, auth = 0; + if (!dryrun) + { +- addr.addr.log.rcode = NOTIMP; ++ addr.log.rcode = NOTIMP; + log_query(F_CONFIG | F_RCODE, name, &addr, NULL); + } + ans = 1, sec_data = 0; +@@ -1418,7 +1418,7 @@ size_t answer_request(struct dns_header + struct addrlist *addrlist; + + for (addrlist = intr->addr; addrlist; addrlist = addrlist->next) +- if (!(addrlist->flags & ADDRLIST_IPV6) && addr.addr.addr4.s_addr == addrlist->addr.addr.addr4.s_addr) ++ if (!(addrlist->flags & ADDRLIST_IPV6) && addr.addr4.s_addr == addrlist->addr.addr4.s_addr) + break; + + if (addrlist) +@@ -1433,7 +1433,7 @@ size_t answer_request(struct dns_header + struct addrlist *addrlist; + + for (addrlist = intr->addr; addrlist; addrlist = addrlist->next) +- if ((addrlist->flags & ADDRLIST_IPV6) && IN6_ARE_ADDR_EQUAL(&addr.addr.addr6, &addrlist->addr.addr.addr6)) ++ if ((addrlist->flags & ADDRLIST_IPV6) && IN6_ARE_ADDR_EQUAL(&addr.addr6, &addrlist->addr.addr6)) + break; + + if (addrlist) +@@ -1533,8 +1533,8 @@ size_t answer_request(struct dns_header + } + } + else if (option_bool(OPT_BOGUSPRIV) && ( +- (is_arpa == F_IPV6 && private_net6(&addr.addr.addr6)) || +- (is_arpa == F_IPV4 && private_net(addr.addr.addr4, 1)))) ++ (is_arpa == F_IPV6 && private_net6(&addr.addr6)) || ++ (is_arpa == F_IPV4 && private_net(addr.addr4, 1)))) + { + struct server *serv; + unsigned int namelen = strlen(name); +@@ -1600,7 +1600,7 @@ size_t answer_request(struct dns_header + if (hostname_isequal(name, intr->name)) + for (addrlist = intr->addr; addrlist; addrlist = addrlist->next) + if (!(addrlist->flags & ADDRLIST_IPV6) && +- is_same_net(*((struct in_addr *)&addrlist->addr), local_addr, local_netmask)) ++ is_same_net(addrlist->addr.addr4, local_addr, local_netmask)) + { + localise = 1; + break; +@@ -1613,7 +1613,7 @@ size_t answer_request(struct dns_header + if (((addrlist->flags & ADDRLIST_IPV6) ? T_AAAA : T_A) == type) + { + if (localise && +- !is_same_net(*((struct in_addr *)&addrlist->addr), local_addr, local_netmask)) ++ !is_same_net(addrlist->addr.addr4, local_addr, local_netmask)) + continue; + + if (addrlist->flags & ADDRLIST_REVONLY) +@@ -1651,7 +1651,7 @@ size_t answer_request(struct dns_header + struct crec *save = crecp; + do { + if ((crecp->flags & F_HOSTS) && +- is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask)) ++ is_same_net(crecp->addr.addr4, local_addr, local_netmask)) + { + localise = 1; + break; +@@ -1710,7 +1710,7 @@ size_t answer_request(struct dns_header + filter here. */ + if (localise && + (crecp->flags & F_HOSTS) && +- !is_same_net(*((struct in_addr *)&crecp->addr), local_addr, local_netmask)) ++ !is_same_net(crecp->addr.addr4, local_addr, local_netmask)) + continue; + + if (!(crecp->flags & (F_HOSTS | F_DHCP))) +@@ -1719,7 +1719,7 @@ size_t answer_request(struct dns_header + ans = 1; + if (!dryrun) + { +- log_query(crecp->flags & ~F_REVERSE, name, &crecp->addr.addr, ++ log_query(crecp->flags & ~F_REVERSE, name, &crecp->addr, + record_source(crecp->uid)); + + if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, +--- a/src/rfc3315.c ++++ b/src/rfc3315.c +@@ -2120,7 +2120,7 @@ void relay_upstream6(struct dhcp_relay * + { + /* ->local is same value for all relays on ->current chain */ + +- struct all_addr from; ++ union all_addr from; + unsigned char *header; + unsigned char *inbuff = daemon->dhcp_packet.iov_base; + int msg_type = *inbuff; +@@ -2133,7 +2133,7 @@ void relay_upstream6(struct dhcp_relay * + get_client_mac(peer_address, scope_id, mac, &maclen, &mactype, now); + + /* source address == relay address */ +- from.addr.addr6 = relay->local.addr.addr6; ++ from.addr6 = relay->local.addr6; + + /* Get hop count from nested relayed message */ + if (msg_type == DHCP6RELAYFORW) +@@ -2153,7 +2153,7 @@ void relay_upstream6(struct dhcp_relay * + + header[0] = DHCP6RELAYFORW; + header[1] = hopcount; +- memcpy(&header[2], &relay->local.addr.addr6, IN6ADDRSZ); ++ memcpy(&header[2], &relay->local.addr6, IN6ADDRSZ); + memcpy(&header[18], peer_address, IN6ADDRSZ); + + /* RFC-6939 */ +@@ -2174,12 +2174,12 @@ void relay_upstream6(struct dhcp_relay * + union mysockaddr to; + + to.sa.sa_family = AF_INET6; +- to.in6.sin6_addr = relay->server.addr.addr6; ++ to.in6.sin6_addr = relay->server.addr6; + to.in6.sin6_port = htons(DHCPV6_SERVER_PORT); + to.in6.sin6_flowinfo = 0; + to.in6.sin6_scope_id = 0; + +- if (IN6_ARE_ADDR_EQUAL(&relay->server.addr.addr6, &multicast)) ++ if (IN6_ARE_ADDR_EQUAL(&relay->server.addr6, &multicast)) + { + int multicast_iface; + if (!relay->interface || strchr(relay->interface, '*') || +@@ -2218,7 +2218,7 @@ unsigned short relay_reply6(struct socka + memcpy(&link, &inbuff[2], IN6ADDRSZ); + + for (relay = daemon->relay6; relay; relay = relay->next) +- if (IN6_ARE_ADDR_EQUAL(&link, &relay->local.addr.addr6) && ++ if (IN6_ARE_ADDR_EQUAL(&link, &relay->local.addr6) && + (!relay->interface || wildcard_match(relay->interface, arrival_interface))) + break; + +--- a/src/tables.c ++++ b/src/tables.c +@@ -62,7 +62,7 @@ void ipset_init(void) + } + } + +-int add_to_ipset(const char *setname, const struct all_addr *ipaddr, ++int add_to_ipset(const char *setname, const union all_addr *ipaddr, + int flags, int remove) + { + struct pfr_addr addr; +@@ -113,13 +113,13 @@ int add_to_ipset(const char *setname, co + { + addr.pfra_af = AF_INET6; + addr.pfra_net = 0x80; +- memcpy(&(addr.pfra_ip6addr), &(ipaddr->addr), sizeof(struct in6_addr)); ++ memcpy(&(addr.pfra_ip6addr), ipaddr, sizeof(struct in6_addr)); + } + else + { + addr.pfra_af = AF_INET; + addr.pfra_net = 0x20; +- addr.pfra_ip4addr.s_addr = ipaddr->addr.addr4.s_addr; ++ addr.pfra_ip4addr.s_addr = ipaddr->addr4.s_addr; + } + + bzero(&io, sizeof(io)); +--- a/src/tftp.c ++++ b/src/tftp.c +@@ -59,7 +59,7 @@ void tftp_request(struct listener *liste + char *name = NULL; + char *prefix = daemon->tftp_prefix; + struct tftp_prefix *pref; +- struct all_addr addra; ++ union all_addr addra; + /* Can always get recvd interface for IPv6 */ + int check_dest = !option_bool(OPT_NOWILD) || listen->family == AF_INET6; + union { +@@ -189,10 +189,10 @@ void tftp_request(struct listener *liste + + name = namebuff; + +- addra.addr.addr4 = addr.in.sin_addr; ++ addra.addr4 = addr.in.sin_addr; + + if (listen->family == AF_INET6) +- addra.addr.addr6 = addr.in6.sin6_addr; ++ addra.addr6 = addr.in6.sin6_addr; + + if (daemon->tftp_interfaces) + { +@@ -212,7 +212,7 @@ void tftp_request(struct listener *liste + if (!option_bool(OPT_CLEVERBIND)) + enumerate_interfaces(0); + if (!loopback_exception(listen->tftpfd, listen->family, &addra, name) && +- !label_exception(if_index, listen->family, &addra) ) ++ !label_exception(if_index, listen->family, &addra)) + return; + } + |