---------------------
PatchSet 5110 
Date: 2007/07/30 03:17:59
Author: amosjeffries
Branch: squid3-ipv6
Tag: (none) 
Log:
Split two initialisation methods of addrinfo.
 - GetAddrInfo still retrieves stored info
 - InitAddrInfo now initialises an empty structure for use by get*() calls
Base code updated to use proper initialisation method.
addrinfo assignment now fails-over to checking family of sockaddr if
 addrinfo family is missing

Members: 
	include/IPAddress.h:1.1.2.24->1.1.2.25 
	lib/IPAddress.cc:1.1.2.57->1.1.2.58 
	src/comm.cc:1.47.2.40->1.47.2.41 
	src/ftp.cc:1.26.2.31->1.26.2.32 
	src/icp_v2.cc:1.17.8.19->1.17.8.20 
	src/ipc.cc:1.9.4.12->1.9.4.13 
	src/neighbors.cc:1.23.4.23->1.23.4.24 
	src/snmp_core.cc:1.10.8.12->1.10.8.13 
	src/wccp.cc:1.10.2.12->1.10.2.13 

Index: squid3/include/IPAddress.h
===================================================================
RCS file: /cvsroot/squid-sf//squid3/include/Attic/IPAddress.h,v
retrieving revision 1.1.2.24
retrieving revision 1.1.2.25
diff -u -r1.1.2.24 -r1.1.2.25
--- squid3/include/IPAddress.h	29 Jul 2007 04:51:00 -0000	1.1.2.24
+++ squid3/include/IPAddress.h	30 Jul 2007 03:17:59 -0000	1.1.2.25
@@ -1,6 +1,6 @@
 
 /*
- * $Id: IPAddress.h,v 1.1.2.24 2007/07/29 04:51:00 amosjeffries Exp $
+ * $Id: IPAddress.h,v 1.1.2.25 2007/07/30 03:17:59 amosjeffries Exp $
  *
  * DEBUG: section 14    IP Storage and Handling
  * AUTHOR: Amos Jeffries
@@ -312,6 +312,14 @@
      */
     void FreeAddrInfo(struct addrinfo *&ai) const;
 
+    /**
+     *  Initializes an empty addrinfo properly for use.
+     *  It is intended for use in cases such as getsockopt() where the addrinfo is
+     *  about to be changed and the stored details may not match the new ones coming.
+     *  \param ai addrinfo struct to be initialized as AF_UNSPEC with large address buffer
+     */
+    void InitAddrInfo(struct addrinfo *&ai) const;
+
 public:
     /* FIXME: When C => C++ conversion is done will be fully private.
      * Legacy Transition Methods.
Index: squid3/lib/IPAddress.cc
===================================================================
RCS file: /cvsroot/squid-sf//squid3/lib/Attic/IPAddress.cc,v
retrieving revision 1.1.2.57
retrieving revision 1.1.2.58
diff -u -r1.1.2.57 -r1.1.2.58
--- squid3/lib/IPAddress.cc	29 Jul 2007 04:51:04 -0000	1.1.2.57
+++ squid3/lib/IPAddress.cc	30 Jul 2007 03:17:59 -0000	1.1.2.58
@@ -1,6 +1,6 @@
 
 /*
- * $Id: IPAddress.cc,v 1.1.2.57 2007/07/29 04:51:04 amosjeffries Exp $
+ * $Id: IPAddress.cc,v 1.1.2.58 2007/07/30 03:17:59 amosjeffries Exp $
  *
  * DEBUG: section 14   IP Storage and Handling
  * AUTHOR: Amos Jeffries
@@ -734,7 +734,23 @@
 #endif
         break;
 
+    case AF_UNSPEC:
     default:
+        // attempt to handle partially initialised addrinfo.
+        // such as those where data only comes from getsockopt()
+        if(s.ai_addr != NULL) {
+#if USE_IPV6
+            if(s.ai_addrlen == sizeof(struct sockaddr_in6)) {
+                operator=(*((struct sockaddr_in6*)s.ai_addr));
+                return true;
+            }
+            else
+#endif
+            if(s.ai_addrlen == sizeof(struct sockaddr_in)) {
+                operator=(*((struct sockaddr_in*)s.ai_addr));
+                return true;
+            }
+        }
         return false;
     }
 
@@ -798,6 +814,23 @@
         }
 }
 
+void IPAddress::InitAddrInfo(struct addrinfo *&ai) const
+{
+    if(ai == NULL) {
+        ai = new addrinfo;
+        memset(ai,0,sizeof(struct addrinfo));
+    }
+
+    // remove any existing data.
+    if(ai->ai_addr) delete ai->ai_addr;
+
+    ai->ai_addr = (struct sockaddr*)new sockaddr_in6;
+    memset(ai->ai_addr, 0, sizeof(struct sockaddr_in6));
+
+    ai->ai_addrlen = sizeof(struct sockaddr_in6);
+
+}
+
 void IPAddress::FreeAddrInfo(struct addrinfo *&ai) const
 {
     if(ai == NULL) return;
Index: squid3/src/comm.cc
===================================================================
RCS file: /cvsroot/squid-sf//squid3/src/comm.cc,v
retrieving revision 1.47.2.40
retrieving revision 1.47.2.41
diff -u -r1.47.2.40 -r1.47.2.41
--- squid3/src/comm.cc	12 Jul 2007 22:22:05 -0000	1.47.2.40
+++ squid3/src/comm.cc	30 Jul 2007 03:17:59 -0000	1.47.2.41
@@ -1,6 +1,6 @@
 
 /*
- * $Id: comm.cc,v 1.47.2.40 2007/07/12 22:22:05 amosjeffries Exp $
+ * $Id: comm.cc,v 1.47.2.41 2007/07/30 03:17:59 amosjeffries Exp $
  *
  * DEBUG: section 5     Socket Functions
  * AUTHOR: Harvest Derived
@@ -723,13 +723,8 @@
     statCounter.syscalls.sock.recvfroms++;
     int x = 0;
     struct addrinfo *AI = NULL;
-    IPAddress nul;
 
-#if USE_IPV6
-    nul.GetAddrInfo(AI, AF_INET6); // IPv6 uses the largest buffers.
-#else
-    nul.GetAddrInfo(AI);
-#endif
+    from.InitAddrInfo(AI);
 
     debugs(5,8, "comm_udp_recvfrom: FD " << fd << " from " << from);
 
@@ -737,7 +732,7 @@
 
     from = *AI;
 
-    nul.FreeAddrInfo(AI);
+    from.FreeAddrInfo(AI);
 
     return x;
 }
@@ -786,9 +781,7 @@
     if (F->local_addr.GetPort())
         return F->local_addr.GetPort();
 
-    // grab default socket information for this address
-    // (does assume its a TCP socket)
-    temp.GetAddrInfo(addr);
+    temp.InitAddrInfo(addr);
 
     if (getsockname(fd, addr->ai_addr, &(addr->ai_addrlen)) ) {
         debugs(50, 1, "comm_local_port: Failed to retrieve TCP/UDP port number for socket: FD " << fd << ": " << xstrerror());
@@ -797,8 +790,13 @@
     }
     temp = *addr;
 
+    temp.FreeAddrInfo(addr);
+
     F->local_addr.SetPort(temp.GetPort());
 
+    // grab default socket information for this address
+    temp.GetAddrInfo(addr);
+
     F->sock_family = addr->ai_family;
 
     temp.FreeAddrInfo(addr);
@@ -880,13 +878,13 @@
     int new_socket;
     fde *F = NULL;
     int tos = 0;
+    struct addrinfo *AI = NULL;
 
     PROF_start(comm_open);
     /* Create socket for accepting new connections. */
     statCounter.syscalls.sock.sockets++;
 
     /* Setup the socket addrinfo details for use */
-    struct addrinfo *AI = NULL;
     addr.GetAddrInfo(AI);
     AI->ai_socktype = sock_type;
     AI->ai_protocol = proto;
@@ -1424,7 +1422,7 @@
     statCounter.syscalls.sock.accepts++;
     int sock;
     struct addrinfo *gai = NULL;
-    details.me.GetAddrInfo(gai);
+    details.me.InitAddrInfo(gai);
 
     if ((sock = accept(fd, gai->ai_addr, &gai->ai_addrlen)) < 0) {
 
@@ -1447,16 +1445,6 @@
         }
     }
 
-#if USE_IPV6
-    if(gai->ai_addrlen == sizeof(struct sockaddr_in6)) {
-        gai->ai_family = ((struct sockaddr_in6*)gai->ai_addr)->sin6_family;
-    }
-    else
-#endif
-    {
-        gai->ai_family = ((struct sockaddr_in*)gai->ai_addr)->sin_family;
-    }
-
     details.peer = *gai;
     details.me.SetEmpty();
 
Index: squid3/src/ftp.cc
===================================================================
RCS file: /cvsroot/squid-sf//squid3/src/ftp.cc,v
retrieving revision 1.26.2.31
retrieving revision 1.26.2.32
diff -u -r1.26.2.31 -r1.26.2.32
--- squid3/src/ftp.cc	26 Jul 2007 23:37:05 -0000	1.26.2.31
+++ squid3/src/ftp.cc	30 Jul 2007 03:17:59 -0000	1.26.2.32
@@ -1,6 +1,6 @@
 
 /*
- * $Id: ftp.cc,v 1.26.2.31 2007/07/26 23:37:05 amosjeffries Exp $
+ * $Id: ftp.cc,v 1.26.2.32 2007/07/30 03:17:59 amosjeffries Exp $
  *
  * DEBUG: section 9     File Transfer Protocol (FTP)
  * AUTHOR: Harvest Derived
@@ -2243,7 +2243,7 @@
         return;
     }
 
-    addr.GetAddrInfo(AI);
+    addr.InitAddrInfo(AI);
 
     if (getsockname(ftpState->ctrl.fd, AI->ai_addr, &AI->ai_addrlen)) {
         addr.FreeAddrInfo(AI);
@@ -2455,7 +2455,7 @@
      * control connection.
      */
 
-    addr.GetAddrInfo(AI);
+    addr.InitAddrInfo(AI);
 
     x = getsockname(ftpState->ctrl.fd, AI->ai_addr, &AI->ai_addrlen);
 
@@ -2511,7 +2511,7 @@
     debugs(9, 3, HERE << "ftpSendPORT started");
     ftpState->flags.pasv_supported = 0;
     fd = ftpOpenListenSocket(ftpState, 0);
-    ipa.GetAddrInfo(AI);
+    ipa.InitAddrInfo(AI);
 
     if (getsockname(fd, AI->ai_addr, &AI->ai_addrlen)) {
         ipa.FreeAddrInfo(AI);
@@ -2571,7 +2571,7 @@
     ftpState->flags.pasv_supported = 0;
     fd = ftpOpenListenSocket(ftpState, 0);
 
-    addr.GetAddrInfo(AI);
+    addr.InitAddrInfo(AI);
 
     if (getsockname(fd, AI->ai_addr, &AI->ai_addrlen)) {
         addr.FreeAddrInfo(AI);
Index: squid3/src/icp_v2.cc
===================================================================
RCS file: /cvsroot/squid-sf//squid3/src/icp_v2.cc,v
retrieving revision 1.17.8.19
retrieving revision 1.17.8.20
diff -u -r1.17.8.19 -r1.17.8.20
--- squid3/src/icp_v2.cc	8 Jun 2007 08:45:16 -0000	1.17.8.19
+++ squid3/src/icp_v2.cc	30 Jul 2007 03:17:59 -0000	1.17.8.20
@@ -1,6 +1,6 @@
 
 /*
- * $Id: icp_v2.cc,v 1.17.8.19 2007/06/08 08:45:16 amosjeffries Exp $
+ * $Id: icp_v2.cc,v 1.17.8.20 2007/07/30 03:17:59 amosjeffries Exp $
  *
  * DEBUG: section 12    Internet Cache Protocol (ICP)
  * AUTHOR: Duane Wessels
@@ -720,9 +720,7 @@
 
     theOutICPAddr.SetEmpty();
 
-    /* IPv6 (via AF_INET6) allocates teh largest buffers possibly needed */
-    /* and addrinfo handles all the nasty magic mapping-unmapping of sockaddr's for us */
-    theOutICPAddr.GetAddrInfo(xai,AF_INET6);
+    theOutICPAddr.InitAddrInfo(xai);
 
     x = getsockname(theOutIcpConnection, xai->ai_addr, &xai->ai_addrlen);
 
Index: squid3/src/ipc.cc
===================================================================
RCS file: /cvsroot/squid-sf//squid3/src/ipc.cc,v
retrieving revision 1.9.4.12
retrieving revision 1.9.4.13
diff -u -r1.9.4.12 -r1.9.4.13
--- squid3/src/ipc.cc	10 Jun 2007 12:03:55 -0000	1.9.4.12
+++ squid3/src/ipc.cc	30 Jul 2007 03:17:59 -0000	1.9.4.13
@@ -1,6 +1,6 @@
 
 /*
- * $Id: ipc.cc,v 1.9.4.12 2007/06/10 12:03:55 amosjeffries Exp $
+ * $Id: ipc.cc,v 1.9.4.13 2007/07/30 03:17:59 amosjeffries Exp $
  *
  * DEBUG: section 54    Interprocess Communication
  * AUTHOR: Duane Wessels
@@ -78,17 +78,15 @@
 ipcCreate(int type, const char *prog, const char *const args[], const char *name, int *rfd, int *wfd, void **hIpc)
 {
     pid_t pid;
-
-    struct sockaddr_in ChS;
-
-    struct sockaddr_in PaS;
+    IPAddress ChS;
+    IPAddress PaS;
+    struct addrinfo *AI = NULL;
     int crfd = -1;
     int prfd = -1;
     int cwfd = -1;
     int pwfd = -1;
     int fd;
     int t1, t2, t3;
-    socklen_t len;
     int x;
 
 #if USE_POLL && defined(_SQUID_OSF_)
@@ -194,25 +192,33 @@
     }
 
     if (type == IPC_TCP_SOCKET || type == IPC_UDP_SOCKET) {
-        len = sizeof(PaS);
-        memset(&PaS, '\0', len);
+        PaS.InitAddrInfo(AI);
 
-        if (getsockname(pwfd, (struct sockaddr *) &PaS, &len) < 0) {
+        if (getsockname(pwfd, AI->ai_addr, &AI->ai_addrlen) < 0) {
+            PaS.FreeAddrInfo(AI);
             debugs(54, 0, "ipcCreate: getsockname: " << xstrerror());
             return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
         }
 
-        debugs(54, 3, "ipcCreate: FD " << pwfd << " sockaddr " << inet_ntoa(PaS.sin_addr) << ":" << ntohs(PaS.sin_port));
+        PaS = *AI;
+
+        debugs(54, 3, "ipcCreate: FD " << pwfd << " sockaddr " << PaS);
 
-        len = sizeof(ChS);
-        memset(&ChS, '\0', len);
+        PaS.FreeAddrInfo(AI);
 
-        if (getsockname(crfd, (struct sockaddr *) &ChS, &len) < 0) {
+        ChS.InitAddrInfo(AI);
+
+        if (getsockname(crfd, AI->ai_addr, &AI->ai_addrlen) < 0) {
+            ChS.FreeAddrInfo(AI);
             debugs(54, 0, "ipcCreate: getsockname: " << xstrerror());
             return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
         }
 
-        debugs(54, 3, "ipcCreate: FD " << crfd << " sockaddr " << inet_ntoa(ChS.sin_addr) << ":" << ntohs(ChS.sin_port));
+        ChS = *AI;
+
+        ChS.FreeAddrInfo(AI);
+
+        debugs(54, 3, "ipcCreate: FD " << crfd << " sockaddr " << ChS );
 
     }
 
@@ -243,8 +249,7 @@
         cwfd = crfd = -1;
 
         if (type == IPC_TCP_SOCKET || type == IPC_UDP_SOCKET) {
-            /* FIXME INET6 : drop temp conversion */ IPAddress tmp(ChS);
-            if (comm_connect_addr(pwfd, tmp) == COMM_ERROR)
+            if (comm_connect_addr(pwfd, ChS) == COMM_ERROR)
                 return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
         }
 
@@ -315,8 +320,7 @@
         close(crfd);
         cwfd = crfd = fd;
     } else if (type == IPC_UDP_SOCKET) {
-        /* FIXME INET6 : drop temp conversion */ IPAddress tmp(PaS);
-        if (comm_connect_addr(crfd, tmp) == COMM_ERROR)
+        if (comm_connect_addr(crfd, PaS) == COMM_ERROR)
             return ipcCloseAllFD(prfd, pwfd, crfd, cwfd);
     }
 
Index: squid3/src/neighbors.cc
===================================================================
RCS file: /cvsroot/squid-sf//squid3/src/neighbors.cc,v
retrieving revision 1.23.4.23
retrieving revision 1.23.4.24
diff -u -r1.23.4.23 -r1.23.4.24
--- squid3/src/neighbors.cc	8 Jun 2007 13:29:11 -0000	1.23.4.23
+++ squid3/src/neighbors.cc	30 Jul 2007 03:17:59 -0000	1.23.4.24
@@ -1,6 +1,6 @@
 
 /*
- * $Id: neighbors.cc,v 1.23.4.23 2007/06/08 13:29:11 amosjeffries Exp $
+ * $Id: neighbors.cc,v 1.23.4.24 2007/07/30 03:17:59 amosjeffries Exp $
  *
  * DEBUG: section 15    Neighbor Routines
  * AUTHOR: Harvest Derived
@@ -495,7 +495,7 @@
     int fd = theInIcpConnection;
 
     /* setup addrinfo for use */
-    nul.GetAddrInfo(AI);
+    nul.InitAddrInfo(AI);
 
     if (fd >= 0) {
 
Index: squid3/src/snmp_core.cc
===================================================================
RCS file: /cvsroot/squid-sf//squid3/src/snmp_core.cc,v
retrieving revision 1.10.8.12
retrieving revision 1.10.8.13
diff -u -r1.10.8.12 -r1.10.8.13
--- squid3/src/snmp_core.cc	15 Jul 2007 09:18:11 -0000	1.10.8.12
+++ squid3/src/snmp_core.cc	30 Jul 2007 03:17:59 -0000	1.10.8.13
@@ -1,6 +1,6 @@
 
 /*
- * $Id: snmp_core.cc,v 1.10.8.12 2007/07/15 09:18:11 amosjeffries Exp $
+ * $Id: snmp_core.cc,v 1.10.8.13 2007/07/30 03:17:59 amosjeffries Exp $
  *
  * DEBUG: section 49    SNMP support
  * AUTHOR: Glenn Chisholm
@@ -410,7 +410,7 @@
 
         theOutSNMPAddr.SetEmpty();
 
-        theOutSNMPAddr.GetAddrInfo(xaddr);
+        theOutSNMPAddr.InitAddrInfo(xaddr);
 
         x = getsockname(theOutSnmpConnection,xaddr->ai_addr, &xaddr->ad_addrlen);
 
@@ -482,7 +482,6 @@
 
     commSetSelect(sock, COMM_SELECT_READ, snmpHandleUdp, NULL, 0);
 
-    from.GetAddrInfo(AI);
     memset(buf, '\0', SNMP_REQUEST_SIZE);
 
     len = comm_udp_recvfrom(sock,
@@ -491,7 +490,7 @@
                             0,
                             from);
 
-    /* INET6 : SNMP still has no IPv6 Support */
+    /* INET6 : SNMP still has no IPv6 Support. Requires IPv6 'from' in line-data snmp_rq packets */
     if(!from.IsIPv4()) {
         debugs(49,1, "snmpHandleUdp: FD " << sock << " cannot handle data from non-IPv4 source " << from);
     }
Index: squid3/src/wccp.cc
===================================================================
RCS file: /cvsroot/squid-sf//squid3/src/wccp.cc,v
retrieving revision 1.10.2.12
retrieving revision 1.10.2.13
diff -u -r1.10.2.12 -r1.10.2.13
--- squid3/src/wccp.cc	4 Jun 2007 06:54:25 -0000	1.10.2.12
+++ squid3/src/wccp.cc	30 Jul 2007 03:17:59 -0000	1.10.2.13
@@ -1,6 +1,6 @@
 
 /*
- * $Id: wccp.cc,v 1.10.2.12 2007/06/04 06:54:25 amosjeffries Exp $
+ * $Id: wccp.cc,v 1.10.2.13 2007/07/30 03:17:59 amosjeffries Exp $
  *
  * DEBUG: section 80    WCCP Support
  * AUTHOR: Glenn Chisholm
@@ -170,16 +170,14 @@
 
     Config.Wccp.router.FreeAddrInfo(router);
 
-    Config.Wccp.address.GetAddrInfo(local,AF_INET);
-
-    memset(local->ai_addr, '\0', local->ai_addrlen);
+    Config.Wccp.address.InitAddrInfo(local);
 
     if (getsockname(theWccpConnection, local->ai_addr, &local->ai_addrlen))
         fatal("Unable to getsockname on WCCP out socket");
 
     local_ip = *local;
 
-     Config.Wccp.address.FreeAddrInfo(local);
+    Config.Wccp.address.FreeAddrInfo(local);
 }
 
 
