Fix memory leak in Linux builds.
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: [EMAIL PROTECTED]
# target_branch: file:///src/squid/bzr/trunk/
# testament_sha1: 17d43699f1813e00a034e95f491c5dbb84d791c3
# timestamp: 2008-03-23 23:19:37 +1200
# base_revision_id: [EMAIL PROTECTED]
# bsyr7gm4440gm4s1
#
# Begin patch
=== modified file 'include/IPAddress.h'
--- include/IPAddress.h 2008-03-20 11:30:19 +
+++ include/IPAddress.h 2008-03-22 23:26:24 +
@@ -123,17 +123,13 @@
/[EMAIL PROTECTED]/
IPAddress& operator =(const IPAddress &s);
IPAddress& operator =(IPAddress *s);
-
IPAddress& operator =(struct sockaddr_in const &s);
-
+IPAddress& operator =(struct sockaddr_storage const &s);
IPAddress& operator =(struct in_addr const &s);
#if USE_IPV6
-
IPAddress& operator =(struct in6_addr const &s);
-
IPAddress& operator =(struct sockaddr_in6 const &s);
#endif
-
bool operator =(const struct hostent &s);
bool operator =(const struct addrinfo &s);
bool operator =(const char *s);
@@ -359,6 +355,8 @@
* these functiosn WILL NOT be in the final public API after transition.
*/
+void GetSockAddr(struct sockaddr_storage &addr, const int family) const;
+
/// \deprecated Deprecated for public use. Use IPAddress::GetAddrInfo()
void GetSockAddr(struct sockaddr_in &) const;
=== modified file 'lib/IPAddress.cc'
--- lib/IPAddress.cc 2008-02-15 16:45:57 +
+++ lib/IPAddress.cc 2008-03-22 23:26:24 +
@@ -557,6 +557,24 @@
return *this;
};
+IPAddress& IPAddress::operator =(const sockaddr_storage &s)
+{
+#if USE_IPV6
+/* some AF_* magic to tell socket types apart and what we need to do */
+if(s.ss_family == AF_INET6) {
+memcpy(&m_SocketAddr, &s, sizeof(struct sockaddr_in));
+}
+else { // convert it to our storage mapping.
+struct sockaddr_in *sin = (struct sockaddr_in*)&s;
+m_SocketAddr.sin6_port = sin->sin_port;
+Map4to6( sin->sin_addr, m_SocketAddr.sin6_addr);
+}
+#else
+memcpy(&m_SocketAddr, &s, sizeof(struct sockaddr_in));
+#endif
+return *this;
+};
+
void IPAddress::check4Mapped()
{
// obsolete.
@@ -1065,6 +1083,36 @@
return buf;
}
+void IPAddress::GetSockAddr(struct sockaddr_storage &addr, const int family) const
+{
+if( family == AF_INET && !IsIPv4()) {
+// FIXME INET6: caller using the wrong socket type!
+debugs(14, DBG_CRITICAL, HERE << "IPAddress::GetSockAddr : Cannot convert non-IPv4 to IPv4. from " << *this);
+assert(false);
+}
+
+#if USE_IPV6
+if( IsIPv6() ) {
+memcpy(&addr, &m_SocketAddr, sizeof(struct sockaddr_in6));
+
+if(addr.ss_family == 0)
+addr.ss_family = AF_INET6;
+}
+else if( IsIPv4() ) {
+struct sockaddr_in *sin = (struct sockaddr_in*)&addr;
+addr.ss_family = AF_INET;
+sin->sin_port = m_SocketAddr.sin6_port;
+Map6to4( m_SocketAddr.sin6_addr, sin->sin_addr);
+}
+#else
+struct sockaddr_in *sa = (struct sockaddr_in*)&addr;
+memcpy(&addr, &m_SocketAddr, sizeof(struct sockaddr_in));
+
+if(addr.sa_family == 0)
+addr.sa_family = AF_INET;
+#endif
+}
+
void IPAddress::GetSockAddr(struct sockaddr_in &buf) const
{
#if USE_IPV6
=== modified file 'src/comm.cc'
--- src/comm.cc 2008-02-27 04:49:32 +
+++ src/comm.cc 2008-03-23 10:39:43 +
@@ -1133,15 +1133,16 @@
int x = 0;
int err = 0;
socklen_t errlen;
-struct addrinfo *AI = NULL;
+struct sockaddr_storage sas;
+socklen_t slen = sizeof(struct sockaddr_storage);
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 << ")");
-/* FIXME INET6 : Bug : when sock is an IPv4-only socket IPv6 traffic will crash. */
-address.GetAddrInfo(AI, F->sock_family);
+memset(&sas, NULL, slen);
+address.GetSockAddr(sas, F->sock_family);
/* Establish connection. */
errno = 0;
@@ -1151,7 +1152,7 @@
F->flags.called_connect = 1;
statCounter.syscalls.sock.connects++;
-x = connect(sock, AI->ai_addr, AI->ai_addrlen);
+x = connect(sock, (struct sockaddr*)&sas, slen);
// XXX: ICAP code refuses callbacks during a pending comm_ call
// Async calls development will fix this.
@@ -1163,12 +1164,8 @@
if (x < 0)
{
debugs(5,5, "comm_connect_addr: sock=" << sock << ", addrinfo( " <<
- " flags=" << AI->ai_flags <<
- ", family=" << AI->ai_family <<
- ", socktype=" << AI->ai_socktype <<
- ", protocol=" << AI->ai_protocol <<
- ", &addr=" << AI->ai_addr <<
- ", addrlen=" << AI->ai_addrlen <<
+ ", family=" << sas.ss_family <<
+