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/32] 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(&param->relay_local) || IN6_ARE_ADDR_EQUAL(local, &param->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;
 	    }
 	  
