diff options
author | Andrew Tridgell <tridge@samba.org> | 2004-01-20 04:32:17 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2004-01-20 04:32:17 +0000 |
commit | 4d39861f991254aa381b8823476825e26a4d6da3 (patch) | |
tree | 75d838f3daf7932ecc83fc5370ffd5bd09ba51b9 | |
parent | 1e1428605b01de36299c0832bce9bf9d29de0b66 (diff) | |
download | samba-4d39861f991254aa381b8823476825e26a4d6da3.tar.gz samba-4d39861f991254aa381b8823476825e26a4d6da3.tar.bz2 samba-4d39861f991254aa381b8823476825e26a4d6da3.zip |
avoid a copy of the data being input to the dcerpc server in the most
common case of there being no pending partial data and a full dcerpc
packet being received.
We should use this same model for the smb server. It gives us
efficient memory usage while allowing for completely async socket
operations.
(This used to be commit 9aab321fb6e2f3499efd8ca5bc88ce2cb8e68219)
-rw-r--r-- | source4/rpc_server/dcerpc_server.c | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 46341e6db1..a4f5fb9768 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -689,15 +689,14 @@ static void dce_partial_advance(struct dcesrv_connection *dce_conn, uint32 offse DATA_BLOB blob; if (dce_conn->partial_input.length == offset) { - free(dce_conn->partial_input.data); - dce_conn->partial_input = data_blob(NULL, 0); + data_blob_free(&dce_conn->partial_input); return; } blob = dce_conn->partial_input; dce_conn->partial_input = data_blob(blob.data + offset, - blob.length - offset); - free(blob.data); + blob.length - offset); + data_blob_free(&blob); } /* @@ -840,6 +839,32 @@ NTSTATUS dcesrv_input(struct dcesrv_connection *dce_conn, const DATA_BLOB *data) { NTSTATUS status; + /* handle the very common case that the input contains a full packet and there + is no partial packet pending. In this case we can avoid a copy of the + data */ + if (dce_conn->partial_input.length == 0) { + dce_conn->partial_input = *data; + /* make sure that dce_partial_advance doesn't free this data */ + dce_conn->partial_input.free = NULL; + while (dce_full_packet(&dce_conn->partial_input)) { + status = dcesrv_input_process(dce_conn); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } + if (dce_conn->partial_input.length) { + /* there was some data left over. We have to copy this + as the caller may free the data */ + dce_conn->partial_input = + data_blob(dce_conn->partial_input.data, + dce_conn->partial_input.length); + if (!dce_conn->partial_input.data) { + return NT_STATUS_NO_MEMORY; + } + } + return NT_STATUS_OK; + } + dce_conn->partial_input.data = Realloc(dce_conn->partial_input.data, dce_conn->partial_input.length + data->length); if (!dce_conn->partial_input.data) { |