[Pysnmp-dev] Potential oneliner bugs
Brought to you by:
elie
From: Mark M E. <mar...@ma...> - 2007-08-14 22:21:33
|
I've run into a couple of issues that I think are bugs in the oneliner implementation. I'm still learning my way around PySNMP, so apologies if my assumptions or conclusions are incorrect. Issue #1: Oneliner commands "leaking" sockets. UdpTransportTarget.openClientMode() creates a transport via UdpSocketTransport(). A side effect of using the default parameters is that a new channel/socket is created and is registered in asyncore.socket_map. The socket is never removed from asyncore.socket_map, it's never garbage collected and the socket is never closed. The result is that instantiating and destroying large numbers of CommandGenerators will consume all of the systems socket resources. I have a patch that works for me which is to pass a throw away dictionary as the sockMap. Example: pysnmp/entity/rfc3413/oneliner/cmdgen.py: class UdpTransportTarget: ... def openClientMode(self): self.transport = udp.UdpSocketTransport(sock=None, sockMap= {}).openClientMode() return self.transport Issue #2: CommandGenerator().nextCmd() does not work with V1 devices. V1 devices terminate the list list of OIDs by returning an errorStatus of noSuchName(2), not by returning a value of endOfMib. CommandGenerator().nextCmd() considers a non-false errorStatus as an error (makes sense) and passes that failure to the caller. I've hacked my local version to explicitly check for an errorStatus of 2, and clears that errorStatus/Index. This seems to work, but there may be a cleaner solution. pysnmp/entity/rfc3413/oneliner/cmdgen.py: class CommandGenerator(AsynCommandGenerator): ... def nextCmd(self, authData, transportTarget, *varNames): def __cbFun( sendRequestHandle, errorIndication, errorStatus, errorIndex, varBindTable, (varBindHead, varBindTotalTable, appReturn) ): if errorStatus == 2: # V1 terminates GETNEXT with an errorStatus of noSuchName # rather than a value of endOfMib (which v2c.PDUAPI replaces # with None). errorStatus = errorStatus.clone(0) errorIndex = errorIndex.clone(0) pass if errorIndication or errorStatus: ... Hopefully this information is helpful. Regards, Mark |