Hi!

First mail to this mailing list, and I admit I haven't managed to read up on the last few years of discussion, so sorry if I'm bringing up already discussed topics.

I've recently taken over maintenance of a few of the modules we're using for both ends of our SNMP functionality, where we have a standard snmpd acting as AgentX with multiple SNMPv3 agents, each with their own context. On the other end of things we boil our SNMP requests down to a simple web interface where each of these contexts, which are entered by the users, are shown as separate sub trees/application nodes. The users may enter any context name, which we will gladly try to find.

This leads us to the issue; If the agents with that specific context has not yet connected to the snmpd, we get the expected behavior, protocol/response wise, as this case is detected in snmp_agent.c:1933 (in the 5.7.2 source code), and quite well documented. However, "on the way out", nothing is done with the pdu->securityStateRef in this case, which in our case generates a leak of about 1GB of unfreed securityStateRefs if I leave it overnight (with 65 unknown contexts for each of which there is a request every 5 seconds).

In the "correct case" where the context exists, the securityStateRef is kept, as it's queued up in netsnmp_handle_request, and later on freed once the request has been fulfilled.

If an agent with that specific context has been connected once, the context is no longer handled as unknown and everything seems to be handled fine, and memory is freed.

Our invocation of handle_snmp_packet is from snmp_api.c:5411 (sp->callback being executed).

The solution I have in place right now, which seems to work fine, is to just after the call to netsnmp_remove_and_free_agent_snmp_session add the same routines as is available at snmp_api.c:5260 and snmp_api.c:5422 (which I can see in the git repository has been converted to the function free_securityStateRef).

This does eliminate the memory leak on our test environment at least.

I thought I'd throw this in for discussion if you believe it is a bad approach to solving the memory leak for this case? I've also attached a unified diff against current git HEAD, to get a easier grasp on the fix...

One thought I had myself is that it might be a cleaner approach to handle the error inside of snmp_api.c instead, to leave the agent code less dependant on the pdu memory operations, but the unhandled context logic seems to be the most direct application of a fix, so I'm a bit split about whats the best approach, and me just starting to look at the code base gives me just about zero knowledge about the convention used for this kind of fixes in this library. :)

As for our environment, and versions we noticed this issue with: Both win32 and win64 msvc2010 builds of the snmpd application shows the leak, the issue was noticed in the 5.6.1 version of Net-SNMP, and the issue still persisting in the 5.7.2 source code. Servers this leak has been seen on is Windows Server 2003, 2008, 2008R2 and 2012.

Best regards
Patrik Thunström / patrik.thunst...@basset.com
 agent/snmp_agent.c         | 1 +
 include/net-snmp/pdu_api.h | 3 +++
 snmplib/snmp_api.c         | 2 +-
 3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/agent/snmp_agent.c b/agent/snmp_agent.c
index 1261c53..f6dbf8b 100644
--- a/agent/snmp_agent.c
+++ b/agent/snmp_agent.c
@@ -1952,6 +1952,7 @@ handle_snmp_packet(int op, netsnmp_session * session, int 
reqid,
              * drop the request 
              */
             netsnmp_remove_and_free_agent_snmp_session(asp);
+            free_securityStateRef(pdu);
             return 0;
         } else {
             /*
diff --git a/include/net-snmp/pdu_api.h b/include/net-snmp/pdu_api.h
index 125595d..d77ea46 100644
--- a/include/net-snmp/pdu_api.h
+++ b/include/net-snmp/pdu_api.h
@@ -20,6 +20,9 @@ netsnmp_pdu    *snmp_fix_pdu(  netsnmp_pdu *pdu, int idx);
 NETSNMP_IMPORT
 void            snmp_free_pdu( netsnmp_pdu *pdu);
 
+NETSNMP_IMPORT
+void            free_securityStateRef(netsnmp_pdu* pdu);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/snmplib/snmp_api.c b/snmplib/snmp_api.c
index f7b0e06..d84725d 100644
--- a/snmplib/snmp_api.c
+++ b/snmplib/snmp_api.c
@@ -3829,7 +3829,7 @@ snmpv3_parse(netsnmp_pdu *pdu,
     return SNMPERR_SUCCESS;
 }                               /* end snmpv3_parse() */
 
-static void
+void
 free_securityStateRef(netsnmp_pdu* pdu)
 {
     struct snmp_secmod_def *sptr = find_sec_mod(pdu->securityModel);
------------------------------------------------------------------------------
Introducing AppDynamics Lite, a free troubleshooting tool for Java/.NET
Get 100% visibility into your production application - at no cost.
Code-level diagnostics for performance bottlenecks with <2% overhead
Download for free and get started troubleshooting in minutes.
http://p.sf.net/sfu/appdyn_d2d_ap1
_______________________________________________
Net-snmp-coders mailing list
Net-snmp-coders@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/net-snmp-coders

Reply via email to