A number of new ideas and improvements have been suggested over the past couple of months and I have been slowly catching up on them.
First was the introduction of IPv6 support which was interesting, not only because of the extended feature support within SnmpSharpNet but also from my personal interest in the protocol. I have integrated the code required in UdpTarget and UdpTransport classes and it seams to work in the limited testing I have been able to do in my home lab. Goal of the implementation was not to impact existing functionality and to make IPv6 usable within the same class, method, parameter structure as with IPv4 support alone.
I had it pointed out to me by Pavel Tatarinov that SNMPv3 operation is very slow for the reason of continuous need to generate authentication and privacy keys for each call. This is not very efficient since when the engine id has been obtained through the discovery process, none of the information needed for authentication and privacy key generation changes in subsequent calls. Caching of some sort seams to be in order.
During the first few tests I performed, a GetNext walk operation on a subtree with 39 items resulted in 156 calls to the PasswordToKey method of the selected authentication protocol class. Considering how key is generated, each call resulted in a significant delay between GetNext calls. Significant enough that walk operation result on the console was visibly slow.
To work around this, I have added PrivacyKey and AuthenticationKey properties to the SecureAgentParameters class that allows for caching of required keys. I have also created BuildCachedSecurityKeys() method to the same class that will generate the keys for both authentication and privacy (if they are appropriate for the selected security model) and cached keys will then be used by every request made using UdpTarget class.
After required changes were made, number of calls to PasswordToKey method have dropped to just 2 and execution speed is visibly better. Looking in a profiler, execution of the above mentioned walk with described changes has reduced running time from 2223ms to 478ms. Anything that results in order of magnitude improvement in speed is good so I’m putting this in a plus column.
One of the bug fixes I introduced in the last revision was related to the source host IP address and port number check. The way it is done in the code is that check was not performed when requested. It is only performed when not requested. Since this is opposite of the required behavior, fix is necessary and will be included in the next version.
A bug that took up most of my time and resulted in no fix is the issue with the Socket class on Windows XP when network cable is disconnected. It appears that once network cable is disconnected, Socket becomes unusable and needs to be recreated. Big problem is that when you first disconnect the network cable, any call to UdpTarget class or network event generated within the class results in a NullArgumentException being thrown with no way to catch it. I have gone through all the calls, wrapped them all into try/catch blocks and still didn’t manage to figure out how or why this is happening. What makes it even more interesting is that it only happens on Windows XP. I didn’t manage to replicate the same issue on Vista or Win7.
The only way to deal with this that I could see was to add a whole new layer of code to monitor network interface status and when connection is disabled put UdpTarget and UdpTransport classes into special state which releases the internal Socket reference until network connectivity is restored. Unfortunately, there is no easy way to do this. It would require a lot of additional code to implement this fix and, more of a concern for me, a lot more effort to support it.
For now, status of this issue is that it can be replicated but there doesn’t not appear to be a way to fix the issue with managed code so application writers will have to build their own code to check for events that could cause uncatchable exceptions. If anybody out there has any information on what could cause this kind of a problem, I would appreciate a pointer.
Now a little about future plans. I’ve spent some time wrapping my mind around MIB parsing and it doesn’t look like I’ll be able to do a quick hack to get this functionality of the ground. My “quick and dirty” parser that I whipped out in a week works ok up to a point but there are MIB file formats that it can’t deal with and it provides very limited subset of information that is available in MIB files that I don’t consider it acceptable. So, instead of looking at just throwing something out there and calling it quits, I decided to devote this winter (or non-golfing season if you prefer) to developing a proper ASN.1 parser. Plan for the library is to advance to version 0.9 with a usable parser.
Final step in the libraries path to version 1 is to include AgentX protocol support. Development plan for the library was never to make it capable of building Master SNMP agents because there is enough of them available for free and another one would not add any value to the potential users. What could be very useful to a number of people is to allow their managed code applications to register their MIB sub-tree with the master SNMP agent that already exists on the machine (server or workstation) and provide status information (or receive commands) from remote management stations through the master agent using SNMP protocol. AgentX protocol is a pain, it has way too many message types and is created for maximum flexibility of registering applications. While very handy for users, this makes it difficult to provide a simple interface in a library so I will be spending some time trying to identify most common use cases and required interfaces to implement it before getting down to the coding part.
That’s the story so far. If anybody has any suggestions on improvements, additional features or any other constructive comments, don’t hesitate to send them to me on dev [at] snmpsharpnet [dot] com.