Without a shared cache, the servers will report many false misses.
ICP and HTCP _clients_ cannot be supported in SMP environment unless each
process has its own address (i.e., unique IP address and/or unique [ICP] port)
because we cannot match outgoing queries and incoming responses across
processes. If ICP/HTCP support in SMP is needed, the easiest change would
be to use random source ports for sending ICP/HTCP queries. This may also
improve security by avoiding well-known source ports for UDP queries.
#include "http.h"
#include "icmp/net_db.h"
#include "AccessLogEntry.h"
+#include "ipc/StartListening.h"
+
+/// dials htcpIncomingConnectionOpened call
+class HtcpListeningStartedDialer: public CallDialer,
+ public Ipc::StartListeningCb
+{
+public:
+ typedef void (*Handler)(int fd, int errNo);
+ HtcpListeningStartedDialer(Handler aHandler): handler(aHandler) {}
+
+ virtual void print(std::ostream &os) const { startPrint(os) << ')'; }
+
+ virtual bool canDial(AsyncCall &) const { return true; }
+ virtual void dial(AsyncCall &) { (handler)(fd, errNo); }
+
+public:
+ Handler handler;
+};
typedef struct _Countstr Countstr;
RR_RESPONSE
};
+static void htcpIncomingConnectionOpened(int fd, int errNo);
+
static u_int32_t msg_id_counter = 0;
static int htcpInSocket = -1;
static int htcpOutSocket = -1;
IpAddress incomingAddr = Config.Addrs.udp_incoming;
incomingAddr.SetPort(Config.Port.htcp);
- enter_suid();
- htcpInSocket = comm_open_listener(SOCK_DGRAM,
+ AsyncCall::Pointer call = asyncCall(31, 2,
+ "htcpIncomingConnectionOpened",
+ HtcpListeningStartedDialer(&htcpIncomingConnectionOpened));
+
+ Ipc::StartListening(SOCK_DGRAM,
IPPROTO_UDP,
incomingAddr,
COMM_NONBLOCKING,
- "HTCP Socket");
- leave_suid();
-
- if (htcpInSocket < 0)
- fatal("Cannot open HTCP Socket");
-
- commSetSelect(htcpInSocket, COMM_SELECT_READ, htcpRecv, NULL, 0);
-
- debugs(31, 1, "Accepting HTCP messages on port " << Config.Port.htcp << ", FD " << htcpInSocket << ".");
+ Ipc::fdnInHtcpSocket, call);
if (!Config.Addrs.udp_outgoing.IsNoAddr()) {
IpAddress outgoingAddr = Config.Addrs.udp_outgoing;
debugs(31, 1, "Outgoing HTCP messages on port " << Config.Port.htcp << ", FD " << htcpOutSocket << ".");
fd_note(htcpInSocket, "Incoming HTCP socket");
- } else {
- htcpOutSocket = htcpInSocket;
}
if (!htcpDetailPool) {
}
}
+static void
+htcpIncomingConnectionOpened(int fd, int errNo)
+{
+ htcpInSocket = fd;
+
+ if (htcpInSocket < 0)
+ fatal("Cannot open HTCP Socket");
+
+ commSetSelect(htcpInSocket, COMM_SELECT_READ, htcpRecv, NULL, 0);
+
+ debugs(31, 1, "Accepting HTCP messages on port " << Config.Port.htcp << ", FD " << htcpInSocket << ".");
+
+ if (Config.Addrs.udp_outgoing.IsNoAddr())
+ htcpOutSocket = htcpInSocket;
+}
+
int
htcpQuery(StoreEntry * e, HttpRequest * req, peer * p)
{
#include "SwapDir.h"
#include "icmp/net_db.h"
#include "ip/IpAddress.h"
+#include "ipc/StartListening.h"
#include "rfc1738.h"
+/// dials icpIncomingConnectionOpened call
+class IcpListeningStartedDialer: public CallDialer,
+ public Ipc::StartListeningCb
+{
+public:
+ typedef void (*Handler)(int fd, int errNo, IpAddress& addr);
+ IcpListeningStartedDialer(Handler aHandler, IpAddress& anAddr):
+ handler(aHandler), addr(anAddr) {}
+
+ virtual void print(std::ostream &os) const { startPrint(os) <<
+ ", address=" << addr << ')'; }
+
+ virtual bool canDial(AsyncCall &) const { return true; }
+ virtual void dial(AsyncCall &) { (handler)(fd, errNo, addr); }
+
+public:
+ Handler handler;
+ IpAddress addr;
+};
+
+static void icpIncomingConnectionOpened(int fd, int errNo, IpAddress& addr);
+
/// \ingroup ServerProtocolICPInternal2
static void icpLogIcp(const IpAddress &, log_type, int, const char *, int);
struct addrinfo *xai = NULL;
int x;
- wordlist *s;
if ((port = Config.Port.icp) <= 0)
return;
- enter_suid();
-
addr = Config.Addrs.udp_incoming;
addr.SetPort(port);
- theInIcpConnection = comm_open_listener(SOCK_DGRAM,
+
+ AsyncCall::Pointer call = asyncCall(12, 2,
+ "icpIncomingConnectionOpened",
+ IcpListeningStartedDialer(&icpIncomingConnectionOpened, addr));
+
+ Ipc::StartListening(SOCK_DGRAM,
IPPROTO_UDP,
addr,
COMM_NONBLOCKING,
- "ICP Socket");
- leave_suid();
-
- if (theInIcpConnection < 0)
- fatal("Cannot open ICP Port");
-
- commSetSelect(theInIcpConnection,
- COMM_SELECT_READ,
- icpHandleUdp,
- NULL,
- 0);
-
- for (s = Config.mcast_group_list; s; s = s->next)
- ipcache_nbgethostbyname(s->key, mcastJoinGroups, NULL);
-
- debugs(12, 1, "Accepting ICP messages at " << addr << ", FD " << theInIcpConnection << ".");
+ Ipc::fdnInIcpSocket, call);
addr.SetEmpty(); // clear for next use.
addr = Config.Addrs.udp_outgoing;
debugs(12, 1, "Outgoing ICP messages on port " << addr.GetPort() << ", FD " << theOutIcpConnection << ".");
fd_note(theOutIcpConnection, "Outgoing ICP socket");
-
- fd_note(theInIcpConnection, "Incoming ICP socket");
- } else {
- theOutIcpConnection = theInIcpConnection;
}
theOutICPAddr.SetEmpty();
theOutICPAddr.FreeAddrInfo(xai);
}
+static void
+icpIncomingConnectionOpened(int fd, int errNo, IpAddress& addr)
+{
+ theInIcpConnection = fd;
+
+ if (theInIcpConnection < 0)
+ fatal("Cannot open ICP Port");
+
+ commSetSelect(theInIcpConnection,
+ COMM_SELECT_READ,
+ icpHandleUdp,
+ NULL,
+ 0);
+
+ for (const wordlist *s = Config.mcast_group_list; s; s = s->next)
+ ipcache_nbgethostbyname(s->key, mcastJoinGroups, NULL);
+
+ debugs(12, 1, "Accepting ICP messages at " << addr << ", FD " << theInIcpConnection << ".");
+
+ fd_note(theInIcpConnection, "Incoming ICP socket");
+
+ if (Config.Addrs.udp_outgoing.IsNoAddr())
+ theOutIcpConnection = theInIcpConnection;
+}
+
/**
* icpConnectionShutdown only closes the 'in' socket if it is
* different than the 'out' socket.
"HTTP Socket", // fdnHttpSocket
"HTTPS Socket", // fdnHttpsSocket
"Incoming SNMP Socket", // fdnInSnmpSocket
- "Outgoing SNMP Socket" // fdnOutSnmpSocket
+ "Outgoing SNMP Socket", // fdnOutSnmpSocket
+ "Incoming ICP Socket", // fdnInIcpSocket
+ "Incoming HTCP Socket" // fdnInHtcpSocket
};
if (fdnNone < fdNoteId && fdNoteId < fdnEnd)
/// fd_note() label ID
typedef enum { fdnNone, fdnHttpSocket, fdnHttpsSocket,
- fdnInSnmpSocket, fdnOutSnmpSocket, fdnEnd } FdNoteId;
+ fdnInSnmpSocket, fdnOutSnmpSocket,
+ fdnInIcpSocket, fdnInHtcpSocket, fdnEnd } FdNoteId;
extern const char *FdNote(int fdNodeId); ///< converts FdNoteId into a string