[SCM] Samba Shared Repository - branch master updated -
c45b6ec29a5b3a39b83209e970b645e5ed0a411c
Volker Lendecke
vlendec at samba.org
Sun Jan 18 14:41:54 GMT 2009
The branch, master has been updated
via c45b6ec29a5b3a39b83209e970b645e5ed0a411c (commit)
via a158ebbe49d431259f002ae8272c39e5792adf4f (commit)
via 28c35b4c0456ce62bf1a492ad9c1b223e2f31816 (commit)
via ecb5184ce57259c709d728ed5f7be1bdf666bbcc (commit)
via 3f9f188877de8a4c0b2883e2360f2834c41b66c1 (commit)
via 396ed3b36359367e1efd49395cd9e6dc6f7c98fc (commit)
via 8a1c6c2c994b2eac05e8cbc3c692d7367b687d32 (commit)
via c655f19e1fa3a1443fd16927d37035a4f4cf46aa (commit)
via f96335afc0602e5874e11c505a4087e32873060e (commit)
via f6740aa7ad1b553410ffbc9fb54916d6a385a753 (commit)
via 761d164420dc4d16e8a0a937146e359130979df9 (commit)
via 5e6f3eaae9435b1ab7b36726e7b898d4994fcebf (commit)
via 5987c8269779ca2a7207c37a94b0e841a380d7d1 (commit)
via 6d47418bc1f3de56e8ed78f2e908eb634230fee9 (commit)
via 173d6c84a68691f8bc00749509b8e3665bc159ee (commit)
via 5d71fe8043799abf098131fd924c35b49111bf54 (commit)
via 30413f12b97149cde7aacfc8e7f2d9b63fa9da5c (commit)
from 8b618d0ba997a9b2254ae2ea530a80dd14631d59 (commit)
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit c45b6ec29a5b3a39b83209e970b645e5ed0a411c
Author: Volker Lendecke <vl at samba.org>
Date: Sun Jan 18 12:22:14 2009 +0100
Add code to torture the fragmentation code a bit
commit a158ebbe49d431259f002ae8272c39e5792adf4f
Author: Volker Lendecke <vl at samba.org>
Date: Sun Jan 18 12:15:33 2009 +0100
Remove unused functions
commit 28c35b4c0456ce62bf1a492ad9c1b223e2f31816
Author: Volker Lendecke <vl at samba.org>
Date: Sun Jan 18 12:12:15 2009 +0100
Make rpc_pipe_bind async
commit ecb5184ce57259c709d728ed5f7be1bdf666bbcc
Author: Volker Lendecke <vl at samba.org>
Date: Sat Jan 17 19:19:04 2009 +0100
Fix an uninitialized variable
commit 3f9f188877de8a4c0b2883e2360f2834c41b66c1
Author: Volker Lendecke <vl at samba.org>
Date: Sat Jan 17 17:53:05 2009 +0100
Remove sync rpc_api_pipe_req
commit 396ed3b36359367e1efd49395cd9e6dc6f7c98fc
Author: Volker Lendecke <vl at samba.org>
Date: Sat Jan 17 17:52:35 2009 +0100
Add async rpc_api_pipe_req
commit 8a1c6c2c994b2eac05e8cbc3c692d7367b687d32
Author: Volker Lendecke <vl at samba.org>
Date: Sat Jan 17 17:52:22 2009 +0100
Tiny simplification of prs_set_offset
commit c655f19e1fa3a1443fd16927d37035a4f4cf46aa
Author: Volker Lendecke <vl at samba.org>
Date: Sat Jan 17 15:07:52 2009 +0100
Add rpc_write_send/recv
commit f96335afc0602e5874e11c505a4087e32873060e
Author: Volker Lendecke <vl at samba.org>
Date: Sat Jan 17 13:58:36 2009 +0100
Remove unused sync functions
commit f6740aa7ad1b553410ffbc9fb54916d6a385a753
Author: Volker Lendecke <vl at samba.org>
Date: Sat Jan 17 13:33:34 2009 +0100
Make rpc_api_pipe async
commit 761d164420dc4d16e8a0a937146e359130979df9
Author: Volker Lendecke <vl at samba.org>
Date: Sat Jan 17 12:50:02 2009 +0100
Rename the async version of get_complete_pdu to get_complete_frag
commit 5e6f3eaae9435b1ab7b36726e7b898d4994fcebf
Author: Volker Lendecke <vl at samba.org>
Date: Sat Jan 17 12:18:29 2009 +0100
Move initialization of the reply prs_struct to rpc_api_pipe
commit 5987c8269779ca2a7207c37a94b0e841a380d7d1
Author: Volker Lendecke <vl at samba.org>
Date: Fri Jan 16 17:31:56 2009 +0100
Always check the max send sizein rpc_api_pipe, not just with DEVELOPER
commit 6d47418bc1f3de56e8ed78f2e908eb634230fee9
Author: Volker Lendecke <vl at samba.org>
Date: Fri Jan 16 17:07:52 2009 +0100
Make cli_api_pipe async
Also move the transport switch to this routine
commit 173d6c84a68691f8bc00749509b8e3665bc159ee
Author: Volker Lendecke <vl at samba.org>
Date: Fri Jan 16 14:47:21 2009 +0100
Remove sync rpc_read wrapper
commit 5d71fe8043799abf098131fd924c35b49111bf54
Author: Volker Lendecke <vl at samba.org>
Date: Fri Jan 16 14:46:41 2009 +0100
Make cli_pipe_get_current_pdu async, rename it to get_current_pdu
commit 30413f12b97149cde7aacfc8e7f2d9b63fa9da5c
Author: Volker Lendecke <vl at samba.org>
Date: Thu Jan 15 21:56:03 2009 +0100
Make rpc_read async
-----------------------------------------------------------------------
Summary of changes:
source3/include/proto.h | 14 +-
source3/include/rpc_client.h | 3 +-
source3/librpc/rpc/dcerpc.c | 3 +-
source3/rpc_client/cli_pipe.c | 2156 +++++++++++++++++++++++++++--------------
source3/rpc_client/ndr.c | 4 +-
source3/rpc_parse/parse_prs.c | 9 +-
6 files changed, 1459 insertions(+), 730 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source3/include/proto.h b/source3/include/proto.h
index d644b09..71ad259 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -5197,10 +5197,22 @@ NTSTATUS rpccli_netlogon_set_trust_password(struct rpc_pipe_client *cli,
/* The following definitions come from rpc_client/cli_pipe.c */
-NTSTATUS rpc_api_pipe_req(struct rpc_pipe_client *cli,
+struct async_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct rpc_pipe_client *cli,
+ uint8_t op_num,
+ prs_struct *req_data);
+NTSTATUS rpc_api_pipe_req_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
+ prs_struct *reply_pdu);
+NTSTATUS rpc_api_pipe_req(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli,
uint8 op_num,
prs_struct *in_data,
prs_struct *out_data);
+struct async_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct rpc_pipe_client *cli,
+ struct cli_pipe_auth_data *auth);
+NTSTATUS rpc_pipe_bind_recv(struct async_req *req);
NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
struct cli_pipe_auth_data *auth);
unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli,
diff --git a/source3/include/rpc_client.h b/source3/include/rpc_client.h
index 684044b..61b861c 100644
--- a/source3/include/rpc_client.h
+++ b/source3/include/rpc_client.h
@@ -49,9 +49,8 @@
if (!prs_init( &q_ps, RPC_MAX_PDU_FRAG_LEN, ctx, MARSHALL )) { \
return WERR_NOMEM;\
}\
- prs_init_empty( &r_ps, ctx, UNMARSHALL );\
if ( q_io_fn("", &q_in, &q_ps, 0) ) {\
- NTSTATUS _smb_pipe_stat_ = rpc_api_pipe_req(pcli, opnum, &q_ps, &r_ps); \
+ NTSTATUS _smb_pipe_stat_ = rpc_api_pipe_req(ctx, pcli, opnum, &q_ps, &r_ps); \
if (!NT_STATUS_IS_OK(_smb_pipe_stat_)) {\
prs_mem_free( &q_ps );\
prs_mem_free( &r_ps );\
diff --git a/source3/librpc/rpc/dcerpc.c b/source3/librpc/rpc/dcerpc.c
index 69bfc6f..21a2004 100644
--- a/source3/librpc/rpc/dcerpc.c
+++ b/source3/librpc/rpc/dcerpc.c
@@ -84,7 +84,8 @@ NTSTATUS dcerpc_ndr_request_recv(struct rpc_request *req)
prs_init_empty( &r_ps, req, UNMARSHALL );
- status = rpc_api_pipe_req(req->pipe->rpc_cli, req->opnum, &req->q_ps, &r_ps);
+ status = rpc_api_pipe_req(req, req->pipe->rpc_cli, req->opnum,
+ &req->q_ps, &r_ps);
prs_mem_free( &req->q_ps );
diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
index 28bbfa5..f3affd1 100644
--- a/source3/rpc_client/cli_pipe.c
+++ b/source3/rpc_client/cli_pipe.c
@@ -172,57 +172,6 @@ static uint32 get_rpc_call_id(void)
return ++call_id;
}
-/*******************************************************************
- Read from a RPC named pipe
- ********************************************************************/
-static NTSTATUS rpc_read_np(struct cli_state *cli, const char *pipe_name,
- int fnum, char *buf, size_t size,
- ssize_t *pnum_read)
-{
- ssize_t num_read;
-
- num_read = cli_read(cli, fnum, buf, 0, size);
-
- DEBUG(5,("rpc_read_np: num_read = %d, to read: %u\n", (int)num_read,
- (unsigned int)size));
-
- /*
- * A dos error of ERRDOS/ERRmoredata is not an error.
- */
- if (cli_is_dos_error(cli)) {
- uint32 ecode;
- uint8 eclass;
- cli_dos_error(cli, &eclass, &ecode);
- if (eclass != ERRDOS && ecode != ERRmoredata) {
- DEBUG(0,("rpc_read: DOS Error %d/%u (%s) in cli_read "
- "on fnum 0x%x\n", eclass, (unsigned int)ecode,
- cli_errstr(cli), fnum));
- return dos_to_ntstatus(eclass, ecode);
- }
- }
-
- /*
- * Likewise for NT_STATUS_BUFFER_TOO_SMALL
- */
- if (cli_is_nt_error(cli)) {
- if (!NT_STATUS_EQUAL(cli_nt_error(cli),
- NT_STATUS_BUFFER_TOO_SMALL)) {
- DEBUG(0,("rpc_read: Error (%s) in cli_read on fnum "
- "0x%x\n", nt_errstr(cli_nt_error(cli)), fnum));
- return cli_nt_error(cli);
- }
- }
-
- if (num_read == -1) {
- DEBUG(0,("rpc_read: Error - cli_read on fnum 0x%x returned "
- "-1\n", fnum));
- return cli_get_nt_error(cli);
- }
-
- *pnum_read = num_read;
- return NT_STATUS_OK;
-}
-
/*
* Realloc pdu to have a least "size" bytes
*/
@@ -254,83 +203,287 @@ static bool rpc_grow_buffer(prs_struct *pdu, size_t size)
Reads the whole size or give an error message
********************************************************************/
-static NTSTATUS rpc_read(struct rpc_pipe_client *cli,
- char *pdata, size_t size)
+struct rpc_read_state {
+ struct event_context *ev;
+ struct rpc_pipe_client *cli;
+ char *data;
+ size_t size;
+ size_t num_read;
+};
+
+static void rpc_read_np_done(struct async_req *subreq);
+static void rpc_read_sock_done(struct async_req *subreq);
+
+static struct async_req *rpc_read_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct rpc_pipe_client *cli,
+ char *data, size_t size)
{
- ssize_t num_read = 0;
+ struct async_req *result, *subreq;
+ struct rpc_read_state *state;
- DEBUG(5, ("rpc_read: data_to_read: %u\n", (unsigned int)size));
+ result = async_req_new(mem_ctx);
+ if (result == NULL) {
+ return NULL;
+ }
+ state = talloc(result, struct rpc_read_state);
+ if (state == NULL) {
+ goto fail;
+ }
+ result->private_data = state;
- while (num_read < size) {
- ssize_t thistime = 0;
- NTSTATUS status;
+ state->ev = ev;
+ state->cli = cli;
+ state->data = data;
+ state->size = size;
+ state->num_read = 0;
- switch (cli->transport_type) {
- case NCACN_NP:
- status = rpc_read_np(cli->trans.np.cli,
- cli->trans.np.pipe_name,
- cli->trans.np.fnum,
- pdata + num_read,
- size - num_read, &thistime);
- break;
- case NCACN_IP_TCP:
- case NCACN_UNIX_STREAM:
- status = NT_STATUS_OK;
- thistime = sys_read(cli->trans.sock.fd,
- pdata + num_read,
- size - num_read);
- if (thistime == -1) {
- status = map_nt_error_from_unix(errno);
- }
- break;
- default:
- DEBUG(0, ("unknown transport type %d\n",
- cli->transport_type));
- return NT_STATUS_INTERNAL_ERROR;
- }
+ DEBUG(5, ("rpc_read_send: data_to_read: %u\n", (unsigned int)size));
- if (!NT_STATUS_IS_OK(status)) {
- return status;
+ if (cli->transport_type == NCACN_NP) {
+ subreq = cli_read_andx_send(
+ state, ev, cli->trans.np.cli,
+ cli->trans.np.fnum, 0, size);
+ if (subreq == NULL) {
+ DEBUG(10, ("cli_read_andx_send failed\n"));
+ goto fail;
}
- if (thistime == 0) {
- return NT_STATUS_END_OF_FILE;
+ subreq->async.fn = rpc_read_np_done;
+ subreq->async.priv = result;
+ return result;
+ }
+
+ if ((cli->transport_type == NCACN_IP_TCP)
+ || (cli->transport_type == NCACN_UNIX_STREAM)) {
+ subreq = recvall_send(state, ev, cli->trans.sock.fd,
+ data, size, 0);
+ if (subreq == NULL) {
+ DEBUG(10, ("recvall_send failed\n"));
+ goto fail;
}
+ subreq->async.fn = rpc_read_sock_done;
+ subreq->async.priv = result;
+ return result;
+ }
+
+ if (async_post_status(result, ev, NT_STATUS_INVALID_PARAMETER)) {
+ return result;
+ }
+ fail:
+ TALLOC_FREE(result);
+ return NULL;
+}
+
+static void rpc_read_np_done(struct async_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.priv, struct async_req);
+ struct rpc_read_state *state = talloc_get_type_abort(
+ req->private_data, struct rpc_read_state);
+ NTSTATUS status;
+ ssize_t received;
+ uint8_t *rcvbuf;
+
+ status = cli_read_andx_recv(subreq, &received, &rcvbuf);
+ /*
+ * We can't TALLOC_FREE(subreq) as usual here, as rcvbuf still is a
+ * child of that.
+ */
+ if (NT_STATUS_EQUAL(status, NT_STATUS_BUFFER_TOO_SMALL)) {
+ status = NT_STATUS_OK;
+ }
+ if (!NT_STATUS_IS_OK(status)) {
+ TALLOC_FREE(subreq);
+ async_req_error(req, status);
+ return;
+ }
+
+ memcpy(state->data + state->num_read, rcvbuf, received);
+ TALLOC_FREE(subreq);
- num_read += thistime;
+ state->num_read += received;
+ if (state->num_read == state->size) {
+ async_req_done(req);
+ return;
}
- return NT_STATUS_OK;
+ subreq = cli_read_andx_send(
+ state, state->ev, state->cli->trans.np.cli,
+ state->cli->trans.np.fnum, 0,
+ state->size - state->num_read);
+
+ if (async_req_nomem(subreq, req)) {
+ return;
+ }
+
+ subreq->async.fn = rpc_read_np_done;
+ subreq->async.priv = req;
}
-/****************************************************************************
- Try and get a PDU's worth of data from current_pdu. If not, then read more
- from the wire.
- ****************************************************************************/
+static void rpc_read_sock_done(struct async_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.priv, struct async_req);
+ NTSTATUS status;
+
+ status = recvall_recv(subreq);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ async_req_error(req, status);
+ return;
+ }
+
+ async_req_done(req);
+}
-static NTSTATUS cli_pipe_get_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *prhdr, prs_struct *current_pdu)
+static NTSTATUS rpc_read_recv(struct async_req *req)
{
- NTSTATUS ret = NT_STATUS_OK;
- uint32 current_pdu_len = prs_data_size(current_pdu);
+ return async_req_simple_recv(req);
+}
- /* Ensure we have at least RPC_HEADER_LEN worth of data to parse. */
- if (current_pdu_len < RPC_HEADER_LEN) {
- if (!rpc_grow_buffer(current_pdu, RPC_HEADER_LEN)) {
- return NT_STATUS_NO_MEMORY;
+struct rpc_write_state {
+ struct event_context *ev;
+ struct rpc_pipe_client *cli;
+ const char *data;
+ size_t size;
+ size_t num_written;
+};
+
+static void rpc_write_np_done(struct async_req *subreq);
+static void rpc_write_sock_done(struct async_req *subreq);
+
+static struct async_req *rpc_write_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct rpc_pipe_client *cli,
+ const char *data, size_t size)
+{
+ struct async_req *result, *subreq;
+ struct rpc_write_state *state;
+
+ result = async_req_new(mem_ctx);
+ if (result == NULL) {
+ return NULL;
+ }
+ state = talloc(result, struct rpc_write_state);
+ if (state == NULL) {
+ goto fail;
+ }
+ result->private_data = state;
+
+ state->ev = ev;
+ state->cli = cli;
+ state->data = data;
+ state->size = size;
+ state->num_written = 0;
+
+ DEBUG(5, ("rpc_write_send: data_to_write: %u\n", (unsigned int)size));
+
+ if (cli->transport_type == NCACN_NP) {
+ subreq = cli_write_andx_send(
+ state, ev, cli->trans.np.cli,
+ cli->trans.np.fnum, 8, /* 8 means message mode. */
+ (uint8_t *)data, 0, size);
+ if (subreq == NULL) {
+ DEBUG(10, ("cli_write_andx_send failed\n"));
+ goto fail;
}
- ret = rpc_read(cli,
- prs_data_p(current_pdu) + current_pdu_len,
- RPC_HEADER_LEN - current_pdu_len);
- if (!NT_STATUS_IS_OK(ret)) {
- return ret;
+ subreq->async.fn = rpc_write_np_done;
+ subreq->async.priv = result;
+ return result;
+ }
+
+ if ((cli->transport_type == NCACN_IP_TCP)
+ || (cli->transport_type == NCACN_UNIX_STREAM)) {
+ subreq = sendall_send(state, ev, cli->trans.sock.fd,
+ data, size, 0);
+ if (subreq == NULL) {
+ DEBUG(10, ("sendall_send failed\n"));
+ goto fail;
}
- current_pdu_len = RPC_HEADER_LEN;
+ subreq->async.fn = rpc_write_sock_done;
+ subreq->async.priv = result;
+ return result;
+ }
+
+ if (async_post_status(result, ev, NT_STATUS_INVALID_PARAMETER)) {
+ return result;
+ }
+ fail:
+ TALLOC_FREE(result);
+ return NULL;
+}
+
+static void rpc_write_np_done(struct async_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.priv, struct async_req);
+ struct rpc_write_state *state = talloc_get_type_abort(
+ req->private_data, struct rpc_write_state);
+ NTSTATUS status;
+ size_t written;
+
+ status = cli_write_andx_recv(subreq, &written);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ async_req_error(req, status);
+ return;
+ }
+
+ state->num_written += written;
+
+ if (state->num_written == state->size) {
+ async_req_done(req);
+ return;
+ }
+
+ subreq = cli_write_andx_send(
+ state, state->ev, state->cli->trans.np.cli,
+ state->cli->trans.np.fnum, 8,
+ (uint8_t *)(state->data + state->num_written),
+ 0, state->size - state->num_written);
+
+ if (async_req_nomem(subreq, req)) {
+ return;
+ }
+
+ subreq->async.fn = rpc_write_np_done;
+ subreq->async.priv = req;
+}
+
+static void rpc_write_sock_done(struct async_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.priv, struct async_req);
+ NTSTATUS status;
+
+ status = sendall_recv(subreq);
+ TALLOC_FREE(subreq);
+ if (!NT_STATUS_IS_OK(status)) {
+ async_req_error(req, status);
+ return;
}
- /* This next call sets the endian bit correctly in current_pdu. */
- /* We will propagate this to rbuf later. */
- if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, current_pdu, 0)) {
- DEBUG(0,("cli_pipe_get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
+ async_req_done(req);
+}
+
+static NTSTATUS rpc_write_recv(struct async_req *req)
+{
+ return async_req_simple_recv(req);
+}
+
+
+static NTSTATUS parse_rpc_header(struct rpc_pipe_client *cli,
+ struct rpc_hdr_info *prhdr,
+ prs_struct *pdu)
+{
+ /*
+ * This next call sets the endian bit correctly in current_pdu. We
+ * will propagate this to rbuf later.
+ */
+
+ if(!smb_io_rpc_hdr("rpc_hdr ", prhdr, pdu, 0)) {
+ DEBUG(0, ("get_current_pdu: Failed to unmarshall RPC_HDR.\n"));
return NT_STATUS_BUFFER_TOO_SMALL;
}
@@ -341,20 +494,162 @@ static NTSTATUS cli_pipe_get_current_pdu(struct rpc_pipe_client *cli, RPC_HDR *p
return NT_STATUS_BUFFER_TOO_SMALL;
}
- /* Ensure we have frag_len bytes of data. */
- if (current_pdu_len < prhdr->frag_len) {
- if (!rpc_grow_buffer(current_pdu, prhdr->frag_len)) {
- return NT_STATUS_NO_MEMORY;
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ Try and get a PDU's worth of data from current_pdu. If not, then read more
+ from the wire.
+ ****************************************************************************/
+
+struct get_complete_frag_state {
+ struct event_context *ev;
+ struct rpc_pipe_client *cli;
+ struct rpc_hdr_info *prhdr;
+ prs_struct *pdu;
+};
+
+static void get_complete_frag_got_header(struct async_req *subreq);
+static void get_complete_frag_got_rest(struct async_req *subreq);
+
+static struct async_req *get_complete_frag_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ struct rpc_pipe_client *cli,
+ struct rpc_hdr_info *prhdr,
+ prs_struct *pdu)
+{
+ struct async_req *result, *subreq;
+ struct get_complete_frag_state *state;
+ uint32_t pdu_len;
+ NTSTATUS status;
--
Samba Shared Repository
More information about the samba-cvs
mailing list