[SNMP4J] SNMP Timeout seems to be incorrect
Frank Fock
fock at agentpp.com
Fri Dec 1 12:17:27 CET 2006
i Steve,
Why do you think, that timeout processing is covered by any SNMP standard?
What is the goal of having an one microsecond timeout?
If you want to receive a response with minimum CPU idle time, the current
implementation is best. Otherwise, you will have to implement a check
and replace the received response by null if the currentTime - sendTime
> timeout.
So the short answer is: yes, this behavior is intended.
Best regards,
Frank
? wrote:
> Hi
> I have found that it seed to be incoorect when testing a very short timeout value.
>
> Please test following code.
> --------------------------------------------------------------------------------------------------
>
> package snmpTest;
>
> import org.snmp4j.*;
> import org.snmp4j.smi.*;
> import org.snmp4j.mp.*;
> import org.snmp4j.event.*;
> import org.snmp4j.transport.DefaultUdpTransportMapping;
> import java.util.Date;
> import java.util.Vector;
> import java.text.SimpleDateFormat;
> import java.util.Hashtable;
>
> /**
> * <p>Title: SNMP4J Test</p>
> *
> * <p>Description: </p>
> *
> * <p>Copyright: Copyright (c) 2006</p>
> *
> * <p>Company: NEXT DATA SYSTEMS</p>
> *
> * @author Steve
> * @version 1.0
> */
> public class ClassMain
> {
> String agentIP;
> int snmpVersion;
>
> public static void main(String args[])
> {
> try
> {
> ClassMain obj = new ClassMain(args[0]);
>
> if(args[1].equals("set"))
> obj.snmpSet(new String[]{args[2]}, Long.parseLong(args[3]));
> else if(args[1].equals("get"))
> obj.snmpGet(args[2], Long.parseLong(args[3]));
> else if(args[1].equals("getNext"))
> obj.snmpGetNext(args[2], Long.parseLong(args[3]));
> else if(args[2].equals("getBulk"))
> obj.snmpGetBulk(args[2], Long.parseLong(args[3]));
> else
> System.out.println("Cannot recognize command.");
> }
> catch(Exception e)
> {
> e.printStackTrace();
> System.out.println("ClassMain SNMPVersion:agentIP command description");
> }
> }
>
> public ClassMain(String uri) throws Exception
> {
> System.out.println("URI:"+uri);
>
> String[] nURI = uri.split(":");
>
> if(nURI[0].equals("SNMPv1"))
> snmpVersion = SnmpConstants.version1;
> else if(nURI[0].equals("SNMPv2c"))
> snmpVersion = SnmpConstants.version2c;
> else if(nURI[0].equals("SNMPv3"))
> snmpVersion = SnmpConstants.version3;
> else
> throw new IllegalArgumentException("URI parsing error");
>
> agentIP = nURI[1];
> System.out.println("SNMP version:"+snmpVersion);
> }
>
> public void doTraceLog(String log)
> {
> try
> {
> SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS");
>
> System.out.print("[" + format.format(new Date()) + "]");
> System.out.println(log);
> }
> catch(Exception e)
> {
> }
>
> }
>
> public void snmpSet(String pdus[], long timeout)
> {
> try
> {
> MessageDispatcherImpl mdi = new MessageDispatcherImpl();
>
> mdi.addMessageProcessingModel(new MPv2c());
> Snmp snmp = new Snmp(mdi);
> CommunityTarget target = new CommunityTarget();
> IpAddress targetAddr = new IpAddress(agentIP);
>
> targetAddr.setValue(agentIP);
>
> target.setAddress(targetAddr);
> target.setRetries(2);
> target.setTimeout(timeout);
> target.setVersion(snmpVersion);
>
> PDU pdu = new PDU();
> pdu.setType(PDU.SET);
>
> for (int i = 0; i < pdus.length; i++)
> {
> String pduData[] = pdus[i].split(":");
> VariantVariable var = new VariantVariable(Variable.createFromSyntax(
> Integer.parseInt(pduData[1])));
>
> var.setValue(pduData[2]);
> pdu.add(new VariableBinding(new OID(pduData[0]), var));
> }
>
> ResponseEvent response = snmp.send(pdu, target);
> }
> catch(Exception e)
> {
> e.printStackTrace();
> }
> }
>
> public void snmpGet(String oid, long timeout)
> {
> try
> {
> //MessageDispatcherImpl mdi = new MessageDispatcherImpl();
>
> //mdi.addMessageProcessingModel(new MPv2c());
> //Snmp snmp = new Snmp(mdi);
> TransportMapping transport = new DefaultUdpTransportMapping();
>
> transport.listen();
>
> Snmp snmp = new Snmp(transport);
> //Snmp snmp = new Snmp();
>
> snmp.setTimeoutModel(new AdvancedTimeoutModel(timeout));
> CommunityTarget target = new CommunityTarget();
> Address targetAddress = GenericAddress.parse("udp:"+agentIP+"/161");
> target.setAddress(targetAddress);
> target.setRetries(0);
> target.setTimeout(timeout);
> target.setVersion(snmpVersion);
> target.setCommunity(new OctetString("public"));
>
> PDU pdu = new PDU();
> pdu.setType(PDU.GET);
> pdu.add(new VariableBinding(new OID(oid)));
>
> doTraceLog("SNMP GET Request: "+oid+", timeout:"+timeout);
>
> ResponseEvent response = snmp.send(pdu, target);
>
> doTraceLog("SNMP GET Response:"+response.getResponse());
> }
> catch(Exception e)
> {
> doTraceLog("Exception: "+e.getMessage());
> //e.printStackTrace();
> }
> }
>
> public void snmpGetNext(String oid, long timeout)
> {
> try
> {
> Snmp snmp = new Snmp();
> CommunityTarget target = new CommunityTarget();
> IpAddress targetAddr = new IpAddress(agentIP);
>
> targetAddr.setValue(agentIP);
>
> target.setAddress(targetAddr);
> target.setRetries(2);
> target.setTimeout(timeout);
> target.setVersion(snmpVersion);
>
> PDU pdu = new PDU();
> pdu.setType(PDU.GETNEXT);
> pdu.add(new VariableBinding(new OID(oid)));
>
> ResponseEvent response = snmp.send(pdu, target);
> }
> catch(Exception e)
> {
> e.printStackTrace();
> }
> }
>
> public void snmpGetBulk(String desc, long timeout)
> {
> try
> {
> String snmpDesc[] = desc.split(":");
> String oid = snmpDesc[0];
> int maxRp = Integer.parseInt(snmpDesc[1]);
>
> Snmp snmp = new Snmp();
> CommunityTarget target = new CommunityTarget();
> IpAddress targetAddr = new IpAddress(agentIP);
>
> targetAddr.setValue(agentIP);
>
> target.setAddress(targetAddr);
> target.setRetries(2);
> target.setTimeout(timeout);
> target.setVersion(snmpVersion);
>
> PDU pdu = new PDU();
> pdu.setType(PDU.GETNEXT);
> pdu.add(new VariableBinding(new OID(oid)));
> pdu.setMaxRepetitions(maxRp);
>
> ResponseEvent response = snmp.send(pdu, target);
> }
> catch(Exception e)
> {
> e.printStackTrace();
> }
> }
>
> private class AdvancedTimeoutModel implements TimeoutModel
> {
> private long retryTimeout;
>
> AdvancedTimeoutModel(long ioTimeout)
> {
> retryTimeout = ioTimeout;
> }
>
> public long getRequestTimeout(int nRetries, long timeout)
> {
> doTraceLog("get request timeout...");
> return retryTimeout;
> }
>
> public long getRetryTimeout(int nRetries, int totalRetries, long timeout)
> {
> doTraceLog("get retry timeout...");
> return 1;
> }
> }
> }
> ------------------------------------------------------------------
>
> test logs
>
>
>
> D:\prj\SNMPTest>java -cp SNMPTest.jar;snmp4j.jar snmpTest.ClassMain SNMPv1:220.90.132.94 get 1.3.6.1.2.1.1.1.0 1
> URI:SNMPv1:220.90.132.94
> SNMP version:0
> [2006/12/01 17:47:07.020]SNMP GET Request: 1.3.6.1.2.1.1.1.0, timeout:1
> [2006/12/01 17:47:07.040]get retry timeout...
> [2006/12/01 17:47:07.040]SNMP GET Response:RESPONSE[requestID=1669627258, errorStatus=Success(0), errorIndex=0, VBS[1.3.
> 6.1.2.1.1.1.0 = Foundry Networks, Inc. Router, IronWare Version 07.8.00aT53 Compiled on Oct 04 2004 at 16:42:07 labeled
> as B2R07800a]]
> ------------------------------------------------------------------
> I think this result caused by folling code of SNMP4j
> ------------------------------------------------------------------
> synchronized (syncResponse) {
> PduHandle handle;
> PendingRequest request;
> synchronized (sync) {
> handle = sendMessage(pdu, target, transport);
> request =
> new PendingRequest(handle, syncResponse, target, pdu, target,
> transport);
> if (logger.isDebugEnabled()) {
> logger.debug("New pending request with handle " + handle);
> }
> pendingRequests.put(handle, request);
> long delay = timeoutModel.getRetryTimeout(0, target.getRetries(),
> target.getTimeout());
> timer.schedule(request, delay);
> }
> try {
> syncResponse.wait();
> PendingRequest retryRequest =
> (PendingRequest) pendingRequests.remove(handle);
> if (retryRequest != null) {
> retryRequest.setFinished();
> retryRequest.cancel();
> }
> if (logger.isDebugEnabled()) {
> logger.debug("Removed pending request with handle: "+handle);
> }
> request.setFinished();
> request.cancel();
> }
> catch (InterruptedException iex) {
> logger.warn(iex);
> // ignore
> }
> }
> --------------------------------------------------------------------
> 1. First of all it seemed to try send the SNMP pdu to the target synchronously.
> 2. And then run the code stuffs related to timer.
>
> So during the first step the timeout will never happens.
> Is this result intended to follow SNMP protocol specification?
>
> If anyone have interests, please reply.
>
> Thanks.
>
>
> _______________________________________________
> SNMP4J mailing list
> SNMP4J at agentpp.org
> http://lists.agentpp.org/mailman/listinfo/snmp4j
--
AGENT++
http://www.agentpp.com
http://www.mibexplorer.com
http://www.mibdesigner.com
More information about the SNMP4J
mailing list