[SNMP4J] Bug in Snmp.close()

Frank Fock fock at agentpp.com
Thu Jul 21 00:08:19 CEST 2005


Matt,

This bug can be fixed by replacing the Snmp.processReport(..)
method by:

  private void processReport(PduHandle handle, CommandResponderEvent e) {
    PDU pdu = e.getPDU();
    logger.debug("Searching pending request with handle" + handle);
    PendingRequest request;
    synchronized (sync) {
      request = (PendingRequest) pendingRequests.get(handle);
    }
    if (request == null) {
      logger.warn("Unmatched report PDU received from " + 
e.getPeerAddress());
      return;
    }
    if (pdu.size() == 0) {
      logger.error("Illegal report PDU received from " + 
e.getPeerAddress() +
                   " missing report variable binding");
      return;
    }
    VariableBinding vb = pdu.get(0);
    if (vb == null) {
      logger.error("Received illegal REPORT PDU from " + 
e.getPeerAddress());
      return;
    }
    OID firstOID = vb.getOid();
    boolean resend = false;
    if (request.requestStatus < request.maxRequestStatus) {
      switch (request.requestStatus) {
        case 0:
          if (SnmpConstants.usmStatsUnknownEngineIDs.equals(firstOID)) {
            resend = true;
          }
          else if 
(SnmpConstants.usmStatsNotInTimeWindows.equals(firstOID)) {
            request.requestStatus++;
            resend = true;
          }
          break;
        case 1:
          if (SnmpConstants.usmStatsNotInTimeWindows.equals(firstOID)) {
            resend = true;
          }
          break;
      }
    }
    // if legal report PDU received, then resend request
    if (resend) {
      logger.debug("Send new request after report.");
      request.requestStatus++;
      try {
        sendMessage(request.pdu, request.target, e.getTransportMapping());
      }
      catch (IOException iox) {
        logger.error("Failed to send message to " + request.target + ": " +
                     iox.getMessage());
        return;
      }
    }
    else {
      boolean intime = request.cancel();
      // remove pending request
      // (sync is not needed as request is already canceled)
      pendingRequests.remove(handle);
      if (intime) {
        // return report
        request.listener.onResponse(new ResponseEvent(this,
            e.getPeerAddress(),
            request.pdu,
            pdu,
            request.userObject));
      }
      else {
        // silently drop late report
        if (logger.isInfoEnabled()) {
          logger.info("Received late report from " +
                      e.getPeerAddress() +
                      " with request ID " + pdu.getRequestID());
        }
      }
    }
  }

This fix will also be included in v1.6.

Best regards,
Frank

Matt Brozowski wrote:

> I have been writing code that does SNMPv3 requests as part of a test  
> case.  As I was testing, I has misconfigured my usmUser name and  
> password so I was getting Report PDUs back indicating unknown user.  
> I  had log messages in onResponse of my ResponseListener.  When I 
> called  Snmp.close() as a result of the Report I got a number of 
> onResponse log  messages indication an InterruptedException.  
> (Originally I didn't  handle this correctly and attempted to call 
> Snmp.close() again  resulting in an infinitely recursive loop).  After 
> looking the code  over it seems like there is a problem here.
>
> When the Report PDU comes in, the request is 'cancelled' by calling 
> its  cancel method, but it is not removed from the pendingRequests 
> list.   Therefore on close() these requests appear to still be pending 
> and  result in interruptedExceptions (not to mention they probably 
> hang  around for a very long time)
>
> Matt
> ________________________________________________________________________ 
> ___
> Matt Brozowski, OpenNMS Maintainer            Main:    +1 919 812 4984
> The OpenNMS Group, Inc.                    Fax:        +1 503 961 7746
> Email: brozow at opennms.org                    URL:    
> http://www.opennms.com
>
> _______________________________________________
> SNMP4J mailing list
> SNMP4J at agentpp.org
> http://lists.agentpp.org/mailman/listinfo/snmp4j
>
>





More information about the SNMP4J mailing list