The branch, master has been updated via 9869358 s3:smb2_server: avoid talloc_zero_array() in smbd_smb2_request_setup_out() via cf77f16 s3:smb2_server: don't assume that req->out.vector is always a valid talloc pointer via 2edc730 s3:smb2_server: avoid talloc_zero_array() in smbd_smb2_request_error_ex() via adaf517 s3:smb2_server: optimize smbd_smb2_generate_outbody() for the common case via d307953 s3:smb2_write: make use of smbd_smb2_generate_outbody() via ec8dedb s3:smb2_tcon: make use of smbd_smb2_generate_outbody() via 27222bb s3:smb2_setinfo: make use of smbd_smb2_generate_outbody() via 39832ff s3:smb2_sesssetup: make use of smbd_smb2_generate_outbody() via c099797 s3:smb2_read: make use of smbd_smb2_generate_outbody() via b065578 s3:smb2_notify: make use of smbd_smb2_generate_outbody() via 59c185b s3:smb2_negprot: make use of smbd_smb2_generate_outbody() via aa70bf5 s3:smb2_lock: make use of smbd_smb2_generate_outbody() via 2ddfe40 s3:smb2_keepalive: make use of smbd_smb2_generate_outbody() via a6ee7ce s3:smb2_ioctl: make use of smbd_smb2_generate_outbody() via a021a25 s3:smb2_getinfo: make use of smbd_smb2_generate_outbody() via 46840db s3:smb2_flush: make use of smbd_smb2_generate_outbody() via 208046b s3:smb2_find: make use of smbd_smb2_generate_outbody() via 2c91f05 s3:smb2_create: make use of smbd_smb2_generate_outbody() via 2ecd5c9 s3:smb2_close: make use of smbd_smb2_generate_outbody() via c09292e s3:smb2_break: make use of smbd_smb2_generate_outbody() via fd4c82f s3:smb2_server: add smbd_smb2_generate_outbody() helper via a6ce800 s3:smb2_read: avoid 2 talloc* calls when using sendfile() via 0ac924b s3:smb2_server: avoid a call to data_blob_clear_free() if not needed via ec498a2 s3:smb2_server: optimize smbd_smb2_request_setup_out() via 66877df s3:smb2_server: optimize req->in.vector allocation from 032621d s3:smbd: s/BUFFER_SIZE/LARGE_WRITEX_BUFFER_SIZE
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 986935854f6ef4638d544054b9ed79f1d407bbf9 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Dec 4 15:32:45 2013 +0100 s3:smb2_server: avoid talloc_zero_array() in smbd_smb2_request_setup_out() In the common case with just one request, we can use a preallocated req->out.vector. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> Autobuild-User(master): Jeremy Allison <j...@samba.org> Autobuild-Date(master): Thu Mar 6 00:59:29 CET 2014 on sn-devel-104 commit cf77f16e3aa60258813b030f8a7f2e0cdd576368 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Dec 4 15:28:11 2013 +0100 s3:smb2_server: don't assume that req->out.vector is always a valid talloc pointer We use 'req' instead as it has the same lifetime. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 2edc7308d6185d724f38e602520617121ef57672 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Dec 4 15:24:29 2013 +0100 s3:smb2_server: avoid talloc_zero_array() in smbd_smb2_request_error_ex() It is only important that the content of info->data stays alive for the lifetime of the request, but the DATA_BLOB structure itself can be on the stack, while passing it as 'dyn' to smbd_smb2_request_done_ex(). Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit adaf517c87db22cb5b74906d43cfbae74a07130c Author: Stefan Metzmacher <me...@samba.org> Date: Wed Dec 4 15:05:34 2013 +0100 s3:smb2_server: optimize smbd_smb2_generate_outbody() for the common case Use a preallocated buffer for the first response in the compound chain. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit d307953e08038cf4ba0367a85296d9f3b11d51d7 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Dec 4 14:59:07 2013 +0100 s3:smb2_write: make use of smbd_smb2_generate_outbody() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit ec8dedb50f8be4c79b1018700b30f035a39650d3 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Dec 4 14:59:07 2013 +0100 s3:smb2_tcon: make use of smbd_smb2_generate_outbody() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 27222bb4f47d72e2759aca83e471d50db6321a26 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Dec 4 14:59:07 2013 +0100 s3:smb2_setinfo: make use of smbd_smb2_generate_outbody() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 39832ff588e4291df13307ab807130123768d3d6 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Dec 4 14:59:07 2013 +0100 s3:smb2_sesssetup: make use of smbd_smb2_generate_outbody() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit c099797238e0671e2c816f9a71b06859595264aa Author: Stefan Metzmacher <me...@samba.org> Date: Wed Dec 4 14:59:07 2013 +0100 s3:smb2_read: make use of smbd_smb2_generate_outbody() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit b065578320b51c8994ff01e79306640cabed1c6f Author: Stefan Metzmacher <me...@samba.org> Date: Wed Dec 4 14:59:07 2013 +0100 s3:smb2_notify: make use of smbd_smb2_generate_outbody() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 59c185bf549b359728183c8e61c165823f6112ef Author: Stefan Metzmacher <me...@samba.org> Date: Wed Dec 4 14:59:07 2013 +0100 s3:smb2_negprot: make use of smbd_smb2_generate_outbody() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit aa70bf5fdcfecf6966e7808d1837bbe134042d5b Author: Stefan Metzmacher <me...@samba.org> Date: Wed Dec 4 14:59:07 2013 +0100 s3:smb2_lock: make use of smbd_smb2_generate_outbody() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 2ddfe40425366dce59b9a23d65044c6a6f93ec81 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Dec 4 14:59:07 2013 +0100 s3:smb2_keepalive: make use of smbd_smb2_generate_outbody() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit a6ee7ce31a864db5a46bcf78d190f8955b95415c Author: Stefan Metzmacher <me...@samba.org> Date: Wed Dec 4 14:59:07 2013 +0100 s3:smb2_ioctl: make use of smbd_smb2_generate_outbody() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit a021a25104aa570efd8b69920b26fc2dcc6b5c04 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Dec 4 14:59:07 2013 +0100 s3:smb2_getinfo: make use of smbd_smb2_generate_outbody() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 46840db4160bfb4a908c08b065cd9130d63e2d86 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Dec 4 14:59:07 2013 +0100 s3:smb2_flush: make use of smbd_smb2_generate_outbody() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 208046b2eb83ca4b5c30b9fa3da69efae439fee3 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Dec 4 14:59:07 2013 +0100 s3:smb2_find: make use of smbd_smb2_generate_outbody() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 2c91f0506bca7936c4e25a8151a6b519c92faae9 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Dec 4 14:59:07 2013 +0100 s3:smb2_create: make use of smbd_smb2_generate_outbody() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 2ecd5c9693a98b6baefabd915a4a44e8ac3fad37 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Dec 4 14:59:07 2013 +0100 s3:smb2_close: make use of smbd_smb2_generate_outbody() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit c09292e20d8f1a6da6d5b56a1155abce4e02acf1 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Dec 4 14:59:07 2013 +0100 s3:smb2_break: make use of smbd_smb2_generate_outbody() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit fd4c82f6f50ebe02613c498c4f0070569e9ba10c Author: Stefan Metzmacher <me...@samba.org> Date: Wed Dec 4 12:52:21 2013 +0100 s3:smb2_server: add smbd_smb2_generate_outbody() helper We can add optimization there later. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit a6ce8001b4d022134e21cdf4c3180596a5a69101 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Dec 4 12:32:36 2013 +0100 s3:smb2_read: avoid 2 talloc* calls when using sendfile() Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 0ac924b2bb3c256f10cde358b95ea1d8a3833972 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Nov 20 09:56:48 2013 +0100 s3:smb2_server: avoid a call to data_blob_clear_free() if not needed Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit ec498a2414d96567bfed26f35b60ebe1ac40c68b Author: Stefan Metzmacher <me...@samba.org> Date: Wed Nov 20 09:56:19 2013 +0100 s3:smb2_server: optimize smbd_smb2_request_setup_out() We can use a preallocated buffer for the possible error response of the first response in the compound chain. This avoids a talloc_array_zero() call for the common case. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 66877dfaa59561145eba6233dc1f43c282d8cd08 Author: Stefan Metzmacher <me...@samba.org> Date: Tue Nov 19 07:42:57 2013 +0100 s3:smb2_server: optimize req->in.vector allocation We can avoid a talloc_zero_array() call in the common case (without compound requests) and use a preallocated array instead. Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> ----------------------------------------------------------------------- Summary of changes: source3/smbd/globals.h | 7 ++ source3/smbd/smb2_break.c | 2 +- source3/smbd/smb2_close.c | 2 +- source3/smbd/smb2_create.c | 2 +- source3/smbd/smb2_find.c | 2 +- source3/smbd/smb2_flush.c | 2 +- source3/smbd/smb2_getinfo.c | 2 +- source3/smbd/smb2_ioctl.c | 2 +- source3/smbd/smb2_keepalive.c | 2 +- source3/smbd/smb2_lock.c | 2 +- source3/smbd/smb2_negprot.c | 2 +- source3/smbd/smb2_notify.c | 2 +- source3/smbd/smb2_read.c | 32 ++++++---- source3/smbd/smb2_server.c | 133 ++++++++++++++++++++++++++++------------ source3/smbd/smb2_sesssetup.c | 4 +- source3/smbd/smb2_setinfo.c | 2 +- source3/smbd/smb2_tcon.c | 4 +- source3/smbd/smb2_write.c | 2 +- 18 files changed, 136 insertions(+), 70 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index bae3ed0..3baa048 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -225,6 +225,8 @@ void reply_smb20ff(struct smb_request *req, uint16_t choice); void smbd_smb2_first_negprot(struct smbd_server_connection *sconn, uint8_t *inbuf, size_t size); +DATA_BLOB smbd_smb2_generate_outbody(struct smbd_smb2_request *req, size_t size); + NTSTATUS smbd_smb2_request_error_ex(struct smbd_smb2_request *req, NTSTATUS status, DATA_BLOB *info, @@ -586,6 +588,7 @@ struct smbd_smb2_request { */ struct iovec *vector; int vector_count; + struct iovec _vector[1 + SMBD_SMB2_NUM_IOV_PER_REQ]; } in; struct { /* the NBT header is not allocated */ @@ -610,6 +613,10 @@ struct smbd_smb2_request { */ struct iovec *vector; int vector_count; + struct iovec _vector[1 + SMBD_SMB2_NUM_IOV_PER_REQ]; +#define OUTVEC_ALLOC_SIZE (SMB2_HDR_BODY + 9) + uint8_t _hdr[OUTVEC_ALLOC_SIZE]; + uint8_t _body[0x58]; } out; }; diff --git a/source3/smbd/smb2_break.c b/source3/smbd/smb2_break.c index 945faa1..6446b79 100644 --- a/source3/smbd/smb2_break.c +++ b/source3/smbd/smb2_break.c @@ -106,7 +106,7 @@ static void smbd_smb2_request_oplock_break_done(struct tevent_req *subreq) in_file_id_persistent = BVAL(inbody, 0x08); in_file_id_volatile = BVAL(inbody, 0x10); - outbody = data_blob_talloc(req->out.vector, NULL, 0x18); + outbody = smbd_smb2_generate_outbody(req, 0x18); if (outbody.data == NULL) { error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY); if (!NT_STATUS_IS_OK(error)) { diff --git a/source3/smbd/smb2_close.c b/source3/smbd/smb2_close.c index dce8cac..3712ffe 100644 --- a/source3/smbd/smb2_close.c +++ b/source3/smbd/smb2_close.c @@ -114,7 +114,7 @@ static void smbd_smb2_request_close_done(struct tevent_req *subreq) return; } - outbody = data_blob_talloc(req->out.vector, NULL, 0x3C); + outbody = smbd_smb2_generate_outbody(req, 0x3C); if (outbody.data == NULL) { error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY); if (!NT_STATUS_IS_OK(error)) { diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c index f2fec08..52ed171 100644 --- a/source3/smbd/smb2_create.c +++ b/source3/smbd/smb2_create.c @@ -318,7 +318,7 @@ static void smbd_smb2_request_create_done(struct tevent_req *tsubreq) out_context_buffer_offset = SMB2_HDR_BODY + 0x58; } - outbody = data_blob_talloc(smb2req->out.vector, NULL, 0x58); + outbody = smbd_smb2_generate_outbody(smb2req, 0x58); if (outbody.data == NULL) { error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY); if (!NT_STATUS_IS_OK(error)) { diff --git a/source3/smbd/smb2_find.c b/source3/smbd/smb2_find.c index 46d0aa4..3f779b8 100644 --- a/source3/smbd/smb2_find.c +++ b/source3/smbd/smb2_find.c @@ -162,7 +162,7 @@ static void smbd_smb2_request_find_done(struct tevent_req *subreq) out_output_buffer_offset = SMB2_HDR_BODY + 0x08; - outbody = data_blob_talloc(req->out.vector, NULL, 0x08); + outbody = smbd_smb2_generate_outbody(req, 0x08); if (outbody.data == NULL) { error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY); if (!NT_STATUS_IS_OK(error)) { diff --git a/source3/smbd/smb2_flush.c b/source3/smbd/smb2_flush.c index 00a7158..0d4c1a5 100644 --- a/source3/smbd/smb2_flush.c +++ b/source3/smbd/smb2_flush.c @@ -84,7 +84,7 @@ static void smbd_smb2_request_flush_done(struct tevent_req *subreq) return; } - outbody = data_blob_talloc(req->out.vector, NULL, 0x04); + outbody = smbd_smb2_generate_outbody(req, 0x04); if (outbody.data == NULL) { error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY); if (!NT_STATUS_IS_OK(error)) { diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c index 449aeb3..ec6181a 100644 --- a/source3/smbd/smb2_getinfo.c +++ b/source3/smbd/smb2_getinfo.c @@ -178,7 +178,7 @@ static void smbd_smb2_request_getinfo_done(struct tevent_req *subreq) out_output_buffer_offset = SMB2_HDR_BODY + 0x08; - outbody = data_blob_talloc(req->out.vector, NULL, 0x08); + outbody = smbd_smb2_generate_outbody(req, 0x08); if (outbody.data == NULL) { error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY); if (!NT_STATUS_IS_OK(error)) { diff --git a/source3/smbd/smb2_ioctl.c b/source3/smbd/smb2_ioctl.c index be2a798..6a19fcb 100644 --- a/source3/smbd/smb2_ioctl.c +++ b/source3/smbd/smb2_ioctl.c @@ -318,7 +318,7 @@ static void smbd_smb2_request_ioctl_done(struct tevent_req *subreq) out_input_offset = SMB2_HDR_BODY + 0x30; out_output_offset = SMB2_HDR_BODY + 0x30; - outbody = data_blob_talloc(req->out.vector, NULL, 0x30); + outbody = smbd_smb2_generate_outbody(req, 0x30); if (outbody.data == NULL) { error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY); if (!NT_STATUS_IS_OK(error)) { diff --git a/source3/smbd/smb2_keepalive.c b/source3/smbd/smb2_keepalive.c index 24a4f8e..b16ff6b 100644 --- a/source3/smbd/smb2_keepalive.c +++ b/source3/smbd/smb2_keepalive.c @@ -35,7 +35,7 @@ NTSTATUS smbd_smb2_request_process_keepalive(struct smbd_smb2_request *req) /* TODO: update some time stamps */ - outbody = data_blob_talloc(req->out.vector, NULL, 0x04); + outbody = smbd_smb2_generate_outbody(req, 0x04); if (outbody.data == NULL) { return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY); } diff --git a/source3/smbd/smb2_lock.c b/source3/smbd/smb2_lock.c index 671cd6f..4af3d61 100644 --- a/source3/smbd/smb2_lock.c +++ b/source3/smbd/smb2_lock.c @@ -146,7 +146,7 @@ static void smbd_smb2_request_lock_done(struct tevent_req *subreq) return; } - outbody = data_blob_talloc(smb2req->out.vector, NULL, 0x04); + outbody = smbd_smb2_generate_outbody(smb2req, 0x04); if (outbody.data == NULL) { error = smbd_smb2_request_error(smb2req, NT_STATUS_NO_MEMORY); if (!NT_STATUS_IS_OK(error)) { diff --git a/source3/smbd/smb2_negprot.c b/source3/smbd/smb2_negprot.c index b1e71e6..6643464 100644 --- a/source3/smbd/smb2_negprot.c +++ b/source3/smbd/smb2_negprot.c @@ -320,7 +320,7 @@ NTSTATUS smbd_smb2_request_process_negprot(struct smbd_smb2_request *req) return smbd_smb2_request_error(req, status); } - outbody = data_blob_talloc(req->out.vector, NULL, 0x40); + outbody = smbd_smb2_generate_outbody(req, 0x40); if (outbody.data == NULL) { return smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY); } diff --git a/source3/smbd/smb2_notify.c b/source3/smbd/smb2_notify.c index 228346e..7351d9f 100644 --- a/source3/smbd/smb2_notify.c +++ b/source3/smbd/smb2_notify.c @@ -130,7 +130,7 @@ static void smbd_smb2_request_notify_done(struct tevent_req *subreq) out_output_buffer_offset = SMB2_HDR_BODY + 0x08; - outbody = data_blob_talloc(req->out.vector, NULL, 0x08); + outbody = smbd_smb2_generate_outbody(req, 0x08); if (outbody.data == NULL) { error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY); if (!NT_STATUS_IS_OK(error)) { diff --git a/source3/smbd/smb2_read.c b/source3/smbd/smb2_read.c index 6478326..05563b2 100644 --- a/source3/smbd/smb2_read.c +++ b/source3/smbd/smb2_read.c @@ -128,7 +128,7 @@ static void smbd_smb2_request_read_done(struct tevent_req *subreq) out_data_offset = SMB2_HDR_BODY + 0x10; - outbody = data_blob_talloc(req->out.vector, NULL, 0x10); + outbody = smbd_smb2_generate_outbody(req, 0x10); if (outbody.data == NULL) { error = smbd_smb2_request_error(req, NT_STATUS_NO_MEMORY); if (!NT_STATUS_IS_OK(error)) { @@ -167,10 +167,16 @@ struct smbd_smb2_read_state { uint64_t in_offset; uint32_t in_minimum; DATA_BLOB out_headers; + uint8_t _out_hdr_buf[NBT_HDR_SIZE + SMB2_HDR_BODY + 0x10]; DATA_BLOB out_data; uint32_t out_remaining; }; +static int smb2_smb2_read_state_deny_destructor(struct smbd_smb2_read_state *state) +{ + return -1; +} + /* struct smbd_smb2_read_state destructor. Send the SMB2_READ data. */ static int smb2_sendfile_send_data(struct smbd_smb2_read_state *state) { @@ -258,7 +264,6 @@ static int smb2_sendfile_send_data(struct smbd_smb2_read_state *state) static NTSTATUS schedule_smb2_sendfile_read(struct smbd_smb2_request *smb2req, struct smbd_smb2_read_state *state) { - struct smbd_smb2_read_state *state_copy = NULL; files_struct *fsp = state->fsp; /* @@ -293,16 +298,8 @@ static NTSTATUS schedule_smb2_sendfile_read(struct smbd_smb2_request *smb2req, state->out_data.length = state->in_length; state->out_remaining = 0; - /* Make a copy of state attached to the smb2req. Attach - the destructor here as this will trigger the sendfile - call when the request is destroyed. */ - state_copy = talloc(smb2req, struct smbd_smb2_read_state); - if (!state_copy) { - return NT_STATUS_NO_MEMORY; - } - *state_copy = *state; - talloc_set_destructor(state_copy, smb2_sendfile_send_data); - state->smb2req->queue_entry.sendfile_header = &state_copy->out_headers; + state->out_headers = data_blob_const(state->_out_hdr_buf, + sizeof(state->_out_hdr_buf)); return NT_STATUS_OK; } @@ -582,6 +579,15 @@ static NTSTATUS smbd_smb2_read_recv(struct tevent_req *req, talloc_steal(mem_ctx, out_data->data); *out_remaining = state->out_remaining; - tevent_req_received(req); + if (state->out_headers.length > 0) { + talloc_steal(mem_ctx, state); + talloc_set_destructor(state, smb2_smb2_read_state_deny_destructor); + tevent_req_received(req); + state->smb2req->queue_entry.sendfile_header = &state->out_headers; + talloc_set_destructor(state, smb2_sendfile_send_data); + } else { + tevent_req_received(req); + } + return NT_STATUS_OK; } diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index 5e6bfd9..3c46efd 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -37,8 +37,6 @@ static void smbd_smb2_connection_handler(struct tevent_context *ev, static NTSTATUS smbd_smb2_io_handler(struct smbd_server_connection *sconn, uint16_t fde_flags); -#define OUTVEC_ALLOC_SIZE (SMB2_HDR_BODY + 9) - static const struct smbd_smb2_dispatch_table { uint16_t opcode; const char *name; @@ -255,8 +253,12 @@ static void smb2_setup_nbt_length(struct iovec *vector, int count) static int smbd_smb2_request_destructor(struct smbd_smb2_request *req) { - data_blob_clear_free(&req->first_key); - data_blob_clear_free(&req->last_key); + if (req->first_key.length > 0) { + data_blob_clear_free(&req->first_key); + } + if (req->last_key.length > 0) { + data_blob_clear_free(&req->last_key); + } return 0; } @@ -297,10 +299,11 @@ static NTSTATUS smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection *conn, NTTIME now, uint8_t *buf, size_t buflen, - TALLOC_CTX *mem_ctx, + struct smbd_smb2_request *req, struct iovec **piov, int *pnum_iov) { + TALLOC_CTX *mem_ctx = req; struct iovec *iov; int num_iov = 1; size_t taken = 0; @@ -312,10 +315,7 @@ static NTSTATUS smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection *conn, /* * Note: index '0' is reserved for the transport protocol */ - iov = talloc_zero_array(mem_ctx, struct iovec, num_iov); - if (iov == NULL) { - return NT_STATUS_NO_MEMORY; - } + iov = req->in._vector; while (taken < buflen) { size_t len = buflen - taken; @@ -327,7 +327,6 @@ static NTSTATUS smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection *conn, uint8_t *body = NULL; uint32_t dyn_size; uint8_t *dyn = NULL; - struct iovec *iov_tmp; if (verified_buflen > taken) { len = verified_buflen - taken; @@ -458,13 +457,31 @@ static NTSTATUS smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection *conn, dyn = body + body_size; dyn_size = full_size - (SMB2_HDR_BODY + body_size); - iov_tmp = talloc_realloc(mem_ctx, iov, struct iovec, - num_iov + SMBD_SMB2_NUM_IOV_PER_REQ); - if (iov_tmp == NULL) { - TALLOC_FREE(iov); - return NT_STATUS_NO_MEMORY; + if (num_iov >= ARRAY_SIZE(req->in._vector)) { + struct iovec *iov_tmp = NULL; + struct iovec *iov_alloc = NULL; + + if (iov != req->in._vector) { + iov_alloc = iov; + } + + iov_tmp = talloc_realloc(mem_ctx, iov_alloc, + struct iovec, + num_iov + + SMBD_SMB2_NUM_IOV_PER_REQ); + if (iov_tmp == NULL) { + TALLOC_FREE(iov_alloc); + return NT_STATUS_NO_MEMORY; + } + + if (iov_alloc == NULL) { + memcpy(iov_tmp, + req->in._vector, + sizeof(req->in._vector)); + } + + iov = iov_tmp; } - iov = iov_tmp; cur = &iov[num_iov]; num_iov += SMBD_SMB2_NUM_IOV_PER_REQ; @@ -485,7 +502,9 @@ static NTSTATUS smbd_smb2_inbuf_parse_compound(struct smbXsrv_connection *conn, return NT_STATUS_OK; inval: - TALLOC_FREE(iov); + if (iov != req->in._vector) { + TALLOC_FREE(iov); + } return NT_STATUS_INVALID_PARAMETER; } @@ -901,16 +920,34 @@ static void smb2_calculate_credits(const struct smbd_smb2_request *inreq, } } +DATA_BLOB smbd_smb2_generate_outbody(struct smbd_smb2_request *req, size_t size) +{ + if (req->current_idx <= 1) { + if (size <= sizeof(req->out._body)) { + return data_blob_const(req->out._body, size); + } + } + + return data_blob_talloc(req, NULL, size); +} + static NTSTATUS smbd_smb2_request_setup_out(struct smbd_smb2_request *req) { + TALLOC_CTX *mem_ctx; struct iovec *vector; int count; int idx; count = req->in.vector_count; - vector = talloc_zero_array(req, struct iovec, count); - if (vector == NULL) { - return NT_STATUS_NO_MEMORY; + if (count <= ARRAY_SIZE(req->out._vector)) { + mem_ctx = req; + vector = req->out._vector; + } else { + vector = talloc_zero_array(req, struct iovec, count); + if (vector == NULL) { + return NT_STATUS_NO_MEMORY; + } + mem_ctx = vector; } vector[0].iov_base = req->out.nbt_hdr; @@ -931,10 +968,14 @@ static NTSTATUS smbd_smb2_request_setup_out(struct smbd_smb2_request *req) next_command_ofs = SMB2_HDR_BODY + 9; } - outhdr = talloc_zero_array(vector, uint8_t, - OUTVEC_ALLOC_SIZE); - if (outhdr == NULL) { - return NT_STATUS_NO_MEMORY; + if (idx == 1) { + outhdr = req->out._hdr; + } else { + outhdr = talloc_zero_array(mem_ctx, uint8_t, + OUTVEC_ALLOC_SIZE); + if (outhdr == NULL) { + return NT_STATUS_NO_MEMORY; + } } outbody = outhdr + SMB2_HDR_BODY; @@ -1324,7 +1365,9 @@ NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req, if (!NT_STATUS_IS_OK(status)) { return status; } - data_blob_clear_free(&req->first_key); + if (req->first_key.length > 0) { + data_blob_clear_free(&req->first_key); + } req->current_idx = 1; @@ -1355,7 +1398,9 @@ NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req, SIVAL(outhdr, SMB2_HDR_FLAGS, flags); } } - data_blob_clear_free(&req->last_key); + if (req->last_key.length > 0) { + data_blob_clear_free(&req->last_key); + } defer_endtime = timeval_current_ofs_usec(defer_time); req->async_te = tevent_add_timer(req->sconn->ev_ctx, @@ -2310,7 +2355,7 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req) return NT_STATUS_NO_MEMORY; } - tf = talloc_zero_array(req->out.vector, uint8_t, + tf = talloc_zero_array(req, uint8_t, SMB2_TF_HDR_SIZE); if (tf == NULL) { return NT_STATUS_NO_MEMORY; @@ -2345,7 +2390,9 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req) return status; } } - data_blob_clear_free(&req->last_key); + if (req->last_key.length > 0) { + data_blob_clear_free(&req->last_key); + } req->current_idx += SMBD_SMB2_NUM_IOV_PER_REQ; @@ -2419,7 +2466,9 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req) return status; } } - data_blob_clear_free(&req->first_key); + if (req->first_key.length > 0) { + data_blob_clear_free(&req->first_key); + } /* I am a sick, sick man... :-). Sendfile hack ... JRA. */ if (req->out.vector_count < (2*SMBD_SMB2_NUM_IOV_PER_REQ) && @@ -2540,7 +2589,7 @@ NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req, */ uint8_t *pad; - pad = talloc_zero_array(req->out.vector, + pad = talloc_zero_array(req, uint8_t, pad_size); if (pad == NULL) { return smbd_smb2_request_error(req, @@ -2563,7 +2612,7 @@ NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req, old_dyn = SMBD_SMB2_OUT_DYN_PTR(req); new_size = old_size + pad_size; - new_dyn = talloc_zero_array(req->out.vector, + new_dyn = talloc_zero_array(req, uint8_t, new_size); if (new_dyn == NULL) { return smbd_smb2_request_error(req, @@ -2590,6 +2639,7 @@ NTSTATUS smbd_smb2_request_error_ex(struct smbd_smb2_request *req, const char *location) { DATA_BLOB body; + DATA_BLOB _dyn; uint8_t *outhdr = SMBD_SMB2_OUT_HDR_PTR(req); size_t unread_bytes = smbd_smb2_unread_bytes(req); @@ -2631,12 +2681,7 @@ NTSTATUS smbd_smb2_request_error_ex(struct smbd_smb2_request *req, * *MUST BE* OUTVEC_ALLOC_SIZE. So we have room for * 1 byte without having to do an alloc. */ - info = talloc_zero_array(req->out.vector, -- Samba Shared Repository