notifyqueue.cpp
来自「JdonFramework need above jdk 1.4.0 This」· C++ 代码 · 共 617 行 · 第 1/2 页
CPP
617 行
my_holder(holder), m_snmpSession(session){//TM: could do the trap registration setup here but seems better to//wait until the app actually requests trap receives by calling//notify_register().}CNotifyEventQueue::~CNotifyEventQueue(){ CNotifyEventQueueElt *leftOver; /* walk the list deleting any elements still on the queue */ lock(); while ((leftOver = m_head.GetNext())) delete leftOver; unlock();}SnmpSocket CNotifyEventQueue::get_notify_fd(const UdpAddress match_addr) const{ SnmpSocket found_fd = INVALID_SOCKET; int max_bits_matched = 0; IpAddress ip_match = IpAddress(match_addr); for (int i = 0; i < m_notify_fd_count; i++) { IpAddress ip = m_notify_addrs[i]; int bits = ip_match.get_match_bits(ip); debugprintf(5, "Compared %s to %s, bits %d", ip.get_printable(), ip_match.get_printable(), bits); if (bits > max_bits_matched) { max_bits_matched = bits; found_fd = m_notify_fds[i]; } } return found_fd;}SnmpSocket CNotifyEventQueue::get_notify_fd(const int i) const{ if ((i < 0) || ( i >= m_notify_fd_count)) return INVALID_SOCKET; return m_notify_fds[i];}int CNotifyEventQueue::AddEntry(Snmp *snmp, const OidCollection &trapids, const TargetCollection &targets, const AddressCollection &addresses){ if (snmp != m_snmpSession) { debugprintf(0, "WARNING: Adding notification event for other Snmp object"); } lock(); if (!m_msgCount) {// m_notify_addrs = addresses; if (m_notify_addrs.size() == 0) { UdpAddress tmp_addr = snmp->get_listen_address(); tmp_addr.set_port(m_listen_port); m_notify_addrs += tmp_addr; } // allocate fd array m_notify_fds = new SnmpSocket[m_notify_addrs.size()]; if (!m_notify_fds) return SNMP_CLASS_RESOURCE_UNAVAIL; m_notify_fd_count = m_notify_addrs.size(); for (int i = 0; i < m_notify_fd_count ; i++) { // This is the first request to receive notifications // Set up the socket for the snmp trap port (162) or the // specified port through set_listen_port() struct sockaddr_in mgr_addr; // open a socket to be used for the session if ((m_notify_fds[i] = socket( AF_INET, SOCK_DGRAM,0)) < 0) { int status;#ifdef WIN32 int werr = WSAGetLastError(); if (EMFILE == werr ||WSAENOBUFS == werr || ENFILE == werr) status = SNMP_CLASS_RESOURCE_UNAVAIL; else if (WSAEHOSTDOWN == werr) status = SNMP_CLASS_TL_FAILED; else status = SNMP_CLASS_TL_UNSUPPORTED;#else if (EMFILE == errno || ENOBUFS == errno || ENFILE == errno) status = SNMP_CLASS_RESOURCE_UNAVAIL; else if (EHOSTDOWN == errno) status = SNMP_CLASS_TL_FAILED; else status = SNMP_CLASS_TL_UNSUPPORTED;#endif // Free all fds... for (int j=0; j<i; j++) close(m_notify_fds[j]); delete [] m_notify_fds; m_notify_fds = 0; m_notify_fd_count = 0; unlock(); return status; } // set up the manager socket attributes unsigned long inaddr = inet_addr(IpAddress(m_notify_addrs[i]).get_printable()); memset(&mgr_addr, 0, sizeof(mgr_addr)); mgr_addr.sin_family = AF_INET; mgr_addr.sin_addr.s_addr = inaddr; // was htonl( INADDR_ANY); mgr_addr.sin_port = htons(UdpAddress(m_notify_addrs[i]).get_port());#ifdef CYGPKG_NET_OPENBSD_STACK mgr_addr.sin_len = sizeof(mgr_addr);#endif // bind the socket if (bind(m_notify_fds[i], (struct sockaddr *) &mgr_addr, sizeof(mgr_addr)) < 0) { int status;#ifdef WIN32 int werr = WSAGetLastError(); if (WSAEADDRINUSE == werr) status = SNMP_CLASS_TL_IN_USE; else if (WSAENOBUFS == werr) status = SNMP_CLASS_RESOURCE_UNAVAIL; else if (werr == WSAEAFNOSUPPORT) status = SNMP_CLASS_TL_UNSUPPORTED; else if (werr == WSAENETUNREACH) status = SNMP_CLASS_TL_FAILED; else if (werr == EACCES) status = SNMP_CLASS_TL_ACCESS_DENIED; else status = SNMP_CLASS_INTERNAL_ERROR;#else if (EADDRINUSE == errno) status = SNMP_CLASS_TL_IN_USE; else if (ENOBUFS == errno) status = SNMP_CLASS_RESOURCE_UNAVAIL; else if (errno == EAFNOSUPPORT) status = SNMP_CLASS_TL_UNSUPPORTED; else if (errno == ENETUNREACH) status = SNMP_CLASS_TL_FAILED; else if (errno == EACCES) status = SNMP_CLASS_TL_ACCESS_DENIED; else { debugprintf(0, "Uncatched errno value %d, returning internal error.", errno); status = SNMP_CLASS_INTERNAL_ERROR; }#endif debugprintf(0, "Fatal: could not bind to %s", m_notify_addrs[i].get_printable()); // Free all fds... for (int j=0; j <= i; j++) close(m_notify_fds[j]); delete [] m_notify_fds; m_notify_fds = 0; m_notify_fd_count = 0; unlock(); return status; } debugprintf(3, "Bind to %s for notifications, fd %d.", m_notify_addrs[i].get_printable(), m_notify_fds[i]); } } CNotifyEvent *newEvent = new CNotifyEvent(snmp, trapids, targets, m_notify_addrs); /*---------------------------------------------------------*/ /* Insert entry at head of list, done automagically by the */ /* constructor function, so don't use the return value. */ /*---------------------------------------------------------*/ (void) new CNotifyEventQueueElt(newEvent, m_head.GetNext(), &m_head); m_msgCount++; unlock(); return SNMP_CLASS_SUCCESS;}CNotifyEvent *CNotifyEventQueue::GetEntry(Snmp * snmp) REENTRANT ({ CNotifyEventQueueElt *msgEltPtr = m_head.GetNext(); CNotifyEvent *returnVal = NULL; while (msgEltPtr){ if ((returnVal = msgEltPtr->TestId(snmp))) return returnVal; msgEltPtr = msgEltPtr->GetNext(); } return 0;})void CNotifyEventQueue::DeleteEntry(Snmp *snmp){ lock(); CNotifyEventQueueElt *msgEltPtr = m_head.GetNext(); while (msgEltPtr){ if (msgEltPtr->TestId(snmp)){ delete msgEltPtr; m_msgCount--; break; } msgEltPtr = msgEltPtr->GetNext(); } if (m_msgCount <= 0) { for(int i=0; i < m_notify_fd_count; i++) { // shut down the trap socket (if valid) if not using it. if (m_notify_fds[i] != (int)INVALID_SOCKET) { debugprintf(3, "Closing notifications port %s, fd %d.", m_notify_addrs[i].get_printable(), m_notify_fds[i]); close(m_notify_fds[i]); m_notify_fds[i] = INVALID_SOCKET; } } if (m_notify_fds) delete [] m_notify_fds; m_notify_fds = 0; m_notify_fd_count = 0; } unlock();}void CNotifyEventQueue::GetFdSets(int &maxfds, fd_set &readfds, fd_set &/*writefds*/, fd_set &/*exceptfds*/) REENTRANT ({ if (m_notify_fd_count > 0) { for (int i = 0; i < m_notify_fd_count; i++) { FD_SET(m_notify_fds[i], &readfds); if (maxfds < m_notify_fds[i] + 1) maxfds = SAFE_INT_CAST(m_notify_fds[i] + 1); } } return;})int CNotifyEventQueue::HandleEvents(const int /*maxfds*/, const fd_set &readfds, const fd_set &/*writefds*/, const fd_set &/*exceptfds*/) REENTRANT ({ int status = SNMP_CLASS_SUCCESS; if (m_notify_fd_count == 0) return status; for (int i=0; i < m_notify_fd_count; i++) { Pdu pdu; SnmpTarget *target = NULL; CNotifyEventQueueElt *notifyEltPtr = m_head.GetNext(); // pull the notifiaction off the socket if (FD_ISSET(m_notify_fds[i], &readfds)) { status = receive_snmp_notification(m_notify_fds[i], *m_snmpSession, pdu, &target); if (SNMP_CLASS_SUCCESS == status || SNMP_CLASS_TL_FAILED == status) { // If we have transport layer failure, the app will want to // know about it. // Go through each snmp object and check the filters, making // callbacks as necessary // LiorK: on failure target will be NULL if (!target) target = new SnmpTarget(); while (notifyEltPtr){ notifyEltPtr->GetNotifyEvent()->Callback(*target, pdu, m_notify_fds[i], status); notifyEltPtr = notifyEltPtr->GetNext(); } // for each snmp object } if (target) // receive_snmp_notification calls new delete target; } } return status;})#ifdef SNMP_PP_NAMESPACE}; // end of namespace Snmp_pp#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?