]> git.ipfire.org Git - people/ms/dnsmasq.git/commitdiff
Eliminate IPv6 privacy addresses from --interface-name answers.
authorSimon Kelley <simon@thekelleys.org.uk>
Wed, 17 Dec 2014 12:41:56 +0000 (12:41 +0000)
committerSimon Kelley <simon@thekelleys.org.uk>
Wed, 17 Dec 2014 12:41:56 +0000 (12:41 +0000)
CHANGELOG
src/auth.c
src/dnsmasq.h
src/network.c
src/rfc1035.c

index 9e6c7aa4fd68532d1efd8c3fed82198c4a195305..01f5208ec0061db84beba8e5fc9d1fbfc4adc864 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -14,6 +14,11 @@ version 2.73
            Fix breakage of --domain=<domain>,<subnet>,local - only reverse
            queries were intercepted. THis appears to have been broken 
            since 2.69. Thanks to Josh Stone for finding the bug.
+
+           Eliminate IPv6 privacy addresses and deprecated addresses from
+           the answers given by --interface-name. Note that reverse queries
+           (ie looking for names, given addresses) are not affected. 
+           Thanks to Michael Gorbach for the suggestion.
        
 
 version 2.72
index dd46566ec2ccb7cec0006c20a512d164ca9a376f..a327f16d8c0bd9d55a3071b1c534efc15e74c7e0 100644 (file)
@@ -363,6 +363,10 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
                 if (((addrlist->flags & ADDRLIST_IPV6)  ? T_AAAA : T_A) == qtype &&
                     (local_query || filter_zone(zone, flag, &addrlist->addr)))
                   {
+#ifdef HAVE_IPV6
+                    if (addrlist->flags & ADDRLIST_REVONLY)
+                      continue;
+#endif
                     found = 1;
                     log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL);
                     if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, 
index ebb6b957812f9ead50e78808e8a82e0b62042120..1dd61c5edba3d73a6f0051ae8687519f35379201 100644 (file)
@@ -318,6 +318,7 @@ struct ds_config {
 
 #define ADDRLIST_LITERAL 1
 #define ADDRLIST_IPV6    2
+#define ADDRLIST_REVONLY 4
 
 struct addrlist {
   struct all_addr addr;
index 99419f57951e2219a11a0c110fee9244add49fc5..14d2af2ce313e224a87ee43f24aa090c49944aea 100644 (file)
@@ -236,7 +236,7 @@ struct iface_param {
 };
 
 static int iface_allowed(struct iface_param *param, int if_index, char *label,
-                        union mysockaddr *addr, struct in_addr netmask, int prefixlen, int dad
+                        union mysockaddr *addr, struct in_addr netmask, int prefixlen, int iface_flags
 {
   struct irec *iface;
   int mtu = 0, loopback;
@@ -388,6 +388,10 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
                 {
                    al->addr.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. */
+                   if (!(iface_flags & IFACE_PERMANENT) || (iface_flags & (IFACE_DEPRECATED | IFACE_TENTATIVE)))
+                     al->flags |= ADDRLIST_REVONLY;
                 } 
 #endif
              }
@@ -399,7 +403,7 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
   for (iface = daemon->interfaces; iface; iface = iface->next) 
     if (sockaddr_isequal(&iface->addr, addr))
       {
-       iface->dad = dad;
+       iface->dad = !!(iface_flags & IFACE_TENTATIVE);
        iface->found = 1; /* for garbage collection */
        return 1;
       }
@@ -474,7 +478,7 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
       iface->dhcp_ok = dhcp_ok;
       iface->dns_auth = auth_dns;
       iface->mtu = mtu;
-      iface->dad = dad;
+      iface->dad = !!(iface_flags & IFACE_TENTATIVE);
       iface->found = 1;
       iface->done = iface->multicast_done = iface->warned = 0;
       iface->index = if_index;
@@ -519,7 +523,7 @@ static int iface_allowed_v6(struct in6_addr *local, int prefix,
   else
     addr.in6.sin6_scope_id = 0;
   
-  return iface_allowed((struct iface_param *)vparam, if_index, NULL, &addr, netmask, prefix, !!(flags & IFACE_TENTATIVE));
+  return iface_allowed((struct iface_param *)vparam, if_index, NULL, &addr, netmask, prefix, flags);
 }
 #endif
 
index 8a7d2608dac58032f923ec2a79379b28770da2d1..bdeb3fb10e6835ed4c9abfbec320ab927d7a1fb4 100644 (file)
@@ -1923,14 +1923,17 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
                  for (intr = daemon->int_names; intr; intr = intr->next)
                    if (hostname_isequal(name, intr->name))
                      {
-                       ans = 1;
-                       if (!dryrun)
-                         {
-                           
-                           for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
+                       for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
 #ifdef HAVE_IPV6
-                             if (((addrlist->flags & ADDRLIST_IPV6) ? T_AAAA : T_A) == type)
+                         if (((addrlist->flags & ADDRLIST_IPV6) ? T_AAAA : T_A) == type)
 #endif
+                           {
+#ifdef HAVE_IPV6
+                             if (addrlist->flags & ADDRLIST_REVONLY)
+                               continue;
+#endif 
+                             ans = 1;  
+                             if (!dryrun)
                                {
                                  gotit = 1;
                                  log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL);
@@ -1939,7 +1942,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
                                                          type == T_A ? "4" : "6", &addrlist->addr))
                                    anscount++;
                                }
-                         }
+                           }
                      }
                  
                  if (!dryrun && !gotit)