--- On Tue, 3/3/09, Sjoerd van Doorn <[email protected]> wrote:
From: Sjoerd van Doorn <[email protected]> Subject: Why is the USM a singleton ? To: "SNMP4j" <[email protected]> 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 [email protected] http://lists.agentpp.org/mailman/listinfo/snmp4j
