]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
author: Christos Tsantilas <chtsanti@users.sourceforge.net>, Amos Jeffries <squid3...
authorChristos Tsantilas <chtsanti@users.sourceforge.net>
Sun, 7 Aug 2011 10:26:09 +0000 (13:26 +0300)
committerChristos Tsantilas <chtsanti@users.sourceforge.net>
Sun, 7 Aug 2011 10:26:09 +0000 (13:26 +0300)
Bug fix: The Ip::Address::IsAnyAddr method return false for IPv4 anyaddr.

 - The ip::Address::IsAnyAddr() returns true only for ipv6 anyaddr
   (0000:0000:0000:0000:0000:0000:0000:0000) and returns false when we have an
   ipv4 anyaddr (0000:0000:0000:0000:0000:FFFF:0000:0000)

 - The ip::Address::IsIPv4 method returns false in the case of IPv4 anyaddr.

The above can cause bugs, eg:
 - inside Ip::Address::SetIPv4(). When it is called for an IPv6 anyaddr the ip
   address will  not considred as anyaddr any morei (it IsAnyAddr will return
   false).

 - inside cache_cf.cc file inside dump_generic_http_port function:
   if (s->s.IsAnyAddr() && !s->s.IsIPv6())
        storeAppendPrintf(e, " ipv4");
   The if condition in the above statement can never be true. But the s->s can
   be an ipv4 anyaddr.

 - other places where the code will not work as expected in the case we are
   listening to an ipv4 anyaddr ip address.

This patch:
  - moving the IsIPv4/6 to base purely on the v4-mapped or not
  - making both protocols ANYADDR match the same test
  - making both protocols NOADDR match the same test
  - Fixing the IsIPv4/6 documentation to match the implementation

src/ip/Address.cc
src/ip/Address.h

index 420b9689287c9973109ce8f28b3c118032885c20..6c521873d8c7e8f65fecafcebfa4aaa410749c55 100644 (file)
@@ -173,19 +173,19 @@ Ip::Address::IsSockAddr() const
 bool
 Ip::Address::IsIPv4() const
 {
-    return IsAnyAddr() || IsNoAddr() || IN6_IS_ADDR_V4MAPPED( &m_SocketAddr.sin6_addr );
+    return IN6_IS_ADDR_V4MAPPED( &m_SocketAddr.sin6_addr );
 }
 
 bool
 Ip::Address::IsIPv6() const
 {
-    return IsAnyAddr() || IsNoAddr() || !IN6_IS_ADDR_V4MAPPED( &m_SocketAddr.sin6_addr );
+    return !IsIPv4();
 }
 
 bool
 Ip::Address::IsAnyAddr() const
 {
-    return IN6_IS_ADDR_UNSPECIFIED( &m_SocketAddr.sin6_addr );
+    return IN6_IS_ADDR_UNSPECIFIED( &m_SocketAddr.sin6_addr ) || IN6_ARE_ADDR_EQUAL( &m_SocketAddr.sin6_addr, &v4_anyaddr); ;
 }
 
 /// NOTE: Does NOT clear the Port stored. Ony the Address and Type.
@@ -237,6 +237,11 @@ Ip::Address::SetIPv4()
         return true;
     }
 
+    if ( IsNoAddr() ) {
+        m_SocketAddr.sin6_addr = v4_noaddr;
+        return true;
+    }
+
     if ( IsIPv4())
         return true;
 
@@ -279,7 +284,8 @@ bool
 Ip::Address::IsNoAddr() const
 {
     // IFF the address == 0xff..ff (all ones)
-    return IN6_ARE_ADDR_EQUAL( &m_SocketAddr.sin6_addr, &v6_noaddr );
+    return IN6_ARE_ADDR_EQUAL( &m_SocketAddr.sin6_addr, &v6_noaddr )
+        || IN6_ARE_ADDR_EQUAL( &m_SocketAddr.sin6_addr, &v4_noaddr );
 }
 
 void
index 15920ca901a7506803ba733379c30965eeb0fe27..8792d9c589da42e2b425d54c69ef58bd0cd20792 100644 (file)
@@ -123,16 +123,14 @@ public:
     /* methods */
 
     /** Test whether content can be used as an IPv4 address
-     \retval true  if content was received as an IPv4 address
      \retval true  if content was received as an IPv4-Mapped address
      \retval false if content was received as a non-mapped IPv6 native address.
      */
     bool IsIPv4() const;
 
     /** Test whether content can be used as an IPv6 address.
-     \retval true  if --enable-ipv6 has been compiled.
-     \retval false if --disable-ipv6 has been compiled.
-     \retval false if --with-ipv6-split-stack has been compiled AND content is IPv4-mapped.
+     \retval true  if content is a non IPv4-mapped address.
+     \retval false if content is IPv4-mapped.
      */
     bool IsIPv6() const;