From: Alex Rousskov Date: Sat, 5 Jun 2010 18:32:22 +0000 (-0600) Subject: Replaced blocking comm_open_listener() call for incoming and outgoing SNMP X-Git-Tag: SQUID_3_2_0_1~93^2~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7b1e5eb4f69eeb46a9f4586f5c83512ecacc928a;p=thirdparty%2Fsquid.git Replaced blocking comm_open_listener() call for incoming and outgoing SNMP ports with Ipc::StartListening calls, to use the "shared listen" feature when doing SMP. --- diff --git a/src/ipc/FdNotes.cc b/src/ipc/FdNotes.cc index 4412f9e121..6c2a992011 100644 --- a/src/ipc/FdNotes.cc +++ b/src/ipc/FdNotes.cc @@ -16,7 +16,9 @@ Ipc::FdNote(int fdNoteId) static const char *FdNotes[Ipc::fdnEnd] = { "None", // fdnNone "HTTP Socket", // fdnHttpSocket - "HTTPS Socket" // fdnHttpsSocket + "HTTPS Socket", // fdnHttpsSocket + "Incoming SNMP Socket", // fdnInSnmpSocket + "Outgoing SNMP Socket" // fdnOutSnmpSocket }; if (fdnNone < fdNoteId && fdNoteId < fdnEnd) diff --git a/src/ipc/FdNotes.h b/src/ipc/FdNotes.h index 20cc9622e4..74deca3456 100644 --- a/src/ipc/FdNotes.h +++ b/src/ipc/FdNotes.h @@ -14,7 +14,8 @@ namespace Ipc /// We cannot send char* FD notes to other processes. Pass int IDs and convert. /// fd_note() label ID -typedef enum { fdnNone, fdnHttpSocket, fdnHttpsSocket, fdnEnd } FdNoteId; +typedef enum { fdnNone, fdnHttpSocket, fdnHttpsSocket, + fdnInSnmpSocket, fdnOutSnmpSocket, fdnEnd } FdNoteId; extern const char *FdNote(int fdNodeId); ///< converts FdNoteId into a string diff --git a/src/snmp_core.cc b/src/snmp_core.cc index d27c781442..e67140d148 100644 --- a/src/snmp_core.cc +++ b/src/snmp_core.cc @@ -34,10 +34,30 @@ #include "cache_snmp.h" #include "acl/FilledChecklist.h" #include "ip/IpAddress.h" +#include "ipc/StartListening.h" #define SNMP_REQUEST_SIZE 4096 #define MAX_PROTOSTAT 5 + +/// dials snmpConnectionOpened call +class SnmpListeningStartedDialer: public CallDialer, + public Ipc::StartListeningCb +{ +public: + typedef void (*Handler)(int fd, int errNo); + SnmpListeningStartedDialer(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; +}; + + IpAddress theOutSNMPAddr; typedef struct _mib_tree_entry mib_tree_entry; @@ -58,6 +78,9 @@ struct _mib_tree_entry { mib_tree_entry *mib_tree_head; mib_tree_entry *mib_tree_last; +static void snmpIncomingConnectionOpened(int fd, int errNo); +static void snmpOutgoingConnectionOpened(int fd, int errNo); + static mib_tree_entry * snmpAddNodeStr(const char *base_str, int o, oid_ParseFn * parsefunction, instance_Fn * instancefunction); static mib_tree_entry *snmpAddNode(oid * name, int len, oid_ParseFn * parsefunction, instance_Fn * instancefunction, int children,...); static oid *snmpCreateOid(int length,...); @@ -278,54 +301,71 @@ snmpInit(void) void snmpConnectionOpen(void) { - struct addrinfo *xaddr = NULL; - int x; - debugs(49, 5, "snmpConnectionOpen: Called"); if (Config.Port.snmp > 0) { Config.Addrs.snmp_incoming.SetPort(Config.Port.snmp); - enter_suid(); - theInSnmpConnection = comm_open_listener(SOCK_DGRAM, + + AsyncCall::Pointer call = asyncCall(49, 2, + "snmpIncomingConnectionOpened", + SnmpListeningStartedDialer(&snmpIncomingConnectionOpened)); + + Ipc::StartListening(SOCK_DGRAM, IPPROTO_UDP, Config.Addrs.snmp_incoming, COMM_NONBLOCKING, - "SNMP Port"); - leave_suid(); - - if (theInSnmpConnection < 0) - fatal("Cannot open SNMP Port"); - - commSetSelect(theInSnmpConnection, COMM_SELECT_READ, snmpHandleUdp, NULL, 0); - - debugs(1, 1, "Accepting SNMP messages on " << Config.Addrs.snmp_incoming << ", FD " << theInSnmpConnection << "."); + Ipc::fdnInSnmpSocket, call); if (!Config.Addrs.snmp_outgoing.IsNoAddr()) { Config.Addrs.snmp_outgoing.SetPort(Config.Port.snmp); - enter_suid(); - theOutSnmpConnection = comm_open_listener(SOCK_DGRAM, + + AsyncCall::Pointer call = asyncCall(49, 2, + "snmpOutgoingConnectionOpened", + SnmpListeningStartedDialer(&snmpOutgoingConnectionOpened)); + + Ipc::StartListening(SOCK_DGRAM, IPPROTO_UDP, Config.Addrs.snmp_outgoing, COMM_NONBLOCKING, - "SNMP Port"); - leave_suid(); + Ipc::fdnOutSnmpSocket, call); + } + } +} - if (theOutSnmpConnection < 0) - fatal("Cannot open Outgoing SNMP Port"); +static void +snmpIncomingConnectionOpened(int fd, int errNo) +{ + theInSnmpConnection = fd; + if (theInSnmpConnection < 0) + fatal("Cannot open Incoming SNMP Port"); - commSetSelect(theOutSnmpConnection, - COMM_SELECT_READ, - snmpHandleUdp, - NULL, 0); + commSetSelect(theInSnmpConnection, COMM_SELECT_READ, snmpHandleUdp, NULL, + 0); - debugs(1, 1, "Outgoing SNMP messages on " << Config.Addrs.snmp_outgoing << ", FD " << theOutSnmpConnection << "."); + debugs(1, 1, "Accepting SNMP messages on " << Config.Addrs.snmp_incoming << + ", FD " << theInSnmpConnection << "."); - fd_note(theOutSnmpConnection, "Outgoing SNMP socket"); + if (Config.Addrs.snmp_outgoing.IsNoAddr()) + theOutSnmpConnection = theInSnmpConnection; +} + +static void +snmpOutgoingConnectionOpened(int fd, int errNo) +{ + theOutSnmpConnection = fd; + if (theOutSnmpConnection < 0) + fatal("Cannot open Outgoing SNMP Port"); + + commSetSelect(theOutSnmpConnection, COMM_SELECT_READ, snmpHandleUdp, NULL, + 0); + + debugs(1, 1, "Outgoing SNMP messages on " << Config.Addrs.snmp_outgoing << + ", FD " << theOutSnmpConnection << "."); + + { + struct addrinfo *xaddr = NULL; + int x; - fd_note(theInSnmpConnection, "Incoming SNMP socket"); - } else { - theOutSnmpConnection = theInSnmpConnection; - } theOutSNMPAddr.SetEmpty();