From: Henrik Nordstrom Date: Fri, 14 May 2010 05:37:19 +0000 (+0200) Subject: Fall back on IPv4 if IPv6 is not present X-Git-Tag: SQUID_3_2_0_1~213 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=0eb08770c21df436e29b9cecf5c6b3812f212caa;p=thirdparty%2Fsquid.git Fall back on IPv4 if IPv6 is not present 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. --- diff --git a/src/cf.data.pre b/src/cf.data.pre index 59934e034d..32b93edba5 100644 --- a/src/cf.data.pre +++ b/src/cf.data.pre @@ -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. diff --git a/src/comm.cc b/src/comm.cc index 03a69e3c63..13cb7bcdf9 100644 --- a/src/comm.cc +++ b/src/comm.cc @@ -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 */ diff --git a/src/ip/Address.cc b/src/ip/Address.cc index 53eedf5961..6ed6234842 100644 --- a/src/ip/Address.cc +++ b/src/ip/Address.cc @@ -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]; diff --git a/src/ip/Address.h b/src/ip/Address.h index 8b0b976983..12612cefba 100644 --- a/src/ip/Address.h +++ b/src/ip/Address.h @@ -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 };