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 + -
显示快捷键?