From: Amos Jeffries Date: Thu, 3 Apr 2008 21:12:16 +0000 (+1200) Subject: Selectively roll comm_connect_addr part of the Linux leak fix out of trunk. X-Git-Tag: BASIC_TPROXY4~4^2~4 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=feca3b9ae0c9733d768ef47222331d6b7fd38eef;p=thirdparty%2Fsquid.git Selectively roll comm_connect_addr part of the Linux leak fix out of trunk. The IPAddress and configure parts are left to simplify future testing of why it does not work in FreeBSD and what went wrong with the sockaddr_storage. --- diff --git a/src/comm.cc b/src/comm.cc index 57ae5b3572..513c71a2ce 100644 --- a/src/comm.cc +++ b/src/comm.cc @@ -1133,16 +1133,15 @@ comm_connect_addr(int sock, const IPAddress &address) int x = 0; int err = 0; socklen_t errlen; - struct sockaddr_storage sas; - socklen_t slen = sizeof(struct sockaddr_storage); + struct addrinfo *AI = NULL; PROF_start(comm_connect_addr); assert(address.GetPort() != 0); debugs(5, 9, "comm_connect_addr: connecting socket " << sock << " to " << address << " (want family: " << F->sock_family << ")"); - memset(&sas, 0, slen); - address.GetSockAddr(sas, F->sock_family); + /* FIXME INET6 : Bug 2222: when sock is an IPv4-only socket IPv6 traffic will crash. */ + address.GetAddrInfo(AI, F->sock_family); /* Establish connection. */ errno = 0; @@ -1152,7 +1151,7 @@ comm_connect_addr(int sock, const IPAddress &address) F->flags.called_connect = 1; statCounter.syscalls.sock.connects++; - x = connect(sock, (struct sockaddr*)&sas, slen); + x = connect(sock, AI->ai_addr, AI->ai_addrlen); // XXX: ICAP code refuses callbacks during a pending comm_ call // Async calls development will fix this. @@ -1164,8 +1163,12 @@ comm_connect_addr(int sock, const IPAddress &address) if (x < 0) { debugs(5,5, "comm_connect_addr: sock=" << sock << ", addrinfo( " << - ", family=" << sas.ss_family << - ", addrlen=" << slen << + " flags=" << AI->ai_flags << + ", family=" << AI->ai_family << + ", socktype=" << AI->ai_socktype << + ", protocol=" << AI->ai_protocol << + ", &addr=" << AI->ai_addr << + ", addrlen=" << AI->ai_addrlen << " )" ); debugs(5, 9, "connect FD " << sock << ": (" << x << ") " << xstrerror()); debugs(14,9, "connecting to: " << address ); @@ -1175,7 +1178,7 @@ comm_connect_addr(int sock, const IPAddress &address) #if defined(_SQUID_NEWSOS6_) /* Makoto MATSUSHITA */ - connect(sock, (struct sockaddr*)&sas, slen); + connect(sock, AI->ai_addr, AI->ai_addrlen); if (errno == EINVAL) { errlen = sizeof(err); @@ -1208,6 +1211,20 @@ comm_connect_addr(int sock, const IPAddress &address) } +#ifdef _SQUID_LINUX_ + /* 2007-11-27: + * Linux Debian replaces our allocated AI pointer with garbage when + * connect() fails. This leads to segmentation faults deallocating + * the system-allocated memory when we go to clean up our pointer. + * HACK: is to leak the memory returned since we can't deallocate. + */ + if(errno != 0) { + AI = NULL; + } +#endif + + address.FreeAddrInfo(AI); + PROF_stop(comm_connect_addr); if (errno == 0 || errno == EISCONN)