diff options
| author | Gregor Beck <gbeck@sernet.de> | 2013-09-24 12:32:50 +0200 |
|---|---|---|
| committer | Stefan Metzmacher <metze@samba.org> | 2014-01-07 08:37:46 +0100 |
| commit | 30ca477c7153999b2bbac87cdbd928bc57ecce51 (patch) | |
| tree | ee70cc84b2ae227875f446820e2c2d9d424a451b /source4 | |
| parent | 3193c27256b921a9ac3963fe4b66bc42faae941d (diff) | |
s4:librpc: factor out xxx_dead() to dcerpc_transport_dead()
Signed-off-by: Gregor Beck <gbeck@sernet.de>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
Diffstat (limited to 'source4')
| -rw-r--r-- | source4/librpc/rpc/dcerpc.c | 22 | ||||
| -rw-r--r-- | source4/librpc/rpc/dcerpc.h | 8 | ||||
| -rw-r--r-- | source4/librpc/rpc/dcerpc_smb.c | 110 | ||||
| -rw-r--r-- | source4/librpc/rpc/dcerpc_sock.c | 85 |
4 files changed, 93 insertions, 132 deletions
diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index 95f608aeb5..a222385170 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -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); + } +} diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h index 2b2e8b78bb..61141c2b1b 100644 --- a/source4/librpc/rpc/dcerpc.h +++ b/source4/librpc/rpc/dcerpc.h @@ -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; diff --git a/source4/librpc/rpc/dcerpc_smb.c b/source4/librpc/rpc/dcerpc_smb.c index b7bd98417b..d55ce6fd83 100644 --- a/source4/librpc/rpc/dcerpc_smb.c +++ b/source4/librpc/rpc/dcerpc_smb.c @@ -37,11 +37,6 @@ 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 diff --git a/source4/librpc/rpc/dcerpc_sock.c b/source4/librpc/rpc/dcerpc_sock.c index 9f82cf26f4..ad7771ea8d 100644 --- a/source4/librpc/rpc/dcerpc_sock.c +++ b/source4/librpc/rpc/dcerpc_sock.c @@ -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; |
