]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/ip/Address.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / ip / Address.cc
index 51e8659a4dfb347dc2170b3afae2361b9c4cf7ba..25e970a659727f8d1499199d5421aafadbcaba3a 100644 (file)
@@ -1,9 +1,14 @@
 /*
- * DEBUG: section 14    IP Storage and Handling
+ * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
  */
+
+/* DEBUG: section 14    IP Storage and Handling */
+
 #include "squid.h"
-#include "compat/getaddrinfo.h"
-#include "compat/inet_ntop.h"
 #include "Debug.h"
 #include "ip/Address.h"
 #include "ip/tools.h"
 /* for inet_ntoa() */
 #include <arpa/inet.h>
 #endif
+#if HAVE_WS2TCPIP_H
+// Windows IPv6 definitions
+#include <ws2tcpip.h>
+#endif
+
+// some OS (ie WIndows) define IN6_ADDR_EQUAL instead
+#if !defined(IN6_ARE_ADDR_EQUAL) && _SQUID_WINDOWS_
+#define IN6_ARE_ADDR_EQUAL IN6_ADDR_EQUAL
+#endif
 
 /* Debugging only. Dump the address content when a fatal assert is encountered. */
 #define IASSERT(a,b)  \
-       if(!(b)){       printf("assert \"%s\" at line %d\n", a, __LINE__); \
-               printf("Ip::Address invalid? with isIPv4()=%c, isIPv6()=%c\n",(isIPv4()?'T':'F'),(isIPv6()?'T':'F')); \
-               printf("ADDRESS:"); \
-               for(unsigned int i = 0; i < sizeof(mSocketAddr_.sin6_addr); ++i) { \
-                       printf(" %x", mSocketAddr_.sin6_addr.s6_addr[i]); \
-               } printf("\n"); assert(b); \
-       }
+    if(!(b)){   printf("assert \"%s\" at line %d\n", a, __LINE__); \
+        printf("Ip::Address invalid? with isIPv4()=%c, isIPv6()=%c\n",(isIPv4()?'T':'F'),(isIPv6()?'T':'F')); \
+        printf("ADDRESS:"); \
+        for(unsigned int i = 0; i < sizeof(mSocketAddr_.sin6_addr); ++i) { \
+            printf(" %x", mSocketAddr_.sin6_addr.s6_addr[i]); \
+        } printf("\n"); assert(b); \
+    }
 
 int
 Ip::Address::cidr() const
 {
-    uint8_t shift,byte;
+    uint8_t shift,ipbyte;
     uint8_t bit,caught;
     int len = 0;
     const uint8_t *ptr= mSocketAddr_.sin6_addr.s6_addr;
@@ -46,20 +60,20 @@ Ip::Address::cidr() const
     }
 
     for (; shift<sizeof(mSocketAddr_.sin6_addr) ; ++shift) {
-        byte= *(ptr+shift);
+        ipbyte= *(ptr+shift);
 
-        if (byte == 0xFF) {
+        if (ipbyte == 0xFF) {
             len += 8;
             continue ;  /* A short-cut */
         }
 
         for (caught = 0 , bit= 7 ; !caught && (bit <= 7); --bit) {
-            caught = ((byte & 0x80) == 0x00);  /* Found a '0' at 'bit' ? */
+            caught = ((ipbyte & 0x80) == 0x00);  /* Found a '0' at 'bit' ? */
 
             if (!caught)
                 ++len;
 
-            byte <<= 1;
+            ipbyte <<= 1;
         }
 
         if (caught)
@@ -173,17 +187,29 @@ const struct in6_addr Ip::Address::v4_anyaddr = {{{ 0x00000000, 0x00000000, 0x00
 const struct in6_addr Ip::Address::v4_noaddr = {{{ 0x00000000, 0x00000000, 0x0000ffff, 0xffffffff }}};
 const struct in6_addr Ip::Address::v6_noaddr = {{{ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }}};
 #else
-const struct in6_addr Ip::Address::v4_localhost = {{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-            0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01 }}
+const struct in6_addr Ip::Address::v4_localhost = {{{
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01
+        }
+    }
 };
-const struct in6_addr Ip::Address::v4_anyaddr = {{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-            0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 }}
+const struct in6_addr Ip::Address::v4_anyaddr = {{{
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
+        }
+    }
 };
-const struct in6_addr Ip::Address::v4_noaddr = {{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-            0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }}
+const struct in6_addr Ip::Address::v4_noaddr = {{{
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+        }
+    }
 };
-const struct in6_addr Ip::Address::v6_noaddr = {{{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }}
+const struct in6_addr Ip::Address::v6_noaddr = {{{
+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+            0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+        }
+    }
 };
 #endif
 
@@ -367,6 +393,20 @@ Ip::Address::lookupHostIP(const char *s, bool nodns)
         return false;
     }
 
+    struct addrinfo *resHead = res; // we need to free the whole list later
+    if (!Ip::EnableIpv6) {
+        // if we are IPv6-disabled, use first-IPv4 instead of first-IP.
+        struct addrinfo *maybeIpv4 = res;
+        while (maybeIpv4) {
+            if (maybeIpv4->ai_family == AF_INET)
+                break;
+            maybeIpv4 = maybeIpv4->ai_next;
+        }
+        if (maybeIpv4 != NULL)
+            res = maybeIpv4;
+        // else IPv6-only host, let the caller deal with first-IP anyway.
+    }
+
     /*
      *  NP: =(sockaddr_*) may alter the port. we don't want that.
      *      all we have been given as input was an IPA.
@@ -376,7 +416,7 @@ Ip::Address::lookupHostIP(const char *s, bool nodns)
     port(portSaved);
 
     /* free the memory getaddrinfo() dynamically allocated. */
-    freeaddrinfo(res);
+    freeaddrinfo(resHead);
     return true;
 }
 
@@ -633,7 +673,7 @@ Ip::Address::getAddrInfo(struct addrinfo *&dst, int force) const
 }
 
 void
-Ip::Address::InitAddrInfo(struct addrinfo *&ai)
+Ip::Address::InitAddr(struct addrinfo *&ai)
 {
     if (ai == NULL) {
         ai = new addrinfo;
@@ -651,7 +691,7 @@ Ip::Address::InitAddrInfo(struct addrinfo *&ai)
 }
 
 void
-Ip::Address::FreeAddrInfo(struct addrinfo *&ai)
+Ip::Address::FreeAddr(struct addrinfo *&ai)
 {
     if (ai == NULL) return;
 
@@ -984,3 +1024,4 @@ Ip::Address::getInAddr(struct in_addr &buf) const
     assert(false);
     return false;
 }
+