r18363: Found a rather nasty bug in our fragment handling.
authorAndrew Bartlett <abartlet@samba.org>
Mon, 11 Sep 2006 06:17:12 +0000 (06:17 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:18:19 +0000 (14:18 -0500)
We were adding packet fragments onto the *reply* queue, not the
recieve queue.  This worked, as long as we got a whole packet before
we did any reply work, but failed once the backend called a remote
LDAP server (and I presume something invoked the event loop).

Andrew Bartlett
(This used to be commit a0162e0ace48104d94f7b7dd3d2f62a7f42e10c6)

source4/rpc_server/dcerpc_server.c
source4/rpc_server/dcerpc_server.h

index c467728747e287a081047ee9873cfb329cae7e65..980fd5490b394a94c352829b352b7bde038c9dfa 100644 (file)
@@ -133,12 +133,12 @@ static const struct dcesrv_interface *find_interface_by_uuid(const struct dcesrv
 }
 
 /*
-  find a call that is pending in our call list
+  find the earlier parts of a fragmented call awaiting reassembily
 */
-static struct dcesrv_call_state *dcesrv_find_call(struct dcesrv_connection *dce_conn, uint16_t call_id)
+static struct dcesrv_call_state *dcesrv_find_fragmented_call(struct dcesrv_connection *dce_conn, uint16_t call_id)
 {
        struct dcesrv_call_state *c;
-       for (c=dce_conn->call_list;c;c=c->next) {
+       for (c=dce_conn->incoming_fragmented_call_list;c;c=c->next) {
                if (c->pkt.call_id == call_id) {
                        return c;
                }
@@ -1013,7 +1013,7 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn)
 
                /* this is a continuation of an existing call - find the call then
                   tack it on the end */
-               call = dcesrv_find_call(dce_conn, call2->pkt.call_id);
+               call = dcesrv_find_fragmented_call(dce_conn, call2->pkt.call_id);
                if (!call) {
                        return dcesrv_fault(call2, DCERPC_FAULT_OTHER);
                }
@@ -1049,10 +1049,11 @@ NTSTATUS dcesrv_input_process(struct dcesrv_connection *dce_conn)
        }
 
        /* this may not be the last pdu in the chain - if its isn't then
-          just put it on the call_list and wait for the rest */
+          just put it on the incoming_fragmented_call_list and wait for the rest */
        if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
            !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) {
-               DLIST_ADD_END(dce_conn->call_list, call, struct dcesrv_call_state *);
+               DLIST_ADD_END(dce_conn->incoming_fragmented_call_list, call, 
+                             struct dcesrv_call_state *);
                return NT_STATUS_OK;
        }
 
index 031ace49d716dc1169fb42898cf45ee2e4f2780e..2990d6e09f466d60dd6020ca205d36d69c971bcc 100644 (file)
@@ -168,12 +168,15 @@ struct dcesrv_connection {
        /* a list of established context_ids */
        struct dcesrv_connection_context *contexts;
 
-       /* the state of the current calls */
-       struct dcesrv_call_state *call_list;
+       /* the state of the current incoming call fragments */
+       struct dcesrv_call_state *incoming_fragmented_call_list;
 
        /* the state of the async pending calls */
        struct dcesrv_call_state *pending_call_list;
 
+       /* the state of the current outgoing calls */
+       struct dcesrv_call_state *call_list;
+
        /* the maximum size the client wants to receive */
        uint32_t cli_max_recv_frag;