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