Blame SOURCES/net-snmp-5.7.2-agentx-disconnect-crash.patch

9a6c41
969061 - net-snmpd crash on time out
9a6c41
9a6c41
ABI breaking upstream patch.
9a6c41
9a6c41
commit 793d596838ff7cb48a73b675d62897c56c9e62df
9a6c41
Author: Jan Safranek <jsafranek@users.sourceforge.net>
9a6c41
Date:   Tue Jul 2 14:32:56 2013 +0200
9a6c41
9a6c41
    From: Jiri Cervenka: snmpd: Fixed agentx crashing and/or freezing on timeout.
9a6c41
    
9a6c41
    Queued requests are dropped gracefuly.
9a6c41
9a6c41
diff --git a/agent/mibgroup/agentx/master_admin.c b/agent/mibgroup/agentx/master_admin.c
9a6c41
index 999128a..4b42104 100644
9a6c41
--- a/agent/mibgroup/agentx/master_admin.c
9a6c41
+++ b/agent/mibgroup/agentx/master_admin.c
9a6c41
@@ -158,6 +158,7 @@ close_agentx_session(netsnmp_session * session, int sessid)
9a6c41
     for (sp = session->subsession; sp != NULL; sp = sp->next) {
9a6c41
 
9a6c41
         if (sp->sessid == sessid) {
9a6c41
+            netsnmp_remove_delegated_requests_for_session(sp);
9a6c41
             unregister_mibs_by_session(sp);
9a6c41
             unregister_index_by_session(sp);
9a6c41
             unregister_sysORTable_by_session(sp);
9a6c41
diff --git a/agent/snmp_agent.c b/agent/snmp_agent.c
9a6c41
index 1261c53..51eb287 100644
9a6c41
--- a/agent/snmp_agent.c
9a6c41
+++ b/agent/snmp_agent.c
9a6c41
@@ -1415,6 +1415,7 @@ init_agent_snmp_session(netsnmp_session * session, netsnmp_pdu *pdu)
9a6c41
     asp->treecache_num = -1;
9a6c41
     asp->treecache_len = 0;
9a6c41
     asp->reqinfo = SNMP_MALLOC_TYPEDEF(netsnmp_agent_request_info);
9a6c41
+    asp->flags = SNMP_AGENT_FLAGS_NONE;
9a6c41
     DEBUGMSGTL(("verbose:asp", "asp %p reqinfo %p created\n",
9a6c41
                 asp, asp->reqinfo));
9a6c41
 
9a6c41
@@ -1463,6 +1464,9 @@ netsnmp_check_for_delegated(netsnmp_agent_session *asp)
9a6c41
 
9a6c41
     if (NULL == asp->treecache)
9a6c41
         return 0;
9a6c41
+
9a6c41
+    if (asp->flags & SNMP_AGENT_FLAGS_CANCEL_IN_PROGRESS)
9a6c41
+        return 0;
9a6c41
     
9a6c41
     for (i = 0; i <= asp->treecache_num; i++) {
9a6c41
         for (request = asp->treecache[i].requests_begin; request;
9a6c41
@@ -1541,39 +1545,48 @@ int
9a6c41
 netsnmp_remove_delegated_requests_for_session(netsnmp_session *sess)
9a6c41
 {
9a6c41
     netsnmp_agent_session *asp;
9a6c41
-    int count = 0;
9a6c41
+    int total_count = 0;
9a6c41
     
9a6c41
     for (asp = agent_delegated_list; asp; asp = asp->next) {
9a6c41
         /*
9a6c41
          * check each request
9a6c41
          */
9a6c41
+        int i;
9a6c41
+        int count = 0;
9a6c41
         netsnmp_request_info *request;
9a6c41
-        for(request = asp->requests; request; request = request->next) {
9a6c41
-            /*
9a6c41
-             * check session
9a6c41
-             */
9a6c41
-            netsnmp_assert(NULL!=request->subtree);
9a6c41
-            if(request->subtree->session != sess)
9a6c41
-                continue;
9a6c41
+        for (i = 0; i <= asp->treecache_num; i++) {
9a6c41
+            for (request = asp->treecache[i].requests_begin; request;
9a6c41
+                 request = request->next) {
9a6c41
+                /*
9a6c41
+                 * check session
9a6c41
+                 */
9a6c41
+                netsnmp_assert(NULL!=request->subtree);
9a6c41
+                if(request->subtree->session != sess)
9a6c41
+                    continue;
9a6c41
 
9a6c41
-            /*
9a6c41
-             * matched! mark request as done
9a6c41
-             */
9a6c41
-            netsnmp_request_set_error(request, SNMP_ERR_GENERR);
9a6c41
-            ++count;
9a6c41
+                /*
9a6c41
+                 * matched! mark request as done
9a6c41
+                 */
9a6c41
+                netsnmp_request_set_error(request, SNMP_ERR_GENERR);
9a6c41
+                ++count;
9a6c41
+            }
9a6c41
+        }
9a6c41
+        if (count) {
9a6c41
+            asp->flags |= SNMP_AGENT_FLAGS_CANCEL_IN_PROGRESS;
9a6c41
+            total_count += count;
9a6c41
         }
9a6c41
     }
9a6c41
 
9a6c41
     /*
9a6c41
      * if we found any, that request may be finished now
9a6c41
      */
9a6c41
-    if(count) {
9a6c41
+    if(total_count) {
9a6c41
         DEBUGMSGTL(("snmp_agent", "removed %d delegated request(s) for session "
9a6c41
-                    "%8p\n", count, sess));
9a6c41
-        netsnmp_check_outstanding_agent_requests();
9a6c41
+                    "%8p\n", total_count, sess));
9a6c41
+        netsnmp_check_delegated_requests();
9a6c41
     }
9a6c41
     
9a6c41
-    return count;
9a6c41
+    return total_count;
9a6c41
 }
9a6c41
 
9a6c41
 int
9a6c41
@@ -2745,19 +2758,11 @@ handle_var_requests(netsnmp_agent_session *asp)
9a6c41
     return final_status;
9a6c41
 }
9a6c41
 
9a6c41
-/*
9a6c41
- * loop through our sessions known delegated sessions and check to see
9a6c41
- * if they've completed yet. If there are no more delegated sessions,
9a6c41
- * check for and process any queued requests
9a6c41
- */
9a6c41
 void
9a6c41
-netsnmp_check_outstanding_agent_requests(void)
9a6c41
+netsnmp_check_delegated_requests(void)
9a6c41
 {
9a6c41
     netsnmp_agent_session *asp, *prev_asp = NULL, *next_asp = NULL;
9a6c41
 
9a6c41
-    /*
9a6c41
-     * deal with delegated requests
9a6c41
-     */
9a6c41
     for (asp = agent_delegated_list; asp; asp = next_asp) {
9a6c41
         next_asp = asp->next;   /* save in case we clean up asp */
9a6c41
         if (!netsnmp_check_for_delegated(asp)) {
9a6c41
@@ -2796,6 +2801,22 @@ netsnmp_check_outstanding_agent_requests(void)
9a6c41
             prev_asp = asp;
9a6c41
         }
9a6c41
     }
9a6c41
+}
9a6c41
+
9a6c41
+/*
9a6c41
+ * loop through our sessions known delegated sessions and check to see
9a6c41
+ * if they've completed yet. If there are no more delegated sessions,
9a6c41
+ * check for and process any queued requests
9a6c41
+ */
9a6c41
+void
9a6c41
+netsnmp_check_outstanding_agent_requests(void)
9a6c41
+{
9a6c41
+    netsnmp_agent_session *asp;
9a6c41
+
9a6c41
+    /*
9a6c41
+     * deal with delegated requests
9a6c41
+     */
9a6c41
+    netsnmp_check_delegated_requests();
9a6c41
 
9a6c41
     /*
9a6c41
      * if we are processing a set and there are more delegated
9a6c41
@@ -2825,7 +2846,8 @@ netsnmp_check_outstanding_agent_requests(void)
9a6c41
 
9a6c41
             netsnmp_processing_set = netsnmp_agent_queued_list;
9a6c41
             DEBUGMSGTL(("snmp_agent", "SET request remains queued while "
9a6c41
-                        "delegated requests finish, asp = %8p\n", asp));
9a6c41
+                        "delegated requests finish, asp = %8p\n",
9a6c41
+                        agent_delegated_list));
9a6c41
             break;
9a6c41
         }
9a6c41
 #endif /* NETSNMP_NO_WRITE_SUPPORT */
9a6c41
@@ -2886,6 +2908,10 @@ check_delayed_request(netsnmp_agent_session *asp)
9a6c41
     case SNMP_MSG_GETBULK:
9a6c41
     case SNMP_MSG_GETNEXT:
9a6c41
         netsnmp_check_all_requests_status(asp, 0);
9a6c41
+        if (asp->flags & SNMP_AGENT_FLAGS_CANCEL_IN_PROGRESS) {
9a6c41
+            DEBUGMSGTL(("snmp_agent","canceling next walk for asp %p\n", asp));
9a6c41
+            break;
9a6c41
+        }
9a6c41
         handle_getnext_loop(asp);
9a6c41
         if (netsnmp_check_for_delegated(asp) &&
9a6c41
             netsnmp_check_transaction_id(asp->pdu->transid) !=
9a6c41
diff --git a/include/net-snmp/agent/snmp_agent.h b/include/net-snmp/agent/snmp_agent.h
9a6c41
index aad8837..43f4fff 100644
9a6c41
--- a/include/net-snmp/agent/snmp_agent.h
9a6c41
+++ b/include/net-snmp/agent/snmp_agent.h
9a6c41
@@ -32,6 +32,9 @@ extern          "C" {
9a6c41
 #define SNMP_MAX_PDU_SIZE 64000 /* local constraint on PDU size sent by agent
9a6c41
                                  * (see also SNMP_MAX_MSG_SIZE in snmp_api.h) */
9a6c41
 
9a6c41
+#define SNMP_AGENT_FLAGS_NONE                   0x0
9a6c41
+#define SNMP_AGENT_FLAGS_CANCEL_IN_PROGRESS     0x1
9a6c41
+
9a6c41
     /*
9a6c41
      * If non-zero, causes the addresses of peers to be logged when receptions
9a6c41
      * occur.  
9a6c41
@@ -205,6 +208,7 @@ extern          "C" {
9a6c41
         int             treecache_num;  /* number of current cache entries */
9a6c41
         netsnmp_cachemap *cache_store;
9a6c41
         int             vbcount;
9a6c41
+        int             flags;
9a6c41
     } netsnmp_agent_session;
9a6c41
 
9a6c41
     /*
9a6c41
@@ -240,6 +244,7 @@ extern          "C" {
9a6c41
     int             init_master_agent(void);
9a6c41
     void            shutdown_master_agent(void);
9a6c41
     int             agent_check_and_process(int block);
9a6c41
+    void            netsnmp_check_delegated_requests(void);
9a6c41
     void            netsnmp_check_outstanding_agent_requests(void);
9a6c41
 
9a6c41
     int             netsnmp_request_set_error(netsnmp_request_info *request,