s4:librpc: factor out xxx_dead() to dcerpc_transport_dead()
authorGregor Beck <gbeck@sernet.de>
Tue, 24 Sep 2013 10:32:50 +0000 (12:32 +0200)
committerStefan Metzmacher <metze@samba.org>
Tue, 7 Jan 2014 07:37:46 +0000 (08:37 +0100)
Signed-off-by: Gregor Beck <gbeck@sernet.de>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
source4/librpc/rpc/dcerpc.c
source4/librpc/rpc/dcerpc.h
source4/librpc/rpc/dcerpc_smb.c
source4/librpc/rpc/dcerpc_sock.c

index 95f608aeb5799d7c4a23c95041d367b66807ea9b..a2223851707773b03583f364fe59fa0d2adff05b 100644 (file)
@@ -2247,3 +2247,25 @@ _PUBLIC_ NTSTATUS dcerpc_alter_context(struct dcerpc_pipe *p,
        return dcerpc_alter_context_recv(subreq);
 }
 
+void dcerpc_transport_dead(struct dcecli_connection *c, NTSTATUS status)
+{
+       if (c->transport.stream == NULL) {
+               return;
+       }
+
+       tevent_queue_stop(c->transport.write_queue);
+       TALLOC_FREE(c->transport.read_subreq);
+       TALLOC_FREE(c->transport.stream);
+
+       if (NT_STATUS_EQUAL(NT_STATUS_UNSUCCESSFUL, status)) {
+               status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
+       }
+
+       if (NT_STATUS_EQUAL(NT_STATUS_OK, status)) {
+               status = NT_STATUS_END_OF_FILE;
+       }
+
+       if (c->transport.recv_data) {
+               c->transport.recv_data(c, NULL, status);
+       }
+}
index 2b2e8b78bb8f55bb8038eafb7e1951de86bddc97..61141c2b1b97ba52abf397f51b0bc20e76b66f26 100644 (file)
@@ -89,6 +89,14 @@ struct dcecli_connection {
                /* a callback to the dcerpc code when a full fragment
                   has been received */
                void (*recv_data)(struct dcecli_connection *, DATA_BLOB *, NTSTATUS status);
+
+               struct tstream_context *stream;
+               /** to serialize write events */
+               struct tevent_queue *write_queue;
+               /** the current active read request if any */
+               struct tevent_req *read_subreq;
+               /** number of read requests other than the current active */
+               uint32_t pending_reads;
        } transport;
 
        const char *server_name;
index b7bd98417b6025026396e0f35621b03aa3aa64f6..d55ce6fd837fff1307a934a314c133965005419f 100644 (file)
 struct smb_private {
        DATA_BLOB session_key;
 
-       struct tstream_context *stream;
-       struct tevent_queue *write_queue;
-       struct tevent_req *read_subreq;
-       uint32_t pending_reads;
-
        /*
         * these are needed to open a secondary connection
         */
@@ -53,33 +48,10 @@ struct smb_private {
 
 
 /*
-  tell the dcerpc layer that the transport is dead
+  Tell the dcerpc layer that the transport is dead.
+  This function is declared here because it is going to be private.
 */
-static void pipe_dead(struct dcecli_connection *c, NTSTATUS status)
-{
-       struct smb_private *smb = talloc_get_type_abort(
-               c->transport.private_data, struct smb_private);
-
-       if (smb->stream == NULL) {
-               return;
-       }
-
-       tevent_queue_stop(smb->write_queue);
-       TALLOC_FREE(smb->read_subreq);
-       TALLOC_FREE(smb->stream);
-
-       if (NT_STATUS_EQUAL(NT_STATUS_UNSUCCESSFUL, status)) {
-               status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
-       }
-
-       if (NT_STATUS_EQUAL(NT_STATUS_OK, status)) {
-               status = NT_STATUS_END_OF_FILE;
-       }
-
-       if (c->transport.recv_data) {
-               c->transport.recv_data(c, NULL, status);
-       }
-}
+void dcerpc_transport_dead(struct dcecli_connection *c, NTSTATUS status);
 
 struct smb_send_read_state {
        struct dcecli_connection *p;
@@ -88,10 +60,8 @@ struct smb_send_read_state {
 static int smb_send_read_state_destructor(struct smb_send_read_state *state)
 {
        struct dcecli_connection *p = state->p;
-       struct smb_private *sock = talloc_get_type_abort(
-               p->transport.private_data, struct smb_private);
 
-       sock->read_subreq = NULL;
+       p->transport.read_subreq = NULL;
 
        return 0;
 }
@@ -104,8 +74,8 @@ static NTSTATUS smb_send_read(struct dcecli_connection *p)
                p->transport.private_data, struct smb_private);
        struct smb_send_read_state *state;
 
-       if (sock->read_subreq != NULL) {
-               sock->pending_reads++;
+       if (p->transport.read_subreq != NULL) {
+               p->transport.pending_reads++;
                return NT_STATUS_OK;
        }
 
@@ -117,13 +87,13 @@ static NTSTATUS smb_send_read(struct dcecli_connection *p)
 
        talloc_set_destructor(state, smb_send_read_state_destructor);
 
-       sock->read_subreq = dcerpc_read_ncacn_packet_send(state,
+       p->transport.read_subreq = dcerpc_read_ncacn_packet_send(state,
                                                          p->event_ctx,
-                                                         sock->stream);
-       if (sock->read_subreq == NULL) {
+                                                         p->transport.stream);
+       if (p->transport.read_subreq == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
-       tevent_req_set_callback(sock->read_subreq, smb_send_read_done, state);
+       tevent_req_set_callback(p->transport.read_subreq, smb_send_read_done, state);
 
        return NT_STATUS_OK;
 }
@@ -134,8 +104,6 @@ static void smb_send_read_done(struct tevent_req *subreq)
                tevent_req_callback_data(subreq,
                                         struct smb_send_read_state);
        struct dcecli_connection *p = state->p;
-       struct smb_private *sock = talloc_get_type_abort(
-               p->transport.private_data, struct smb_private);
        NTSTATUS status;
        struct ncacn_packet *pkt;
        DATA_BLOB blob;
@@ -145,7 +113,7 @@ static void smb_send_read_done(struct tevent_req *subreq)
        TALLOC_FREE(subreq);
        if (!NT_STATUS_IS_OK(status)) {
                TALLOC_FREE(state);
-               pipe_dead(p, status);
+               dcerpc_transport_dead(p, status);
                return;
        }
 
@@ -156,12 +124,12 @@ static void smb_send_read_done(struct tevent_req *subreq)
        talloc_steal(p, blob.data);
        TALLOC_FREE(state);
 
-       if (sock->pending_reads > 0) {
-               sock->pending_reads--;
+       if (p->transport.pending_reads > 0) {
+               p->transport.pending_reads--;
 
                status = smb_send_read(p);
                if (!NT_STATUS_IS_OK(status)) {
-                       pipe_dead(p, status);
+                       dcerpc_transport_dead(p, status);
                        return;
                }
        }
@@ -183,11 +151,7 @@ struct smb_send_request_state {
 
 static int smb_send_request_state_destructor(struct smb_send_request_state *state)
 {
-       struct dcecli_connection *p = state->p;
-       struct smb_private *sock = talloc_get_type_abort(
-               p->transport.private_data, struct smb_private);
-
-       sock->read_subreq = NULL;
+       state->p->transport.read_subreq = NULL;
 
        return 0;
 }
@@ -204,7 +168,7 @@ static NTSTATUS smb_send_request(struct dcecli_connection *p, DATA_BLOB *data,
        struct tevent_req *subreq;
        bool use_trans = trigger_read;
 
-       if (sock->stream == NULL) {
+       if (p->transport.stream == NULL) {
                return NT_STATUS_CONNECTION_DISCONNECTED;
        }
 
@@ -222,7 +186,7 @@ static NTSTATUS smb_send_request(struct dcecli_connection *p, DATA_BLOB *data,
        state->iov.iov_base = (void *)state->blob.data;
        state->iov.iov_len = state->blob.length;
 
-       if (sock->read_subreq != NULL) {
+       if (p->transport.read_subreq != NULL) {
                use_trans = false;
        }
 
@@ -231,13 +195,13 @@ static NTSTATUS smb_send_request(struct dcecli_connection *p, DATA_BLOB *data,
                 * we need to block reads until our write is
                 * the next in the write queue.
                 */
-               sock->read_subreq = tevent_queue_wait_send(state, p->event_ctx,
-                                                          sock->write_queue);
-               if (sock->read_subreq == NULL) {
+               p->transport.read_subreq = tevent_queue_wait_send(state, p->event_ctx,
+                                                       p->transport.write_queue);
+               if (p->transport.read_subreq == NULL) {
                        TALLOC_FREE(state);
                        return NT_STATUS_NO_MEMORY;
                }
-               tevent_req_set_callback(sock->read_subreq,
+               tevent_req_set_callback(p->transport.read_subreq,
                                        smb_send_request_wait_done,
                                        state);
 
@@ -247,8 +211,8 @@ static NTSTATUS smb_send_request(struct dcecli_connection *p, DATA_BLOB *data,
        }
 
        subreq = tstream_writev_queue_send(state, p->event_ctx,
-                                          sock->stream,
-                                          sock->write_queue,
+                                          p->transport.stream,
+                                          p->transport.write_queue,
                                           &state->iov, 1);
        if (subreq == NULL) {
                TALLOC_FREE(state);
@@ -269,26 +233,24 @@ static void smb_send_request_wait_done(struct tevent_req *subreq)
                tevent_req_callback_data(subreq,
                struct smb_send_request_state);
        struct dcecli_connection *p = state->p;
-       struct smb_private *sock = talloc_get_type_abort(
-               p->transport.private_data, struct smb_private);
        NTSTATUS status;
        bool ok;
 
-       sock->read_subreq = NULL;
+       p->transport.read_subreq = NULL;
        talloc_set_destructor(state, NULL);
 
        ok = tevent_queue_wait_recv(subreq);
        if (!ok) {
                TALLOC_FREE(state);
-               pipe_dead(p, NT_STATUS_NO_MEMORY);
+               dcerpc_transport_dead(p, NT_STATUS_NO_MEMORY);
                return;
        }
 
-       if (tevent_queue_length(sock->write_queue) <= 2) {
-               status = tstream_smbXcli_np_use_trans(sock->stream);
+       if (tevent_queue_length(p->transport.write_queue) <= 2) {
+               status = tstream_smbXcli_np_use_trans(p->transport.stream);
                if (!NT_STATUS_IS_OK(status)) {
                        TALLOC_FREE(state);
-                       pipe_dead(p, status);
+                       dcerpc_transport_dead(p, status);
                        return;
                }
        }
@@ -314,7 +276,7 @@ static void smb_send_request_done(struct tevent_req *subreq)
                NTSTATUS status = map_nt_error_from_unix_common(error);
 
                TALLOC_FREE(state);
-               pipe_dead(p, status);
+               dcerpc_transport_dead(p, status);
                return;
        }
 
@@ -338,7 +300,7 @@ static NTSTATUS smb_shutdown_pipe(struct dcecli_connection *c, NTSTATUS status)
        struct smb_shutdown_pipe_state *state;
        struct tevent_req *subreq;
 
-       if (smb->stream == NULL) {
+       if (c->transport.stream == NULL) {
                return NT_STATUS_OK;
        }
 
@@ -349,7 +311,7 @@ static NTSTATUS smb_shutdown_pipe(struct dcecli_connection *c, NTSTATUS status)
        state->c = c;
        state->status = status;
 
-       subreq = tstream_disconnect_send(state, c->event_ctx, smb->stream);
+       subreq = tstream_disconnect_send(state, c->event_ctx, c->transport.stream);
        if (subreq == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -374,7 +336,7 @@ static void smb_shutdown_pipe_done(struct tevent_req *subreq)
 
        TALLOC_FREE(state);
 
-       pipe_dead(c, status);
+       dcerpc_transport_dead(c, status);
 }
 
 /*
@@ -479,13 +441,13 @@ static void dcerpc_pipe_open_smb_done(struct tevent_req *subreq)
 
        ctx->status = tstream_smbXcli_np_open_recv(subreq,
                                                   state->smb,
-                                                  &state->smb->stream);
+                                                  &state->c->transport.stream);
        TALLOC_FREE(subreq);
        if (!composite_is_ok(ctx)) return;
 
-       state->smb->write_queue = tevent_queue_create(state->smb,
-                                       "dcerpc_smb write queue");
-       if (composite_nomem(state->smb->write_queue, ctx)) return;
+       state->c->transport.write_queue =
+               tevent_queue_create(state->c, "dcerpc_smb write queue");
+       if (composite_nomem(state->c->transport.write_queue, ctx)) return;
 
        /*
          fill in the transport methods
index 9f82cf26f434c420beaec337d4be291c8ba8b919..ad7771ea8df4ffadadf7bce23dbe7d5858ec3207 100644 (file)
@@ -37,40 +37,14 @@ struct sock_private {
        const char *path; /* For ncacn_unix_sock and ncalrpc */
 
        struct socket_address *peer_addr;
-
-       struct tstream_context *stream;
-       struct tevent_queue *write_queue;
-       struct tevent_req *read_subreq;
-       uint32_t pending_reads;
 };
 
 
 /*
-  mark the socket dead
+  Mark the socket dead.
+  This function is declared here because it is going to be private.
 */
-static void sock_dead(struct dcecli_connection *p, NTSTATUS status)
-{
-       struct sock_private *sock = talloc_get_type_abort(
-               p->transport.private_data, struct sock_private);
-
-       if (!sock) return;
-
-       tevent_queue_stop(sock->write_queue);
-       TALLOC_FREE(sock->read_subreq);
-       TALLOC_FREE(sock->stream);
-
-       if (NT_STATUS_EQUAL(NT_STATUS_UNSUCCESSFUL, status)) {
-               status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
-       }
-
-       if (NT_STATUS_EQUAL(NT_STATUS_OK, status)) {
-               status = NT_STATUS_END_OF_FILE;
-       }
-
-       if (p->transport.recv_data) {
-               p->transport.recv_data(p, NULL, status);
-       }
-}
+void dcerpc_transport_dead(struct dcecli_connection *p, NTSTATUS status);
 
 /*
    initiate a read request - not needed for dcerpc sockets
@@ -82,10 +56,8 @@ struct sock_send_read_state {
 static int sock_send_read_state_destructor(struct sock_send_read_state *state)
 {
        struct dcecli_connection *p = state->p;
-       struct sock_private *sock = talloc_get_type_abort(
-               p->transport.private_data, struct sock_private);
 
-       sock->read_subreq = NULL;
+       p->transport.read_subreq = NULL;
 
        return 0;
 }
@@ -98,8 +70,8 @@ static NTSTATUS sock_send_read(struct dcecli_connection *p)
                p->transport.private_data, struct sock_private);
        struct sock_send_read_state *state;
 
-       if (sock->read_subreq != NULL) {
-               sock->pending_reads++;
+       if (p->transport.read_subreq != NULL) {
+               p->transport.pending_reads++;
                return NT_STATUS_OK;
        }
 
@@ -111,13 +83,13 @@ static NTSTATUS sock_send_read(struct dcecli_connection *p)
 
        talloc_set_destructor(state, sock_send_read_state_destructor);
 
-       sock->read_subreq = dcerpc_read_ncacn_packet_send(state,
+       p->transport.read_subreq = dcerpc_read_ncacn_packet_send(state,
                                                          p->event_ctx,
-                                                         sock->stream);
-       if (sock->read_subreq == NULL) {
+                                                         p->transport.stream);
+       if (p->transport.read_subreq == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
-       tevent_req_set_callback(sock->read_subreq, sock_send_read_done, state);
+       tevent_req_set_callback(p->transport.read_subreq, sock_send_read_done, state);
 
        return NT_STATUS_OK;
 }
@@ -128,8 +100,6 @@ static void sock_send_read_done(struct tevent_req *subreq)
                tevent_req_callback_data(subreq,
                                         struct sock_send_read_state);
        struct dcecli_connection *p = state->p;
-       struct sock_private *sock = talloc_get_type_abort(
-               p->transport.private_data, struct sock_private);
        NTSTATUS status;
        struct ncacn_packet *pkt;
        DATA_BLOB blob;
@@ -139,7 +109,7 @@ static void sock_send_read_done(struct tevent_req *subreq)
        TALLOC_FREE(subreq);
        if (!NT_STATUS_IS_OK(status)) {
                TALLOC_FREE(state);
-               sock_dead(p, status);
+               dcerpc_transport_dead(p, status);
                return;
        }
 
@@ -150,12 +120,12 @@ static void sock_send_read_done(struct tevent_req *subreq)
        talloc_steal(p, blob.data);
        TALLOC_FREE(state);
 
-       if (sock->pending_reads > 0) {
-               sock->pending_reads--;
+       if (p->transport.pending_reads > 0) {
+               p->transport.pending_reads--;
 
                status = sock_send_read(p);
                if (!NT_STATUS_IS_OK(status)) {
-                       sock_dead(p, status);
+                       dcerpc_transport_dead(p, status);
                        return;
                }
        }
@@ -185,7 +155,7 @@ static NTSTATUS sock_send_request(struct dcecli_connection *p, DATA_BLOB *data,
        struct sock_send_request_state *state;
        struct tevent_req *subreq;
 
-       if (sock->stream == NULL) {
+       if (p->transport.stream == NULL) {
                return NT_STATUS_CONNECTION_DISCONNECTED;
        }
 
@@ -204,8 +174,8 @@ static NTSTATUS sock_send_request(struct dcecli_connection *p, DATA_BLOB *data,
        state->iov.iov_len = state->blob.length;
 
        subreq = tstream_writev_queue_send(state, p->event_ctx,
-                                          sock->stream,
-                                          sock->write_queue,
+                                          p->transport.stream,
+                                          p->transport.write_queue,
                                           &state->iov, 1);
        if (subreq == NULL) {
                TALLOC_FREE(state);
@@ -235,7 +205,7 @@ static void sock_send_request_done(struct tevent_req *subreq)
                NTSTATUS status = map_nt_error_from_unix_common(error);
 
                TALLOC_FREE(state);
-               sock_dead(p, status);
+               dcerpc_transport_dead(p, status);
                return;
        }
 
@@ -247,13 +217,12 @@ static void sock_send_request_done(struct tevent_req *subreq)
 */
 static NTSTATUS sock_shutdown_pipe(struct dcecli_connection *p, NTSTATUS status)
 {
-       struct sock_private *sock = talloc_get_type_abort(
-               p->transport.private_data, struct sock_private);
-
-       if (sock && sock->stream) {
-               sock_dead(p, status);
+       if (p->transport.stream == NULL) {
+               return NT_STATUS_OK;
        }
 
+       dcerpc_transport_dead(p, status);
+
        return status;
 }
 
@@ -321,22 +290,22 @@ static void continue_socket_connect(struct composite_context *ctx)
        conn->srv_max_xmit_frag = 5840;
        conn->srv_max_recv_frag = 5840;
 
-       sock->pending_reads = 0;
+       conn->transport.pending_reads = 0;
        conn->server_name   = strupper_talloc(conn, s->target_hostname);
 
        conn->transport.private_data = sock;
 
        rc = tstream_bsd_existing_socket(sock, sock_fd,
-                                        &sock->stream);
+                                        &conn->transport.stream);
        if (rc < 0) {
                talloc_free(sock);
                composite_error(c, NT_STATUS_NO_MEMORY);
                return;
        }
 
-       sock->write_queue = tevent_queue_create(sock,
-                                               "dcerpc sock write queue");
-       if (sock->write_queue == NULL) {
+       conn->transport.write_queue =
+               tevent_queue_create(conn, "dcerpc sock write queue");
+       if (conn->transport.write_queue == NULL) {
                talloc_free(sock);
                composite_error(c, NT_STATUS_NO_MEMORY);
                return;