# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: henrik@henriknordstrom.net-20100514013827-\
#   3t96ayov9whpmx1h
# target_branch: http://squid-cache.org/bzr/squid3/branches/SQUID_3_1/
# testament_sha1: 82fbabc83ff0884fa2cad3d399ebbd32e4f27488
# timestamp: 2010-05-14 03:38:40 +0200
# base_revision_id: squid3@treenet.co.nz-20100512085735-\
#   85q5fquskamzv6pu
# 
# Begin patch
=== modified file 'src/comm.cc'
--- src/comm.cc	2010-04-23 01:17:20 +0000
+++ src/comm.cc	2010-05-14 01:38:27 +0000
@@ -968,9 +968,6 @@
 int
 ConnectStateData::commResetFD()
 {
-    struct addrinfo *AI = NULL;
-    IpAddress nul;
-    int new_family = AF_UNSPEC;
 
 // XXX: do we have to check this?
 //
@@ -979,21 +976,19 @@
 
     statCounter.syscalls.sock.sockets++;
 
-    /* setup a bare-bones addrinfo */
-    /* TODO INET6: for WinXP we may need to check the local_addr type and setup the family properly. */
-    nul.GetAddrInfo(AI);
-    new_family = AI->ai_family;
+    fde *F = &fd_table[fd];
 
+    struct addrinfo *AI = NULL;
+    F->local_addr.GetAddrInfo(AI);
     int fd2 = socket(AI->ai_family, AI->ai_socktype, AI->ai_protocol);
 
-    nul.FreeAddrInfo(AI);
-
     if (fd2 < 0) {
         debugs(5, DBG_CRITICAL, HERE << "WARNING: FD " << fd2 << " socket failed to allocate: " << xstrerror());
 
         if (ENFILE == errno || EMFILE == errno)
             fdAdjustReserved();
 
+        F->local_addr.FreeAddrInfo(AI);
         return 0;
     }
 
@@ -1013,17 +1008,15 @@
 
         close(fd2);
 
+        F->local_addr.FreeAddrInfo(AI);
         return 0;
     }
     commResetSelect(fd);
 
     close(fd2);
-    fde *F = &fd_table[fd];
-
-    /* INET6: copy the new sockets family type to the FDE table */
-    fd_table[fd].sock_family = new_family;
-
-    fd_table[fd].flags.called_connect = 0;
+
+    F->flags.called_connect = 0;
+
     /*
      * yuck, this has assumptions about comm_open() arguments for
      * the original socket
@@ -1034,9 +1027,6 @@
         comm_set_transparent(fd);
     }
 
-    AI = NULL;
-    F->local_addr.GetAddrInfo(AI);
-
     if (commBind(fd, *AI) != COMM_OK) {
         debugs(5, DBG_CRITICAL, "WARNING: Reset of FD " << fd << " for " << F->local_addr << " failed to bind: " << xstrerror());
         F->local_addr.FreeAddrInfo(AI);
@@ -1104,8 +1094,7 @@
 void
 ConnectStateData::connect()
 {
-    if (S.IsAnyAddr())
-        defaults();
+    defaults();
 
     debugs(5,5, HERE << "to " << S);
 
@@ -1122,15 +1111,22 @@
         callCallback(COMM_OK, 0);
         break;
 
-#if USE_IPV6
     case COMM_ERR_PROTOCOL:
+        debugs(5, 5, HERE "FD " << fd << ": COMM_ERR_PROTOCOL - try again");
         /* problem using the desired protocol over this socket.
-         * count the connection attempt, reset the socket, and immediately try again */
+         * skip to the next address and hope it's more compatible
+         * but do not mark the current address as bad
+         */
         tries++;
-        commResetFD();
-        connect();
+        if (commRetryConnect()) {
+            /* Force an addr cycle to move forward to the next possible address */
+            ipcacheCycleAddr(host, NULL);
+            eventAdd("commReconnect", commReconnect, this, this->addrcount == 1 ? 0.05 : 0.0, 0);
+        } else {
+            debugs(5, 5, HERE << "FD " << fd << ": COMM_ERR_PROTOCOL - ERR tried too many times already.");
+            callCallback(COMM_ERR_CONNECT, errno);
+        }
         break;
-#endif
 
     default:
         debugs(5, 5, HERE "FD " << fd << ": * - try again");
@@ -1232,18 +1228,27 @@
 
     debugs(5, 9, "comm_connect_addr: connecting socket " << sock << " to " << address << " (want family: " << F->sock_family << ")");
 
-    /* BUG 2222 FIX: reset the FD when its found to be IPv4 in IPv6 mode */
-    /* inverse case of IPv4 failing to connect on IPv6 socket is handeld post-connect.
+    /* Handle IPv6 over IPv4-only socket case.
      * this case must presently be handled here since the GetAddrInfo asserts on bad mappings.
-     * eventually we want it to throw a Must() that gets handled there instead of this if.
-     * NP: because commresetFD is private to ConnStateData we have to return an error and
+     * NP: because commResetFD is private to ConnStateData we have to return an error and
      *     trust its handled properly.
      */
-#if USE_IPV6
     if (F->sock_family == AF_INET && !address.IsIPv4()) {
-        return COMM_ERR_PROTOCOL;
-    }
-#endif
+        errno = ENETUNREACH;
+        return COMM_ERR_PROTOCOL;
+    }
+
+    /* Handle IPv4 over IPv6-only socket case.
+     * This case is presently handled here as it's both a known case and it's
+     * uncertain what error will be returned by the IPv6 stack in such case. It's
+     * possible this will also be handled by the errno checks below after connect()
+     * but needs carefull cross-platform verification, and verifying the address
+     * condition here is simple.
+     */
+    if (!F->local_addr.IsIPv4() && address.IsIPv4()) {
+        errno = ENETUNREACH;
+        return COMM_ERR_PROTOCOL;
+    }
 
     address.GetAddrInfo(AI, F->sock_family);
 
@@ -1337,23 +1342,10 @@
         status = COMM_OK;
     else if (ignoreErrno(errno))
         status = COMM_INPROGRESS;
+    else if (errno == EAFNOSUPPORT || errno == EINVAL)
+        return COMM_ERR_PROTOCOL;
     else
-#if USE_IPV6
-        if ( address.IsIPv4() && F->sock_family == AF_INET6 ) {
-
-            /* failover to trying IPv4-only link if an IPv6 one fails */
-            /* to catch the edge case of apps listening on IPv4-localhost */
-            F->sock_family = AF_INET;
-            int res = comm_connect_addr(sock, address);
-
-            /* if that fails too, undo our temporary socktype hack so the repeat works properly. */
-            if (res == COMM_ERROR)
-                F->sock_family = AF_INET6;
-
-            return res;
-        } else
-#endif
-            return COMM_ERROR;
+        return COMM_ERROR;
 
     address.NtoA(F->ipaddr, MAX_IPSTRLEN);
 

# Begin bundle
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

