]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Fall back on IPv4 if IPv6 is not present
authorHenrik Nordstrom <henrik@henriknordstrom.net>
Fri, 14 May 2010 05:37:19 +0000 (07:37 +0200)
committerHenrik Nordstrom <henrik@henriknordstrom.net>
Fri, 14 May 2010 05:37:19 +0000 (07:37 +0200)
automatically fall back on IPv4 operation if it fails creating an
IPv6 socket. This may happen if Squid is built with IPv6 support
enabled but no IPv6 stack is available when it runs.

src/cf.data.pre
src/comm.cc
src/ip/Address.cc
src/ip/Address.h

index 59934e034d229d31192805a4a4987a1c2de8c494..32b93edba5bc68cb16d15fcdb340afa20ff66a6d 100644 (file)
@@ -3021,7 +3021,7 @@ DOC_END
 NAME: client_netmask
 TYPE: address
 LOC: Config.Addrs.client_netmask
-DEFAULT: 255.255.255.255
+DEFAULT: no_addr
 DOC_START
        A netmask for client addresses in logfiles and cachemgr output.
        Change this to protect the privacy of your cache clients.
@@ -4668,7 +4668,7 @@ COMMENT_END
 NAME: wccp_router
 TYPE: address
 LOC: Config.Wccp.router
-DEFAULT: 0.0.0.0
+DEFAULT: any_addr
 IFDEF: USE_WCCP
 DOC_START
        Use this option to define your WCCP ``home'' router for
@@ -5034,14 +5034,14 @@ DOC_END
 NAME: snmp_incoming_address
 TYPE: address
 LOC: Config.Addrs.snmp_incoming
-DEFAULT: 0.0.0.0
+DEFAULT: any_addr
 IFDEF: SQUID_SNMP
 DOC_NONE
 
 NAME: snmp_outgoing_address
 TYPE: address
 LOC: Config.Addrs.snmp_outgoing
-DEFAULT: 255.255.255.255
+DEFAULT: no_addr
 IFDEF: SQUID_SNMP
 DOC_START
        Just like 'udp_incoming_address', but for the SNMP port.
@@ -5051,13 +5051,13 @@ DOC_START
        snmp_outgoing_address   is used for SNMP packets returned to SNMP
                                agents.
 
-       The default snmp_incoming_address (0.0.0.0) is to listen on all
+       The default snmp_incoming_address is to listen on all
        available network interfaces.
 
-       If snmp_outgoing_address is set to 255.255.255.255 (the default)
-       it will use the same socket as snmp_incoming_address. Only
-       change this if you want to have SNMP replies sent using another
-       address than where this Squid listens for SNMP queries.
+       If snmp_outgoing_address is not set it will use the same socket
+       as snmp_incoming_address. Only change this if you want to have
+       SNMP replies sent using another address than where this Squid
+       listens for SNMP queries.
 
        NOTE, snmp_incoming_address and snmp_outgoing_address can not have
        the same value since they both use port 3401.
@@ -5109,7 +5109,7 @@ DOC_END
 NAME: udp_incoming_address
 TYPE: address
 LOC:Config.Addrs.udp_incoming
-DEFAULT: 0.0.0.0
+DEFAULT: any_addr
 DOC_START
        udp_incoming_address    is used for UDP packets received from other
                                caches.
@@ -5131,7 +5131,7 @@ DOC_END
 NAME: udp_outgoing_address
 TYPE: address
 LOC: Config.Addrs.udp_outgoing
-DEFAULT: 255.255.255.255
+DEFAULT: no_addr
 DOC_START
        udp_outgoing_address    is used for UDP packets sent out to other
                                caches.
@@ -5333,7 +5333,7 @@ NAME: mcast_miss_addr
 IFDEF: MULTICAST_MISS_STREAM
 TYPE: address
 LOC: Config.mcast_miss.addr
-DEFAULT: 255.255.255.255
+DEFAULT: no_addr
 DOC_START
        If you enable this option, every "cache miss" URL will
        be sent out on the specified multicast address.
index 03a69e3c639dc4bfa0b714deafa8ba10d44df9dc..13cb7bcdf931759f10570dafc64a30fe0684cb15 100644 (file)
@@ -610,16 +610,6 @@ comm_open_listener(int sock_type,
     /* attempt native enabled port. */
     sock = comm_openex(sock_type, proto, addr, flags, 0, note);
 
-#if USE_IPV6
-    /* under IPv6 there is the possibility IPv6 is present but disabled. */
-    /* try again as IPv4-native */
-    if ( sock < 0 && addr.IsIPv6() && addr.SetIPv4() ) {
-        /* attempt to open this IPv4-only. */
-        sock = comm_openex(sock_type, proto, addr, flags, 0, note);
-        debugs(50, 2, HERE << "attempt open " << note << " socket on: " << addr);
-    }
-#endif
-
     return sock;
 }
 
@@ -702,7 +692,24 @@ comm_openex(int sock_type,
 
     debugs(50, 3, "comm_openex: Attempt open socket for: " << addr );
 
-    if ((new_socket = socket(AI->ai_family, AI->ai_socktype, AI->ai_protocol)) < 0) {
+    new_socket = socket(AI->ai_family, AI->ai_socktype, AI->ai_protocol);
+#if USE_IPV6
+    /* under IPv6 there is the possibility IPv6 is present but disabled. */
+    /* try again as IPv4-native if possible */
+    if ( new_socket < 0 && addr.IsIPv6() && addr.SetIPv4() ) {
+        /* attempt to open this IPv4-only. */
+        addr.FreeAddrInfo(AI);
+        /* Setup the socket addrinfo details for use */
+        addr.GetAddrInfo(AI);
+        AI->ai_socktype = sock_type;
+        AI->ai_protocol = proto;
+        debugs(50, 3, "comm_openex: Attempt fallback open socket for: " << addr );
+       new_socket = socket(AI->ai_family, AI->ai_socktype, AI->ai_protocol);
+        debugs(50, 2, HERE << "attempt open " << note << " socket on: " << addr);
+    }
+#endif
+
+    if (new_socket < 0) {
         /* Increase the number of reserved fd's if calls to socket()
          * are failing because the open file table is full.  This
          * limits the number of simultaneous clients */
index 53eedf59616295e919e337078d53494223692276..6ed6234842a7d0f6dce67305f7d8c88f3c1284c1 100644 (file)
@@ -160,9 +160,6 @@ Ip::Address::ApplyMask(Ip::Address const &mask_addr)
         p1[i] &= p2[i];
     }
 
-    /* we have found a situation where mask forms or destroys a IPv4 map. */
-    check4Mapped();
-
     return changes;
 }
 
@@ -287,6 +284,9 @@ const struct in6_addr Ip::Address::v4_localhost = {{{ 0x00, 0x00, 0x00, 0x00, 0x
 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::v6_noaddr = {{{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
             0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }}
 };
@@ -542,9 +542,6 @@ Ip::Address::operator =(struct sockaddr_in const &s)
     memcpy(&m_SocketAddr, &s, sizeof(struct sockaddr_in));
 #endif
 
-    /* maintain stored family values properly */
-    check4Mapped();
-
     return *this;
 };
 
@@ -566,13 +563,6 @@ Ip::Address::operator =(const struct sockaddr_storage &s)
     return *this;
 };
 
-void
-Ip::Address::check4Mapped()
-{
-    // obsolete.
-    // TODO use this NOW to set the sin6_family properly on exporting. not on import.
-}
-
 #if USE_IPV6
 Ip::Address::Address(struct sockaddr_in6 const &s)
 {
@@ -585,8 +575,6 @@ Ip::Address::operator =(struct sockaddr_in6 const &s)
 {
     memcpy(&m_SocketAddr, &s, sizeof(struct sockaddr_in6));
 
-    /* maintain address family properly */
-    check4Mapped();
     return *this;
 };
 #endif
@@ -609,10 +597,6 @@ Ip::Address::operator =(struct in_addr const &s)
     memcpy(&m_SocketAddr.sin_addr, &s, sizeof(struct in_addr));
 
 #endif
-
-    /* maintain stored family type properly */
-    check4Mapped();
-
     return *this;
 };
 
@@ -630,9 +614,6 @@ Ip::Address::operator =(struct in6_addr const &s)
     memcpy(&m_SocketAddr.sin6_addr, &s, sizeof(struct in6_addr));
     m_SocketAddr.sin6_family = AF_INET6;
 
-    /* maintain address family type properly */
-    check4Mapped();
-
     return *this;
 };
 #endif
@@ -1174,15 +1155,13 @@ Ip::Address::Map4to6(const struct in_addr &in, struct in6_addr &out) const
 
     if ( in.s_addr == 0x00000000) {
         /* ANYADDR */
-        memset(&out, 0, sizeof(struct in6_addr));
+        out = v4_anyaddr;
     } else if ( in.s_addr == 0xFFFFFFFF) {
         /* NOADDR */
-        memset(&out, 255, sizeof(struct in6_addr));
+        out = v4_noaddr;
     } else {
         /* general */
-        memset(&out, 0, sizeof(struct in6_addr));
-        out.s6_addr[10] = 0xFF;
-        out.s6_addr[11] = 0xFF;
+        out = v4_anyaddr;
         out.s6_addr[12] = ((uint8_t *)&in.s_addr)[0];
         out.s6_addr[13] = ((uint8_t *)&in.s_addr)[1];
         out.s6_addr[14] = ((uint8_t *)&in.s_addr)[2];
index 8b0b976983aa1bde3f9e40a69f6274fff6bd1371..12612cefbae483078e7bd0f1049442668fa62dd0 100644 (file)
@@ -391,8 +391,6 @@ private:
 
     bool GetReverseString4(char buf[MAX_IPSTRLEN], const struct in_addr &dat) const;
 
-    void check4Mapped();
-
 #if USE_IPV6
 
     bool GetReverseString6(char buf[MAX_IPSTRLEN], const struct in6_addr &dat) const;
@@ -425,6 +423,7 @@ private:
     static const unsigned int MAX_IP6_STRLEN = STRLEN_IP6R;
     static const struct in6_addr v4_localhost;
     static const struct in6_addr v4_anyaddr;
+    static const struct in6_addr v4_noaddr;
     static const struct in6_addr v6_noaddr;
 #endif
 };