/** * This method determines whether the inform request is to be retried. This is used if the peer * did not respond to a previous request. If the request exceeds the maxTries limit, a timeout is * signaled. */ void action() { if (inProgress() == false) return; while (true) { try { if (numTries == 0) { invokeOnReady(); } else if (numTries < getMaxTries()) { invokeOnRetry(); } else { invokeOnTimeout(); } return; } catch (OutOfMemoryError omerr) { // Consider it as a try ! // numTries++; if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { SNMP_ADAPTOR_LOGGER.logp( Level.FINEST, SnmpInformRequest.class.getName(), "action", "Inform request hit out of memory situation..."); } Thread.currentThread().yield(); } } }
/** For SNMP Runtime internal use only. */ final void processResponse() { if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { SNMP_ADAPTOR_LOGGER.logp( Level.FINER, SnmpInformRequest.class.getName(), "processResponse", "errstatus = " + errorStatus); } if (inProgress() == false) { // check if this request is still alive. responsePdu = null; return; // the request may have cancelled. } if (errorStatus >= snmpReqInternalError) { handleInternalError("Internal Error..."); return; } try { parsePduPacket(responsePdu); // responsePdu = null; // At this point the errorIndex is rationalized to start with 0. switch (errorStatus) { case snmpRspNoError: handleSuccess(); return; case snmpReqTimeout: handleTimeout(); return; case snmpReqInternalError: handleInternalError("Unknown internal error. deal with it later!"); return; case snmpReqHandleTooBig: setErrorStatusAndIndex(snmpRspTooBig, 0); handleError("Cannot handle too-big situation..."); return; case snmpReqRefireAfterVbFix: // Refire request after fixing varbindlist. initializeAndFire(); return; default: handleError("Error status set in packet...!!"); return; } } catch (Exception e) { if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { SNMP_ADAPTOR_LOGGER.logp( Level.FINEST, SnmpInformRequest.class.getName(), "processResponse", "Got unexpected exception", e); } reason = e.getMessage(); } handleInternalError(reason); }
/** For SNMP Runtime internal use only. */ final void setRequestSentTime(long sendtime) { numTries++; setPrevPollTime(sendtime); waitTimeForResponse = prevPollTime + timeout * numTries; setRequestStatus(stWaitingForReply); if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { SNMP_ADAPTOR_LOGGER.logp( Level.FINER, SnmpInformRequest.class.getName(), "setRequestSentTime", "Inform request Successfully sent"); } informSession.getSnmpQManager().addWaiting(this); }
/** * Checks if a <CODE>set</CODE> operation can be performed. If the operation can not be performed, * the method should emit a <CODE>SnmpStatusException</CODE>. * * @param inRequest The SnmpMibRequest object holding the list of variables to be set. This list * is composed of <CODE>SnmpVarBind</CODE> objects. * @exception SnmpStatusException The <CODE>set</CODE> operation cannot be performed. */ @Override public void check(SnmpMibRequest inRequest) throws SnmpStatusException { SNMP_ADAPTOR_LOGGER.logp( Level.FINEST, SnmpErrorHandlerAgent.class.getName(), "check", "Check in Exception"); throw new SnmpStatusException(SnmpDefinitions.snmpRspNotWritable); }
/** * Processes a <CODE>set</CODE> operation. Should never be called (check previously called having * failed). * * @param inRequest The SnmpMibRequest object holding the list of variable to be set. * @exception SnmpStatusException An error occurred during the operation. */ @Override public void set(SnmpMibRequest inRequest) throws SnmpStatusException { SNMP_ADAPTOR_LOGGER.logp( Level.FINEST, SnmpErrorHandlerAgent.class.getName(), "set", "Set in Exception, CANNOT be called"); throw new SnmpStatusException(SnmpDefinitions.snmpRspNotWritable); }
/** * Parses the inform response packet. If the agent responds with error set, it does not parse any * further. */ synchronized void parsePduPacket(SnmpPduRequestType rpdu) { if (rpdu == null) return; errorStatus = rpdu.getErrorStatus(); errorIndex = rpdu.getErrorIndex(); if (errorStatus == snmpRspNoError) { updateInternalVarBindWithResult(((SnmpPdu) rpdu).varBindList); return; } if (errorStatus != snmpRspNoError) --errorIndex; // rationalize for index to start with 0. if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { SNMP_ADAPTOR_LOGGER.logp( Level.FINER, SnmpInformRequest.class.getName(), "parsePduPacket", "received inform response. ErrorStatus/ErrorIndex = " + errorStatus + "/" + errorIndex); } }
/** * Sends the prepared PDU packet to the manager and updates the data structure to expect a * response. It acquires a lock on the socket to prevent a case where a response arrives before * this thread could insert the request into the wait queue. * * @exception IOException Signals that an I/O exception of some sort has occurred. */ final void sendPduPacket(byte[] buffer, int length) throws java.io.IOException { if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { SNMP_ADAPTOR_LOGGER.logp( Level.FINER, SnmpInformRequest.class.getName(), "sendPduPacket", "Send to peer. Peer/Port : " + address.getHostName() + "/" + port + ". Length = " + length + "\nDump : \n" + SnmpMessage.dumpHexBuffer(buffer, 0, length)); } SnmpSocket theSocket = informSession.getSocket(); synchronized (theSocket) { theSocket.sendPacket(buffer, length, address, port); setRequestSentTime(System.currentTimeMillis()); } }
/** SNMP V1/V2 . To be called with updateRequest. */ protected SnmpSubRequestHandler(SnmpMibAgent agent, SnmpPdu req) { if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { SNMP_ADAPTOR_LOGGER.logp( Level.FINER, SnmpSubRequestHandler.class.getName(), "constructor", "creating instance for request " + String.valueOf(req.requestId)); } version = req.version; type = req.type; this.agent = agent; // We get a ref on the pdu in order to pass it to SnmpMibRequest. reqPdu = req; // Pre-allocate room for storing varbindlist and translation table. // int length = req.varBindList.length; translation = new int[length]; varBind = new NonSyncVector<SnmpVarBind>(length); }
/** * The method updates a given var bind list with the result of a previsouly invoked operation. * Prior to calling the method, one must make sure that the operation was successful. As such the * method getErrorIndex or getErrorStatus should be called. */ protected void updateResult(SnmpVarBind[] result) { if (result == null) return; final int max = varBind.size(); final int len = result.length; for (int i = 0; i < max; i++) { // bugId 4641694: must check position in order to avoid // ArrayIndexOutOfBoundException final int pos = translation[i]; if (pos < len) { result[pos] = (SnmpVarBind) ((NonSyncVector) varBind).elementAtNonSync(i); } else { if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { SNMP_ADAPTOR_LOGGER.logp( Level.FINEST, SnmpSubRequestHandler.class.getName(), "updateResult", "Position `" + pos + "' is out of bound..."); } } } }
/** * Processes a <CODE>get</CODE> operation. It will throw an exception for V1 requests or it will * set exceptions within the list for V2 requests. * * @param inRequest The SnmpMibRequest object holding the list of variable to be retrieved. * @exception SnmpStatusException An error occurred during the operation. */ @Override public void get(SnmpMibRequest inRequest) throws SnmpStatusException { SNMP_ADAPTOR_LOGGER.logp( Level.FINEST, SnmpErrorHandlerAgent.class.getName(), "get", "Get in Exception"); if (inRequest.getVersion() == SnmpDefinitions.snmpVersionOne) throw new SnmpStatusException(SnmpStatusException.noSuchName); Enumeration<SnmpVarBind> l = inRequest.getElements(); while (l.hasMoreElements()) { SnmpVarBind varbind = l.nextElement(); varbind.setNoSuchObject(); } }
/** Constructs an inform request PDU. */ synchronized SnmpPdu constructPduPacket() { SnmpPduPacket reqpdu = null; Exception excep = null; try { reqpdu = new SnmpPduRequest(); reqpdu.port = port; reqpdu.type = pduInformRequestPdu; reqpdu.version = snmpVersionTwo; reqpdu.community = communityString.getBytes("8859_1"); reqpdu.requestId = getRequestId(); reqpdu.varBindList = internalVarBind; if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { SNMP_ADAPTOR_LOGGER.logp( Level.FINER, SnmpInformRequest.class.getName(), "constructPduPacket", "Packet built"); } } catch (Exception e) { excep = e; errorStatus = snmpReqUnknownError; reason = e.getMessage(); } if (excep != null) { if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { SNMP_ADAPTOR_LOGGER.logp( Level.FINEST, SnmpInformRequest.class.getName(), "constructPduPacket", "Got unexpected exception", excep); } reqpdu = null; queueResponse(); } return reqpdu; }
/** * Processes a <CODE>getBulk</CODE> operation. It will throw an exception if the request is a V1 * one or it will set exceptions within the list for V2 ones. * * @param inRequest The SnmpMibRequest object holding the list of variable to be retrieved. * @exception SnmpStatusException An error occurred during the operation. */ @Override public void getBulk(SnmpMibRequest inRequest, int nonRepeat, int maxRepeat) throws SnmpStatusException { SNMP_ADAPTOR_LOGGER.logp( Level.FINEST, SnmpErrorHandlerAgent.class.getName(), "getBulk", "GetBulk in Exception"); if (inRequest.getVersion() == SnmpDefinitions.snmpVersionOne) throw new SnmpStatusException(SnmpDefinitions.snmpRspGenErr, 0); Enumeration<SnmpVarBind> l = inRequest.getElements(); while (l.hasMoreElements()) { SnmpVarBind varbind = l.nextElement(); varbind.setEndOfMibView(); } }
/** Calls the user implementation of the <CODE>SnmpInformHandler</CODE> interface. */ private void handleInternalError(String msg) { setRequestStatus(stInternalError); if (reason == null) reason = msg; if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { SNMP_ADAPTOR_LOGGER.logp( Level.FINEST, SnmpInformRequest.class.getName(), "handleInternalError", "Snmp error/index = " + snmpErrorToString(errorStatus) + "/" + errorIndex + ". Invoking internal error user defined callback...\n" + getVarBindList()); } deleteRequest(); notifyClient(); requestPdu = null; responsePdu = null; internalVarBind = null; try { if (callback != null) callback.processSnmpInternalError(this, reason); } catch (Exception e) { // catch any exception a user might not handle. if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { SNMP_ADAPTOR_LOGGER.logp( Level.FINEST, SnmpInformRequest.class.getName(), "handleInternalError", "Exception generated by user callback", e); } } catch (OutOfMemoryError ome) { if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { SNMP_ADAPTOR_LOGGER.logp( Level.FINEST, SnmpInformRequest.class.getName(), "handleInternalError", "OutOfMemory Error generated by user callback", ome); } Thread.currentThread().yield(); } }
/** Calls the user implementation of the <CODE>SnmpInformHandler</CODE> interface. */ private void handleSuccess() { setRequestStatus(stResultsAvailable); if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { SNMP_ADAPTOR_LOGGER.logp( Level.FINER, SnmpInformRequest.class.getName(), "handleSuccess", "Invoking user defined callback..."); } deleteRequest(); // delete only non-poll request. notifyClient(); requestPdu = null; // responsePdu = null; internalVarBind = null; try { // catch all user exception which may happen in callback. if (callback != null) callback.processSnmpPollData(this, errorStatus, errorIndex, getVarBindList()); } catch (Exception e) { if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { SNMP_ADAPTOR_LOGGER.logp( Level.FINEST, SnmpInformRequest.class.getName(), "handleSuccess", "Exception generated by user callback", e); } } catch (OutOfMemoryError ome) { if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { SNMP_ADAPTOR_LOGGER.logp( Level.FINEST, SnmpInformRequest.class.getName(), "handleSuccess", "OutOfMemory Error generated by user callback", ome); } Thread.currentThread().yield(); } return; }
boolean sendPdu() { try { responsePdu = null; SnmpPduFactory pduFactory = adaptor.getPduFactory(); SnmpMessage msg = (SnmpMessage) pduFactory.encodeSnmpPdu( (SnmpPduPacket) requestPdu, adaptor.getBufferSize().intValue()); if (msg == null) { if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { SNMP_ADAPTOR_LOGGER.logp( Level.FINEST, SnmpInformRequest.class.getName(), "sendPdu", "pdu factory returned a null value"); } throw new SnmpStatusException(snmpReqUnknownError); // This exception will caught hereafter and reported as an snmpReqUnknownError // FIXME: may be it's not the best behaviour ? } int maxPktSize = adaptor.getBufferSize().intValue(); byte[] encoding = new byte[maxPktSize]; int encodingLength = msg.encodeMessage(encoding); if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { SNMP_ADAPTOR_LOGGER.logp( Level.FINER, SnmpInformRequest.class.getName(), "sendPdu", "Dump : \n" + msg.printMessage()); } sendPduPacket(encoding, encodingLength); return true; } catch (SnmpTooBigException ar) { if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { SNMP_ADAPTOR_LOGGER.logp( Level.FINEST, SnmpInformRequest.class.getName(), "sendPdu", "Got unexpected exception", ar); } setErrorStatusAndIndex(snmpReqPacketOverflow, ar.getVarBindCount()); requestPdu = null; reason = ar.getMessage(); if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { SNMP_ADAPTOR_LOGGER.logp( Level.FINEST, SnmpInformRequest.class.getName(), "sendPdu", "Packet Overflow while building inform request"); } } catch (java.io.IOException ioe) { setErrorStatusAndIndex(snmpReqSocketIOError, 0); reason = ioe.getMessage(); } catch (Exception e) { if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { SNMP_ADAPTOR_LOGGER.logp( Level.FINEST, SnmpInformRequest.class.getName(), "sendPdu", "Got unexpected exception", e); } setErrorStatusAndIndex(snmpReqUnknownError, 0); reason = e.getMessage(); } return false; }
public void run() { try { final ThreadContext oldContext = ThreadContext.push("SnmpUserData", data); try { switch (type) { case pduGetRequestPdu: // Invoke a get operation // if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { SNMP_ADAPTOR_LOGGER.logp( Level.FINER, SnmpSubRequestHandler.class.getName(), "run", "[" + Thread.currentThread() + "]:get operation on " + agent.getMibName()); } agent.get(createMibRequest(varBind, version, data)); break; case pduGetNextRequestPdu: if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { SNMP_ADAPTOR_LOGGER.logp( Level.FINER, SnmpSubRequestHandler.class.getName(), "run", "[" + Thread.currentThread() + "]:getNext operation on " + agent.getMibName()); } // #ifdef DEBUG agent.getNext(createMibRequest(varBind, version, data)); break; case pduSetRequestPdu: if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { SNMP_ADAPTOR_LOGGER.logp( Level.FINER, SnmpSubRequestHandler.class.getName(), "run", "[" + Thread.currentThread() + "]:set operation on " + agent.getMibName()); } agent.set(createMibRequest(varBind, version, data)); break; case pduWalkRequest: if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { SNMP_ADAPTOR_LOGGER.logp( Level.FINER, SnmpSubRequestHandler.class.getName(), "run", "[" + Thread.currentThread() + "]:check operation on " + agent.getMibName()); } agent.check(createMibRequest(varBind, version, data)); break; default: if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { SNMP_ADAPTOR_LOGGER.logp( Level.FINEST, SnmpSubRequestHandler.class.getName(), "run", "[" + Thread.currentThread() + "]:unknown operation (" + type + ") on " + agent.getMibName()); } errorStatus = snmpRspGenErr; errorIndex = 1; break; } // end of switch } finally { ThreadContext.restore(oldContext); } } catch (SnmpStatusException x) { errorStatus = x.getStatus(); errorIndex = x.getErrorIndex(); if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { SNMP_ADAPTOR_LOGGER.logp( Level.FINEST, SnmpSubRequestHandler.class.getName(), "run", "[" + Thread.currentThread() + "]:an Snmp error occured during the operation", x); } } catch (Exception x) { errorStatus = SnmpDefinitions.snmpRspGenErr; if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINEST)) { SNMP_ADAPTOR_LOGGER.logp( Level.FINEST, SnmpSubRequestHandler.class.getName(), "run", "[" + Thread.currentThread() + "]:a generic error occured during the operation", x); } } if (SNMP_ADAPTOR_LOGGER.isLoggable(Level.FINER)) { SNMP_ADAPTOR_LOGGER.logp( Level.FINER, SnmpSubRequestHandler.class.getName(), "run", "[" + Thread.currentThread() + "]:operation completed"); } }