- The "Sender Host Address" field of the ICP messages header it is a
32bit integer so it can be only an ipv4 ip address. Moreover according
the ICP RFC:
"Sender Host Address
The IPv4 address of the host sending the ICP message. This field
should probably not be trusted over what is provided by getpeer-
name(), accept(), and recvfrom(). There is some ambiguity over
the original purpose of this field. In practice it is not used."
This patch in the case we have an IPv4 address set this header field
with the IPv4 address else set it to 0.
- Remove the echo_hdr static variable from neighbors.cc file and the
theIcpPublicHostID variable from the icp_v2.cc file. They are part of
the old "source_ping" squid feature code which does not exit any more.
=== 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++;