appl_request_downstream_free gets called from 3 locations:
- appl_request_upstream_free: called from appl_request_upstream_reply
  and cleans up after a request has been answered, whether all the
  downstream requests have been completed or not (when timed out)
- appl_response: When a downstream reqeuest has been completed
- appl_close: When a downstream backend has been closed.

appl_request_upstream_free is already done with the upstream request
and appl_response already automatically starts the next iteration of
missing varbinds.

The problem arrises when appl_close is called (e.g. a backend
disappears unexpected) while there are still pending downstream
requests. In that case all references to the upstream request are
lost and we have a memory leak.

Diff below resets the pending varbinds to new and restarts the
parsing procedure.

OK?

martijn@

Index: application.c
===================================================================
RCS file: /cvs/src/usr.sbin/snmpd/application.c,v
retrieving revision 1.6
diff -u -p -r1.6 application.c
--- application.c       30 Jun 2022 11:28:36 -0000      1.6
+++ application.c       22 Jul 2022 14:59:00 -0000
@@ -716,6 +716,7 @@ void
 appl_request_downstream_free(struct appl_request_downstream *dreq)
 {
        struct appl_varbind_internal *vb;
+       int retry = 0;
 
        if (dreq == NULL)
                return;
@@ -723,9 +724,16 @@ appl_request_downstream_free(struct appl
        RB_REMOVE(appl_requests, &(dreq->ard_backend->ab_requests), dreq);
        evtimer_del(&(dreq->ard_timer));
 
-       for (vb = dreq->ard_vblist; vb != NULL; vb = vb->avi_next)
+       for (vb = dreq->ard_vblist; vb != NULL; vb = vb->avi_next) { 
                vb->avi_request_downstream = NULL;
+               if (vb->avi_state == APPL_VBSTATE_PENDING) {
+                       vb->avi_state = APPL_VBSTATE_NEW;
+                       retry = 1;
+               }
+       }
 
+       if (retry)
+               appl_request_upstream_resolve(dreq->ard_request);
        free(dreq);
 }
 

Reply via email to