dst->ai_addrlen = sizeof(struct sockaddr_in6);
dst->ai_family = ((struct sockaddr_in6*)dst->ai_addr)->sin6_family;
+
+#if 0
+ /**
+ * Enable only if you must and please report to squid-dev if you find a need for this.
+ *
+ * Vista may need this to cope with dual-stack (unsetting IP6_V6ONLY).
+ * http://msdn.microsoft.com/en-us/library/ms738574(VS.85).aspx
+ * Linux appears to only do some things when its present.
+ * (93) Bad Protocol
+ * FreeBSD dies horribly when using dual-stack with it set.
+ * (43) Protocol not supported
+ */
dst->ai_protocol = IPPROTO_IPV6;
+#endif
+
} else
#endif
if( force == AF_INET || (force == AF_UNSPEC && IsIPv4()) )
{
struct addrinfo *AI = NULL;
IPAddress nul;
+ int new_family = AF_UNSPEC;
// XXX: do we have to check this?
//
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;
int fd2 = socket(AI->ai_family, AI->ai_socktype, AI->ai_protocol);
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;
/*
* yuck, this has assumptions about comm_open() arguments for
callCallback(COMM_OK, 0);
break;
+#if USE_IPV6
+ case COMM_ERR_PROTOCOL:
+ /* problem using the desired protocol over this socket.
+ * count the connection attempt, reset the socket, and immediately try again */
+ tries++;
+ commResetFD();
+ connect();
+ break;
+#endif
+
default:
debugs(5, 5, HERE "FD " << fd << ": * - try again");
tries++;
debugs(5, 9, "comm_connect_addr: connecting socket " << sock << " to " << address << " (want family: " << F->sock_family << ")");
- /* FIXME INET6 : Bug 2222: when sock is an IPv4-only socket IPv6 traffic will crash. */
+ /* 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.
+ * 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
+ * trust its handled properly.
+ */
+#if USE_IPV6
+ if(F->sock_family == AF_INET && !address.IsIPv4()) {
+ return COMM_ERR_PROTOCOL;
+ }
+#endif
+
address.GetAddrInfo(AI, F->sock_family);
/* Establish connection. */