=== 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++;