=== modified file 'src/icp_v2.cc'
--- src/icp_v2.cc	2011-07-16 15:21:48 +0000
+++ src/icp_v2.cc	2011-07-26 13:36:00 +0000
@@ -88,50 +88,43 @@
 
 /**
  \ingroup ServerProtocolICPInternal2
  * IcpQueueHead is global so comm_incoming() knows whether or not
  * to call icpUdpSendQueue.
  */
 static icpUdpData *IcpQueueHead = NULL;
 /// \ingroup ServerProtocolICPInternal2
 static icpUdpData *IcpQueueTail = NULL;
 
 /// \ingroup ServerProtocolICPInternal2
 Comm::ConnectionPointer icpIncomingConn = NULL;
 /// \ingroup ServerProtocolICPInternal2
 Comm::ConnectionPointer icpOutgoingConn = NULL;
 
 /** \ingroup ServerProtocolICPInternal2
  * ICP v2 uses the outgoing address as host ID.
  * NP: this *may* be identical to icpOutgoingConn->local
  * but when IN/OUT sockets are shared we can't guarantee that
  * so a separate variable is used for now.
- *
- * We have one for private use (sent only by this local cache)
- * and one for public use (for external caches to contact us)
  */
 Ip::Address theIcpPrivateHostID;
 
-/// \see theIcpPrivateHostID
-Ip::Address theIcpPublicHostID;
-
-
 /* icp_common_t */
 _icp_common_t::_icp_common_t() : opcode(ICP_INVALID), version(0), length(0), reqnum(0), flags(0), pad(0), shostid(0)
 {}
 
 _icp_common_t::_icp_common_t(char *buf, unsigned int len)
 {
     if (len < sizeof(_icp_common_t)) {
         /* mark as invalid */
         length = len + 1;
         return;
     }
 
     memcpy(this, buf, sizeof(icp_common_t));
     /*
      * Convert network order sensitive fields
      */
     length = ntohs(length);
     reqnum = ntohl(reqnum);
     flags = ntohl(flags);
     pad = ntohl(pad);
@@ -282,41 +275,44 @@
 
     if (opcode == ICP_QUERY)
         buf_len += sizeof(uint32_t);
 
     buf = (char *) xcalloc(buf_len, 1);
 
     headerp = (icp_common_t *) (void *) buf;
 
     headerp->opcode = (char) opcode;
 
     headerp->version = ICP_VERSION_CURRENT;
 
     headerp->length = (uint16_t) htons(buf_len);
 
     headerp->reqnum = htonl(reqnum);
 
     headerp->flags = htonl(flags);
 
     headerp->pad = htonl(pad);
 
-    theIcpPrivateHostID.GetInAddr( *((struct in_addr*)&headerp->shostid) );
+    if (theIcpPrivateHostID.IsIPv4())
+        theIcpPrivateHostID.GetInAddr( *((struct in_addr*)&headerp->shostid) );
+    else
+        headerp->shostid = 0;
 
     urloffset = buf + sizeof(icp_common_t);
 
     if (opcode == ICP_QUERY)
         urloffset += sizeof(uint32_t);
 
     memcpy(urloffset, url, strlen(url));
 
     return (icp_common_t *)buf;
 }
 
 int
 icpUdpSend(int fd,
            const Ip::Address &to,
            icp_common_t * msg,
            log_type logcode,
            int delay)
 {
     icpUdpData *queue;
     int x;
@@ -746,73 +742,65 @@
         Comm::SetSelect(icpOutgoingConn->fd, COMM_SELECT_READ, icpHandleUdp, NULL, 0);
         fd_note(icpOutgoingConn->fd, "Outgoing ICP socket");
         icpGetOutgoingIpAddress();
     }
 }
 
 // Ensure that we have the IP address(es) to use for Host ID.
 // The outgoing address is used as 'private' host ID used only on packets we send
 static void
 icpGetOutgoingIpAddress()
 {
     struct addrinfo *xai = NULL;
     theIcpPrivateHostID.SetEmpty();
     theIcpPrivateHostID.InitAddrInfo(xai);
     if (getsockname(icpOutgoingConn->fd, xai->ai_addr, &xai->ai_addrlen) < 0)
         debugs(50, DBG_IMPORTANT, "ERROR: Unable to identify ICP host ID to use for " << icpOutgoingConn
                << ": getsockname: " << xstrerror());
     else
         theIcpPrivateHostID = *xai;
     theIcpPrivateHostID.FreeAddrInfo(xai);
+
+    // The icp Host ID can be only an ipv4 address
+    theIcpPrivateHostID.SetIPv4();
 }
 
 static void
 icpIncomingConnectionOpened(int errNo)
 {
     if (!Comm::IsConnOpen(icpIncomingConn))
         fatal("Cannot open ICP Port");
 
     Comm::SetSelect(icpIncomingConn->fd, COMM_SELECT_READ, icpHandleUdp, NULL, 0);
 
     for (const wordlist *s = Config.mcast_group_list; s; s = s->next)
         ipcache_nbgethostbyname(s->key, mcastJoinGroups, NULL); // XXX: pass the icpIncomingConn for mcastJoinGroups usage.
 
     debugs(12, DBG_IMPORTANT, "Accepting ICP messages on " << icpIncomingConn->local);
 
     fd_note(icpIncomingConn->fd, "Incoming ICP port");
 
     if (Config.Addrs.udp_outgoing.IsNoAddr()) {
         icpOutgoingConn = icpIncomingConn;
         debugs(12, DBG_IMPORTANT, "Sending ICP messages from " << icpOutgoingConn->local);
         icpGetOutgoingIpAddress();
     }
-
-    // Ensure that we have the IP address(es) to use for Host ID.
-    // The listening address is used as 'public' host ID which can be used to contact us
-    struct addrinfo *xai = NULL;
-    theIcpPublicHostID.InitAddrInfo(xai); // reset xai
-    if (getsockname(icpIncomingConn->fd, xai->ai_addr, &xai->ai_addrlen) < 0)
-        debugs(50, DBG_IMPORTANT, "ERROR: Unable to identify ICP host ID to use for " << icpIncomingConn
-               << ": getsockname: " << xstrerror());
-    else
-        theIcpPublicHostID = *xai;
-    theIcpPublicHostID.FreeAddrInfo(xai);
 }
 
 /**
  * icpConnectionShutdown only closes the 'in' socket if it is
  * different than the 'out' socket.
  */
 void
 icpConnectionShutdown(void)
 {
     if (!Comm::IsConnOpen(icpIncomingConn))
         return;
 
     debugs(12, DBG_IMPORTANT, "Stop receiving ICP on " << icpIncomingConn->local);
 
     /** Release the 'in' socket for lazy closure.
      * in and out sockets may be sharing one same FD.
      * This prevents this function from executing repeatedly.
      */
     icpIncomingConn = NULL;
 

=== modified file 'src/neighbors.cc'
--- src/neighbors.cc	2011-07-20 07:35:53 +0000
+++ src/neighbors.cc	2011-07-26 10:08:56 +0000
@@ -60,41 +60,40 @@
 static void neighborRemove(peer *);
 static void neighborAlive(peer *, const MemObject *, const icp_common_t *);
 #if USE_HTCP
 static void neighborAliveHtcp(peer *, const MemObject *, const htcpReplyData *);
 #endif
 static void neighborCountIgnored(peer *);
 static void peerRefreshDNS(void *);
 static IPH peerDNSConfigure;
 static bool peerProbeConnect(peer *);
 static CNCB peerProbeConnectDone;
 static void peerCountMcastPeersDone(void *data);
 static void peerCountMcastPeersStart(void *data);
 static void peerCountMcastPeersSchedule(peer * p, time_t when);
 static IRCB peerCountHandleIcpReply;
 
 static void neighborIgnoreNonPeer(const Ip::Address &, icp_opcode);
 static OBJH neighborDumpPeers;
 static OBJH neighborDumpNonPeers;
 static void dump_peers(StoreEntry * sentry, peer * peers);
 
-static icp_common_t echo_hdr;
 static u_short echo_port;
 
 static int NLateReplies = 0;
 static peer *first_ping = NULL;
 
 const char *
 neighborTypeStr(const peer * p)
 {
     if (p->type == PEER_NONE)
         return "Non-Peer";
 
     if (p->type == PEER_SIBLING)
         return "Sibling";
 
     if (p->type == PEER_MULTICAST)
         return "Multicast Group";
 
     return "Parent";
 }
 
@@ -548,51 +547,42 @@
                 continue;
 
             for (s = Config.Sockaddr.http; s; s = s->next) {
                 if (thisPeer->http_port != s->s.GetPort())
                     continue;
 
                 debugs(15, DBG_IMPORTANT, "WARNING: Peer looks like this host");
 
                 debugs(15, DBG_IMPORTANT, "         Ignoring " <<
                        neighborTypeStr(thisPeer) << " " << thisPeer->host <<
                        "/" << thisPeer->http_port << "/" <<
                        thisPeer->icp.port);
 
                 neighborRemove(thisPeer);
             }
         }
     }
 
     peerRefreshDNS((void *) 1);
 
-    if (echo_hdr.opcode == ICP_INVALID) {
-        echo_hdr.opcode = ICP_SECHO;
-        echo_hdr.version = ICP_VERSION_CURRENT;
-        echo_hdr.length = 0;
-        echo_hdr.reqnum = 0;
-        echo_hdr.flags = 0;
-        echo_hdr.pad = 0;
-        theIcpPublicHostID.GetInAddr( *((struct in_addr*)&echo_hdr.shostid) );
-        sep = getservbyname("echo", "udp");
-        echo_port = sep ? ntohs((u_short) sep->s_port) : 7;
-    }
+    sep = getservbyname("echo", "udp");
+    echo_port = sep ? ntohs((u_short) sep->s_port) : 7;
 
     first_ping = Config.peers;
 }
 
 int
 neighborsUdpPing(HttpRequest * request,
                  StoreEntry * entry,
                  IRCB * callback,
                  void *callback_data,
                  int *exprep,
                  int *timeout)
 {
     const char *url = entry->url();
     MemObject *mem = entry->mem_obj;
     peer *p = NULL;
     int i;
     int reqnum = 0;
     int flags;
     icp_common_t *query;
     int queries_sent = 0;
@@ -636,41 +626,40 @@
             if (Config.Port.htcp <= 0) {
                 debugs(15, DBG_CRITICAL, "HTCP is disabled! Cannot send HTCP request to peer.");
                 continue;
             }
 
             debugs(15, 3, "neighborsUdpPing: sending HTCP query");
             if (htcpQuery(entry, request, p) <= 0) continue; // unable to send.
         } else
 #endif
         {
             if (Config.Port.icp <= 0 || !Comm::IsConnOpen(icpOutgoingConn)) {
                 debugs(15, DBG_CRITICAL, "ICP is disabled! Cannot send ICP request to peer.");
                 continue;
             } else {
 
                 if (p->type == PEER_MULTICAST)
                     mcastSetTtl(icpOutgoingConn->fd, p->mcast.ttl);
 
                 if (p->icp.port == echo_port) {
                     debugs(15, 4, "neighborsUdpPing: Looks like a dumb cache, send DECHO ping");
-                    echo_hdr.reqnum = reqnum;
                     query = _icp_common_t::createMessage(ICP_DECHO, 0, url, reqnum, 0);
                     icpUdpSend(icpOutgoingConn->fd, p->in_addr, query, LOG_ICP_QUERY, 0);
                 } else {
                     flags = 0;
 
                     if (Config.onoff.query_icmp)
                         if (p->icp.version == ICP_VERSION_2)
                             flags |= ICP_FLAG_SRC_RTT;
 
                     query = _icp_common_t::createMessage(ICP_QUERY, flags, url, reqnum, 0);
 
                     icpUdpSend(icpOutgoingConn->fd, p->in_addr, query, LOG_ICP_QUERY, 0);
                 }
             }
         }
 
         queries_sent++;
 
         p->stats.pings_sent++;
 


