|
1 http://sourceforge.net/p/net-snmp/code/ci/793d596838ff7cb48a73b675d62897c56c9e62df |
|
2 http://sourceforge.net/p/net-snmp/patches/1237/?page=0 |
|
3 |
|
4 diff --git a/agent/mibgroup/agentx/master_admin.c b/agent/mibgroup/agentx/master_admin.c |
|
5 index a04b18a..82c1fbf 100644 |
|
6 --- a/agent/mibgroup/agentx/master_admin.c |
|
7 +++ b/agent/mibgroup/agentx/master_admin.c |
|
8 @@ -161,6 +161,7 @@ close_agentx_session(netsnmp_session * session, int sessid) |
|
9 for (sp = session->subsession; sp != NULL; sp = sp->next) { |
|
10 |
|
11 if (sp->sessid == sessid) { |
|
12 + netsnmp_remove_delegated_requests_for_session(sp); |
|
13 unregister_mibs_by_session(sp); |
|
14 unregister_index_by_session(sp); |
|
15 snmp_call_callbacks(SNMP_CALLBACK_APPLICATION, |
|
16 diff --git a/agent/snmp_agent.c b/agent/snmp_agent.c |
|
17 index c655900..466ec4c 100644 |
|
18 --- a/agent/snmp_agent.c |
|
19 +++ b/agent/snmp_agent.c |
|
20 @@ -1286,6 +1286,7 @@ init_agent_snmp_session(netsnmp_session * session, netsnmp_pdu *pdu) |
|
21 asp->treecache_num = -1; |
|
22 asp->treecache_len = 0; |
|
23 asp->reqinfo = SNMP_MALLOC_TYPEDEF(netsnmp_agent_request_info); |
|
24 + asp->flags = SNMP_AGENT_FLAGS_NONE; |
|
25 DEBUGMSGTL(("verbose:asp", "asp %p reqinfo %p created\n", |
|
26 asp, asp->reqinfo)); |
|
27 |
|
28 @@ -1338,6 +1339,9 @@ netsnmp_check_for_delegated(netsnmp_agent_session *asp) |
|
29 |
|
30 if (NULL == asp->treecache) |
|
31 return 0; |
|
32 + |
|
33 + if (asp->flags & SNMP_AGENT_FLAGS_CANCEL_IN_PROGRESS) |
|
34 + return 0; |
|
35 |
|
36 for (i = 0; i <= asp->treecache_num; i++) { |
|
37 for (request = asp->treecache[i].requests_begin; request; |
|
38 @@ -1416,39 +1420,48 @@ int |
|
39 netsnmp_remove_delegated_requests_for_session(netsnmp_session *sess) |
|
40 { |
|
41 netsnmp_agent_session *asp; |
|
42 - int count = 0; |
|
43 + int total_count = 0; |
|
44 |
|
45 for (asp = agent_delegated_list; asp; asp = asp->next) { |
|
46 /* |
|
47 * check each request |
|
48 */ |
|
49 + int i; |
|
50 + int count = 0; |
|
51 netsnmp_request_info *request; |
|
52 - for(request = asp->requests; request; request = request->next) { |
|
53 - /* |
|
54 - * check session |
|
55 - */ |
|
56 - netsnmp_assert(NULL!=request->subtree); |
|
57 - if(request->subtree->session != sess) |
|
58 - continue; |
|
59 + for (i = 0; i <= asp->treecache_num; i++) { |
|
60 + for (request = asp->treecache[i].requests_begin; request; |
|
61 + request = request->next) { |
|
62 + /* |
|
63 + * check session |
|
64 + */ |
|
65 + netsnmp_assert(NULL!=request->subtree); |
|
66 + if(request->subtree->session != sess) |
|
67 + continue; |
|
68 |
|
69 - /* |
|
70 - * matched! mark request as done |
|
71 - */ |
|
72 - netsnmp_request_set_error(request, SNMP_ERR_GENERR); |
|
73 - ++count; |
|
74 + /* |
|
75 + * matched! mark request as done |
|
76 + */ |
|
77 + netsnmp_request_set_error(request, SNMP_ERR_GENERR); |
|
78 + ++count; |
|
79 + } |
|
80 + } |
|
81 + if (count) { |
|
82 + asp->flags |= SNMP_AGENT_FLAGS_CANCEL_IN_PROGRESS; |
|
83 + total_count += count; |
|
84 } |
|
85 } |
|
86 |
|
87 /* |
|
88 * if we found any, that request may be finished now |
|
89 */ |
|
90 - if(count) { |
|
91 + if(total_count) { |
|
92 DEBUGMSGTL(("snmp_agent", "removed %d delegated request(s) for session " |
|
93 - "%08p\n", count, sess)); |
|
94 - netsnmp_check_outstanding_agent_requests(); |
|
95 + "%08p\n", total_count, sess)); |
|
96 + netsnmp_check_delegated_requests(); |
|
97 } |
|
98 |
|
99 - return count; |
|
100 + return total_count; |
|
101 } |
|
102 |
|
103 int |
|
104 @@ -2587,19 +2600,11 @@ handle_var_requests(netsnmp_agent_session *asp) |
|
105 return final_status; |
|
106 } |
|
107 |
|
108 -/* |
|
109 - * loop through our sessions known delegated sessions and check to see |
|
110 - * if they've completed yet. If there are no more delegated sessions, |
|
111 - * check for and process any queued requests |
|
112 - */ |
|
113 void |
|
114 -netsnmp_check_outstanding_agent_requests(void) |
|
115 +netsnmp_check_delegated_requests(void) |
|
116 { |
|
117 netsnmp_agent_session *asp, *prev_asp = NULL, *next_asp = NULL; |
|
118 |
|
119 - /* |
|
120 - * deal with delegated requests |
|
121 - */ |
|
122 for (asp = agent_delegated_list; asp; asp = next_asp) { |
|
123 next_asp = asp->next; /* save in case we clean up asp */ |
|
124 if (!netsnmp_check_for_delegated(asp)) { |
|
125 @@ -2638,6 +2643,22 @@ netsnmp_check_outstanding_agent_requests(void) |
|
126 prev_asp = asp; |
|
127 } |
|
128 } |
|
129 +} |
|
130 + |
|
131 +/* |
|
132 + * loop through our sessions known delegated sessions and check to see |
|
133 + * if they've completed yet. If there are no more delegated sessions, |
|
134 + * check for and process any queued requests |
|
135 + */ |
|
136 +void |
|
137 +netsnmp_check_outstanding_agent_requests(void) |
|
138 +{ |
|
139 + netsnmp_agent_session *asp; |
|
140 + |
|
141 + /* |
|
142 + * deal with delegated requests |
|
143 + */ |
|
144 + netsnmp_check_delegated_requests(); |
|
145 |
|
146 /* |
|
147 * if we are processing a set and there are more delegated |
|
148 @@ -2666,7 +2687,8 @@ netsnmp_check_outstanding_agent_requests(void) |
|
149 |
|
150 netsnmp_processing_set = netsnmp_agent_queued_list; |
|
151 DEBUGMSGTL(("snmp_agent", "SET request remains queued while " |
|
152 - "delegated requests finish, asp = %08p\n", asp)); |
|
153 + "delegated requests finish, asp = %08p\n", |
|
154 + agent_delegated_list)); |
|
155 break; |
|
156 } |
|
157 |
|
158 @@ -2726,6 +2748,10 @@ check_delayed_request(netsnmp_agent_session *asp) |
|
159 case SNMP_MSG_GETBULK: |
|
160 case SNMP_MSG_GETNEXT: |
|
161 netsnmp_check_all_requests_status(asp, 0); |
|
162 + if (asp->flags & SNMP_AGENT_FLAGS_CANCEL_IN_PROGRESS) { |
|
163 + DEBUGMSGTL(("snmp_agent","canceling next walk for asp %p\n", asp)); |
|
164 + break; |
|
165 + } |
|
166 handle_getnext_loop(asp); |
|
167 if (netsnmp_check_for_delegated(asp) && |
|
168 netsnmp_check_transaction_id(asp->pdu->transid) != |
|
169 diff --git a/include/net-snmp/agent/snmp_agent.h b/include/net-snmp/agent/snmp_agent.h |
|
170 index fd84f0f..efbeb5b 100644 |
|
171 --- a/include/net-snmp/agent/snmp_agent.h |
|
172 +++ b/include/net-snmp/agent/snmp_agent.h |
|
173 @@ -32,6 +32,9 @@ extern "C" { |
|
174 #define SNMP_MAX_PDU_SIZE 64000 /* local constraint on PDU size sent by agent |
|
175 * (see also SNMP_MAX_MSG_SIZE in snmp_api.h) */ |
|
176 |
|
177 +#define SNMP_AGENT_FLAGS_NONE 0x0 |
|
178 +#define SNMP_AGENT_FLAGS_CANCEL_IN_PROGRESS 0x1 |
|
179 + |
|
180 /* |
|
181 * If non-zero, causes the addresses of peers to be logged when receptions |
|
182 * occur. |
|
183 @@ -197,6 +200,7 @@ extern "C" { |
|
184 int treecache_num; /* number of current cache entries */ |
|
185 netsnmp_cachemap *cache_store; |
|
186 int vbcount; |
|
187 + int flags; |
|
188 } netsnmp_agent_session; |
|
189 |
|
190 /* |
|
191 @@ -231,6 +235,7 @@ extern "C" { |
|
192 int init_master_agent(void); |
|
193 void shutdown_master_agent(void); |
|
194 int agent_check_and_process(int block); |
|
195 + void netsnmp_check_delegated_requests(void); |
|
196 void netsnmp_check_outstanding_agent_requests(void); |
|
197 |
|
198 int netsnmp_request_set_error(netsnmp_request_info *request, |
|
199 |