[SNMP4J] Resent (full code now): Why is the USM a singleton ?

Frank Fock fock at agentpp.com
Wed Mar 4 00:07:33 CET 2009


Hello Sjoerd,

First, for 200+ elements using a single thread with async
response processing will be sufficient. With 15 threads
each creating a Snmp instance, you waist resources and
probably run into problems with port allocation on your
system. The thread context switches are also expensive,
unless you have 16 CPUs.

The USM is NOT a singleton! The problem with your code
is, that you have 15 (or more) Snmp instances with the
same engine ID. Just create a different engine ID for
each instance.

BTW, creating a Snmp instance is expensive. I would
always share an instance if possible.

Best regards,
Frank


Sjoerd van Doorn wrote:
> 
> --- On Tue, 3/3/09, Sjoerd van Doorn <sjoerdvandoorn at yahoo.com> wrote:
> 
> From: Sjoerd van Doorn <sjoerdvandoorn at yahoo.com>
> Subject: Why is the USM a singleton ?
> To: "SNMP4j" <snmp4j at agentpp.org>
> Date: Tuesday, March 3, 2009, 10:35 PM
> 
> 
> 
> 
> 
> 
> 
> Hello all,
>  
> I'm working on an issue and I suspect the fact that the USM is a singleton, is part of the reasons I'm having problems.
> Can someone explain why not have an instance of the USM for every MPv3 instance ?
>  
> My problem is having timeouts, usmStatsNotInTime, usmUnknownEngineId and MessageException (1404) every now and then.
> I'm in a network with 200+ elements and I already have seen that the autoritiveEngineId of the elements is not unique, however I cannot have them changed for my purpose (I am aware that this is against RFC 3414)
> The issues show when in parallel (multithreaded) querying appr. 15 devices.(I'll post a snipped at the end of my mail.
>  
> I suspect the internal administration of the USM is broken due to the fact that the engineID is non-unique and that this is causing my errors.
>  
> After analysing the code for a couple of days and going through the previous posts, I can see more people are having these kind of problems, however I could not find any solution.
> I'm thinking that a modification of the USM from a singleton to a instance per MPv3 could solve the problem, but I can't realy oversee why it is designed as a singleton from the beginning. 
>  
> Here is my code (executed by 15 threads in parallel in synchronous mode.
>  
> private final Snmp4jAgent _agent; 
> 
> private final String _requestType; 
> 
> protected SnmpCommand(Snmp4jAgent agent, String requestType){ 
>   _agent = agent; 
> _requestType = requestType; 
> initSecurityModels(createUSM()); 
> } 
> 
> protected void initSecurityModels( USM usm ){ 
> SecurityModels.getInstance().addSecurityModel(usm); 
> } 
> 
> protected USM createUSM(){ 
> return new USM(SecurityProtocols.getInstance(), 
> new OctetString(MPv3.createLocalEngineID()), 
> 0); 
> } 
> 
> protected PDU createRequest(){ 
> final PDU request = new ScopedPDU(); 
> request.setType(PDU.getTypeFromString(_requestType)); 
> request.setMaxRepetitions(15); 
> request.setNonRepeaters(0); 
> return request; 
> } 
> 
> protected Target createTarget(){ 
> final UserTarget target = new UserTarget(); 
> target.setSecurityLevel(_agent.securityLevel); 
> target.setSecurityName(_agent.securityName); 
> target.setVersion(_agent.version); 
> target.setAddress(_agent.udpAddress); 
> target.setRetries(_agent.retries); 
> target.setTimeout(_agent.timeoutInSeconds * 1000); 
> return target; 
> } 
> 
> protected Snmp createSnmp() throws IOException{ 
> Snmp snmp = new Snmp(new DefaultUdpTransportMapping()); 
> UsmUser user = new UsmUser(_agent.securityName, 
> _agent.authProtocol, 
> _agent.authPassphrase, 
> _agent.privProtocol, 
> _agent.privPassphrase); 
> snmp.getUSM().addUser(_agent.securityName, user); 
> return snmp; 
> } 
> 
> public PDU execute() throws IOException{
> Snmp snmp = null;
> 
> try{
> snmp = createSnmp();
> final List<VariableBinding> results = new ArrayList<VariableBinding>();
> snmp.listen();
> final PDU request = createRequest();
> request.add(new VariableBinding(_oid));
> final Target target = createTarget();
> ResponseEvent responseEvent = snmp.send(request, target);
> if (responseEvent.getPeerAddress() == null){
> throw new IOException("No response received");
> }
> PDU response = responseEvent.getResponse();
> if (response == null){
> log.error("SNMP GetNextCommand :: response==null");
> return null;
> }
> _agent.check(response);
> VariableBinding binding = response.get(0);
> OID checker = binding.getOid();
> while (binding.getOid().leftMostCompare(_oid.size(), _oid) == 0){
> results.add(binding);
> 
> request.set(0, new VariableBinding(binding.getOid()));
> responseEvent = snmp.send(request, target);
> response = responseEvent.getResponse();
> if (response == null){
> throw new IOException("Timeout occured");
> }
> binding = response.get(0);
> // check oid duplicated ( last one ...
> if (checker.equals(binding.getOid())){
> // if there is only one remove the last one ... bogus
> if (results.size() == 1){
> results.clear();
> }
> log.debug("loopy checking the same");
> break;
> }
> checker = binding.getOid();
> }
> response.clear();
> for (int i = 0; i < results.size(); i++){
> response.add((VariableBinding) results.get(i));
> }
> 
> return response;
> }
> finally{
> // always close the snmp connection
> if (snmp != null){
> snmp.close();
> }
> }
> } 
>  
>  
>  
>  
>  
> 
> 
> 
>       
> _______________________________________________
> 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