Revert "s4:librpc: Send orphaned PDU if a pending request is freed"
authorStefan Metzmacher <metze@samba.org>
Wed, 10 Jan 2024 16:04:15 +0000 (17:04 +0100)
committerStefan Metzmacher <metze@samba.org>
Thu, 8 Feb 2024 15:39:20 +0000 (16:39 +0100)
This reverts commit 5fad4a8a8c15b13ec84691c4855a8040f3602f91.

source4/librpc/rpc/dcerpc.c

index 8e832724ee776487b5c1c99cdedb50138d62855a..a18ad96fcdc24f13f73179f1c30a47039c8078bb 100644 (file)
@@ -71,9 +71,6 @@ struct rpc_request {
        bool verify_pcontext;
        bool cancelled;
        struct tevent_req *cancel_subreq;
-       bool orphaned;
-       struct tevent_req *orphaned_subreq;
-       uint32_t orphaned_generation;
 
        struct {
                void (*callback)(struct rpc_request *);
@@ -121,11 +118,6 @@ static struct tevent_req *dcerpc_submit_cancel_send(TALLOC_CTX *mem_ctx,
                                                  struct dcerpc_pipe *p,
                                                  uint32_t call_id);
 static NTSTATUS dcerpc_submit_cancel_recv(struct tevent_req *req);
-static struct tevent_req *dcerpc_submit_orphaned_send(TALLOC_CTX *mem_ctx,
-                                                     struct tevent_context *ev,
-                                                     struct dcerpc_pipe *p,
-                                                     uint32_t call_id);
-static NTSTATUS dcerpc_submit_orphaned_recv(struct tevent_req *req);
 
 /* destroy a dcerpc connection */
 static int dcerpc_connection_destructor(struct dcecli_connection *conn)
@@ -259,8 +251,6 @@ struct dcerpc_bh_raw_call_state {
 
 static void dcerpc_bh_raw_call_done(struct rpc_request *subreq);
 static bool dcerpc_bh_raw_call_cancel(struct tevent_req *req);
-static void dcerpc_bh_raw_call_cleanup(struct tevent_req *req,
-                                      enum tevent_req_state req_state);
 
 static struct tevent_req *dcerpc_bh_raw_call_send(TALLOC_CTX *mem_ctx,
                                                  struct tevent_context *ev,
@@ -305,7 +295,6 @@ static struct tevent_req *dcerpc_bh_raw_call_send(TALLOC_CTX *mem_ctx,
        state->subreq->async.private_data = req;
 
        tevent_req_set_cancel_fn(req, dcerpc_bh_raw_call_cancel);
-       tevent_req_set_cleanup_fn(req, dcerpc_bh_raw_call_cleanup);
 
        return req;
 }
@@ -386,129 +375,6 @@ static void dcerpc_bh_raw_call_cancelled(struct tevent_req *cancel_subreq)
        subreq->cancelled = true;
 }
 
-static void dcerpc_bh_raw_call_orphaned(struct tevent_req *orphaned_subreq);
-static void dcerpc_bh_raw_call_orphaned_cancelled(
-                                       struct tevent_req *cancel_subreq);
-static void dcerpc_bh_raw_call_free(struct rpc_request *subreq);
-
-static void dcerpc_bh_raw_call_cleanup(struct tevent_req *req,
-                                      enum tevent_req_state req_state)
-{
-       struct dcerpc_bh_raw_call_state *state =
-               tevent_req_data(req, struct dcerpc_bh_raw_call_state);
-       struct rpc_request *subreq = state->subreq;
-
-       if (req_state != TEVENT_REQ_RECEIVED) {
-               return;
-       }
-
-       switch (subreq->state) {
-       case RPC_REQUEST_DONE:
-               /* Nothing to do */
-               return;
-       case RPC_REQUEST_QUEUED:
-       {
-               /* Nothing to do, the rpc_request destructor will dequeue */
-               return;
-       }
-       case RPC_REQUEST_PENDING:
-       {
-               /* Send orphaned or cancel PDU */
-               break;
-       }
-       }
-
-       if (subreq->p->conn->bind_time_features &
-                       DCERPC_BIND_TIME_KEEP_CONNECTION_ON_ORPHAN) {
-               subreq->orphaned_subreq = dcerpc_submit_orphaned_send(
-                                                       subreq,
-                                                       state->ev,
-                                                       subreq->p,
-                                                       subreq->call_id);
-               if (subreq->orphaned_subreq == NULL) {
-                       DBG_ERR("No memory\n");
-                       return;
-               }
-               tevent_req_set_callback(subreq->orphaned_subreq,
-                                       dcerpc_bh_raw_call_orphaned,
-                                       subreq);
-
-               /*
-                * As req will be free when returning from this function
-                * move the subreq to the pipe talloc context and reset
-                * the callback to a function that just frees.
-                */
-               subreq->async.callback = dcerpc_bh_raw_call_free;
-               subreq->async.private_data = NULL;
-               talloc_move(subreq->p, &subreq);
-               return;
-       }
-
-       /* Fallback to co_cancel if co_orphan can't be used */
-
-       if (subreq->cancelled) {
-               /* co_cancel is already submitted */
-               return;
-       }
-
-       subreq->cancel_subreq = dcerpc_submit_cancel_send(subreq,
-                                                         state->ev,
-                                                         subreq->p,
-                                                         subreq->call_id);
-       if (subreq->cancel_subreq == NULL) {
-               DBG_ERR("No memory\n");
-               return;
-       }
-       tevent_req_set_callback(subreq->cancel_subreq,
-                               dcerpc_bh_raw_call_orphaned_cancelled,
-                               subreq);
-       subreq->async.callback = dcerpc_bh_raw_call_free;
-       subreq->async.private_data = NULL;
-       talloc_move(subreq->p, &subreq);
-}
-
-static void dcerpc_bh_raw_call_orphaned(struct tevent_req *orphaned_subreq)
-{
-       struct rpc_request *subreq = tevent_req_callback_data(
-                       orphaned_subreq, struct rpc_request);
-       NTSTATUS status;
-
-       status = dcerpc_submit_orphaned_recv(subreq->orphaned_subreq);
-       TALLOC_FREE(subreq->orphaned_subreq);
-       if (!NT_STATUS_IS_OK(status)) {
-               DBG_NOTICE("Failed to send orphaned PDU for call_id %u: "
-                          "%s\n", subreq->call_id, nt_errstr(status));
-               return;
-       }
-
-       subreq->orphaned = true;
-       subreq->orphaned_generation = subreq->p->conn->call_id;
-}
-
-static void dcerpc_bh_raw_call_orphaned_cancelled(
-                                       struct tevent_req *cancel_subreq)
-{
-       struct rpc_request *subreq = tevent_req_callback_data(
-                       cancel_subreq, struct rpc_request);
-       NTSTATUS status;
-
-       status = dcerpc_submit_orphaned_recv(subreq->cancel_subreq);
-       TALLOC_FREE(subreq->cancel_subreq);
-       if (!NT_STATUS_IS_OK(status)) {
-               DBG_NOTICE("Failed to send cancel PDU for call_id %u: "
-                          "%s\n", subreq->call_id, nt_errstr(status));
-               return;
-       }
-
-       subreq->cancelled = true;
-       subreq->orphaned_generation = subreq->p->conn->call_id;
-}
-
-static void dcerpc_bh_raw_call_free(struct rpc_request *subreq)
-{
-       TALLOC_FREE(subreq);
-}
-
 static void dcerpc_bh_raw_call_done(struct rpc_request *subreq)
 {
        struct tevent_req *req =
@@ -1534,43 +1400,6 @@ NTSTATUS dcerpc_auth3(struct dcerpc_pipe *p,
        return NT_STATUS_OK;    
 }
 
-/*
- * Finds a pending rpc_request in the pending calls list and frees
- * stale orphaned rpc_requests.
- */
-static struct rpc_request *dcerpc_find_pending_request(
-                                               struct dcecli_connection *c,
-                                               uint32_t call_id)
-{
-       struct rpc_request *req = NULL;
-       struct rpc_request *it = NULL;
-       struct rpc_request *free = NULL;
-
-       for (it = c->pending; it != NULL; it = it->next) {
-               /*
-                * If the request is orphaned and we got a response to a
-                * request that started after we submitted the co_cancel
-                * or co_orphan PDUs then queue for free
-                */
-               if (it->orphaned_generation != 0 &&
-                   it->orphaned_generation < call_id) {
-                       DLIST_ADD(free, it);
-                       continue;
-               }
-
-               if (it->call_id == call_id) {
-                       req = it;
-               }
-       }
-
-       while (free != NULL) {
-               it = free;
-               DLIST_REMOVE(free, it);
-               TALLOC_FREE(it);
-       }
-
-       return req;
-}
 
 /*
   process a fragment received from the transport layer during a
@@ -1609,7 +1438,9 @@ static void dcerpc_request_recv_data(struct dcecli_connection *c,
        }
 
        /* find the matching request */
-       req = dcerpc_find_pending_request(c, pkt->call_id);
+       for (req=c->pending;req;req=req->next) {
+               if (pkt->call_id == req->call_id) break;
+       }
 
 #if 0
        /* useful for testing certain vendors RPC servers */
@@ -2995,6 +2826,7 @@ struct dcerpc_submit_orphaned_state {
 
 static void dcerpc_writev_orphaned_done(struct tevent_req *subreq);
 
+_UNUSED_
 static struct tevent_req *dcerpc_submit_orphaned_send(TALLOC_CTX *mem_ctx,
                                                      struct tevent_context *ev,
                                                      struct dcerpc_pipe *p,
@@ -3081,6 +2913,7 @@ static void dcerpc_writev_orphaned_done(struct tevent_req *subreq)
        tevent_req_done(req);
 }
 
+_UNUSED_
 static NTSTATUS dcerpc_submit_orphaned_recv(struct tevent_req *req)
 {
        return tevent_req_simple_recv_ntstatus(req);