The Samba-Bugzilla – Attachment 6815 Details for
Bug 8407
SMB2 server can return requests out-of-order when processing a compound request.
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
git-am fix for 3.6.1 based on Metze's patch
samba-3.6.patch (text/plain), 9.89 KB, created by
Jeremy Allison
on 2011-08-26 21:28:31 UTC
(
hide
)
Description:
git-am fix for 3.6.1 based on Metze's patch
Filename:
MIME Type:
Creator:
Jeremy Allison
Created:
2011-08-26 21:28:31 UTC
Size:
9.89 KB
patch
obsolete
>From 076412390210a9abbd08350a6458aaec375cefe5 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Fri, 5 Aug 2011 20:34:43 +0200 >Subject: [PATCH 1/3] s3:smb2_server: make sure we prefer responses over requests on the client socket > >metze > >Autobuild-User: Stefan Metzmacher <metze@samba.org> >Autobuild-Date: Fri Aug 12 16:46:43 CEST 2011 on sn-devel-104 >(cherry picked from commit 42cde0480bd6a5e2dddaa66917e1fa71e6a4edcd) >--- > source3/smbd/smb2_server.c | 64 +++++++++++++++++++++++++++++++++++-------- > 1 files changed, 52 insertions(+), 12 deletions(-) > >diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c >index 0cc80ed..b121a29 100644 >--- a/source3/smbd/smb2_server.c >+++ b/source3/smbd/smb2_server.c >@@ -1695,6 +1695,8 @@ void smbd_smb2_request_dispatch_immediate(struct tevent_context *ctx, > } > } > >+static NTSTATUS smbd_smb2_request_next_incoming(struct smbd_server_connection *sconn); >+ > static void smbd_smb2_request_writev_done(struct tevent_req *subreq) > { > struct smbd_smb2_request *req = tevent_req_callback_data(subreq, >@@ -1702,17 +1704,24 @@ static void smbd_smb2_request_writev_done(struct tevent_req *subreq) > struct smbd_server_connection *sconn = req->sconn; > int ret; > int sys_errno; >+ NTSTATUS status; > > ret = tstream_writev_queue_recv(subreq, &sys_errno); > TALLOC_FREE(subreq); > TALLOC_FREE(req); > if (ret == -1) { >- NTSTATUS status = map_nt_error_from_unix(sys_errno); >+ status = map_nt_error_from_unix(sys_errno); > DEBUG(2,("smbd_smb2_request_writev_done: client write error %s\n", > nt_errstr(status))); > smbd_server_connection_terminate(sconn, nt_errstr(status)); > return; > } >+ >+ status = smbd_smb2_request_next_incoming(sconn); >+ if (!NT_STATUS_IS_OK(status)) { >+ smbd_server_connection_terminate(sconn, nt_errstr(status)); >+ return; >+ } > } > > NTSTATUS smbd_smb2_request_done_ex(struct smbd_smb2_request *req, >@@ -2317,12 +2326,47 @@ static NTSTATUS smbd_smb2_request_read_recv(struct tevent_req *req, > > static void smbd_smb2_request_incoming(struct tevent_req *subreq); > >+static NTSTATUS smbd_smb2_request_next_incoming(struct smbd_server_connection *sconn) >+{ >+ size_t max_send_queue_len; >+ size_t cur_send_queue_len; >+ struct tevent_req *subreq; >+ >+ if (tevent_queue_length(sconn->smb2.recv_queue) > 0) { >+ /* >+ * if there is already a smbd_smb2_request_read >+ * pending, we are done. >+ */ >+ return NT_STATUS_OK; >+ } >+ >+ max_send_queue_len = MAX(1, sconn->smb2.max_credits/16); >+ cur_send_queue_len = tevent_queue_length(sconn->smb2.send_queue); >+ >+ if (cur_send_queue_len > max_send_queue_len) { >+ /* >+ * if we have a lot of requests to send, >+ * we wait until they are on the wire until we >+ * ask for the next request. >+ */ >+ return NT_STATUS_OK; >+ } >+ >+ /* ask for the next request */ >+ subreq = smbd_smb2_request_read_send(sconn, sconn->smb2.event_ctx, sconn); >+ if (subreq == NULL) { >+ return NT_STATUS_NO_MEMORY; >+ } >+ tevent_req_set_callback(subreq, smbd_smb2_request_incoming, sconn); >+ >+ return NT_STATUS_OK; >+} >+ > void smbd_smb2_first_negprot(struct smbd_server_connection *sconn, > const uint8_t *inbuf, size_t size) > { > NTSTATUS status; > struct smbd_smb2_request *req = NULL; >- struct tevent_req *subreq; > > DEBUG(10,("smbd_smb2_first_negprot: packet length %u\n", > (unsigned int)size)); >@@ -2351,13 +2395,11 @@ void smbd_smb2_first_negprot(struct smbd_server_connection *sconn, > return; > } > >- /* ask for the next request */ >- subreq = smbd_smb2_request_read_send(sconn, sconn->smb2.event_ctx, sconn); >- if (subreq == NULL) { >- smbd_server_connection_terminate(sconn, "no memory for reading"); >+ status = smbd_smb2_request_next_incoming(sconn); >+ if (!NT_STATUS_IS_OK(status)) { >+ smbd_server_connection_terminate(sconn, nt_errstr(status)); > return; > } >- tevent_req_set_callback(subreq, smbd_smb2_request_incoming, sconn); > > sconn->num_requests++; > } >@@ -2409,13 +2451,11 @@ static void smbd_smb2_request_incoming(struct tevent_req *subreq) > } > > next: >- /* ask for the next request (this constructs the main loop) */ >- subreq = smbd_smb2_request_read_send(sconn, sconn->smb2.event_ctx, sconn); >- if (subreq == NULL) { >- smbd_server_connection_terminate(sconn, "no memory for reading"); >+ status = smbd_smb2_request_next_incoming(sconn); >+ if (!NT_STATUS_IS_OK(status)) { >+ smbd_server_connection_terminate(sconn, nt_errstr(status)); > return; > } >- tevent_req_set_callback(subreq, smbd_smb2_request_incoming, sconn); > > sconn->num_requests++; > >-- >1.7.3.1 > > >From c449ecbfd5f4b562540822e1d0e181dd45e1ce66 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 25 Aug 2011 23:33:41 +0200 >Subject: [PATCH 2/3] s3:smb2_server: keep compound_related on struct smbd_smb2_request > >metze >(cherry picked from commit cda93f04eb4e7e975b192a5fd33275ec638140ac) >--- > source3/smbd/globals.h | 1 + > source3/smbd/smb2_server.c | 7 +++---- > 2 files changed, 4 insertions(+), 4 deletions(-) > >diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h >index 58e03a5..ed3a8c6 100644 >--- a/source3/smbd/globals.h >+++ b/source3/smbd/globals.h >@@ -358,6 +358,7 @@ struct smbd_smb2_request { > bool do_signing; > bool async; > bool cancelled; >+ bool compound_related; > > /* fake smb1 request. */ > struct smb_request *smb1req; >diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c >index b121a29..0cd664a 100644 >--- a/source3/smbd/smb2_server.c >+++ b/source3/smbd/smb2_server.c >@@ -357,7 +357,6 @@ static NTSTATUS smbd_smb2_request_validate(struct smbd_smb2_request *req) > { > int count; > int idx; >- bool compound_related = false; > > count = req->in.vector_count; > >@@ -405,7 +404,7 @@ static NTSTATUS smbd_smb2_request_validate(struct smbd_smb2_request *req) > * compounded requests > */ > if (flags & SMB2_HDR_FLAG_CHAINED) { >- compound_related = true; >+ req->compound_related = true; > } > } else if (idx > 4) { > #if 0 >@@ -418,13 +417,13 @@ static NTSTATUS smbd_smb2_request_validate(struct smbd_smb2_request *req) > * all other requests should match the 2nd one > */ > if (flags & SMB2_HDR_FLAG_CHAINED) { >- if (!compound_related) { >+ if (!req->compound_related) { > req->next_status = > NT_STATUS_INVALID_PARAMETER; > return NT_STATUS_OK; > } > } else { >- if (compound_related) { >+ if (req->compound_related) { > req->next_status = > NT_STATUS_INVALID_PARAMETER; > return NT_STATUS_OK; >-- >1.7.3.1 > > >From 9f8b2b9e4eee8c7b6c8f4ca98c4a8e50ca38f196 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Fri, 26 Aug 2011 14:23:26 -0700 >Subject: [PATCH 3/3] Based on metze's fix for Bug 8407 - SMB2 server can return requests out-of-order when processing a compound request. > (cherry picked from commit 19db1c98c6ba3cb5e883e16e865c44900ce17444) > >--- > source3/smbd/globals.h | 1 + > source3/smbd/smb2_server.c | 40 ++++++++++++++++++++++++++++++++++++++-- > 2 files changed, 39 insertions(+), 2 deletions(-) > >diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h >index ed3a8c6..abeaed4 100644 >--- a/source3/smbd/globals.h >+++ b/source3/smbd/globals.h >@@ -602,6 +602,7 @@ struct smbd_server_connection { > uint32_t credits_granted; > uint32_t max_credits; > struct bitmap *credits_bitmap; >+ bool compound_related_in_progress; > } smb2; > }; > >diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c >index 0cd664a..d7a40ed 100644 >--- a/source3/smbd/smb2_server.c >+++ b/source3/smbd/smb2_server.c >@@ -883,6 +883,20 @@ NTSTATUS smbd_smb2_request_pending_queue(struct smbd_smb2_request *req, > if (!NT_STATUS_IS_OK(status)) { > return status; > } >+ >+ /* >+ * We're splitting off the last SMB2 >+ * request in a compound set, and the >+ * smb2_send_async_interim_response() >+ * call above just sent all the replies >+ * for the previous SMB2 requests in >+ * this compound set. So we're no longer >+ * in the "compound_related_in_progress" >+ * state, and this is no longer a compound >+ * request. >+ */ >+ req->compound_related = false; >+ req->sconn->smb2.compound_related_in_progress = false; > } > > /* Don't return an intermediate packet on a pipe read/write. */ >@@ -1174,6 +1188,10 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req) > req->compat_chain_fsp = NULL; > } > >+ if (req->compound_related) { >+ req->sconn->smb2.compound_related_in_progress = true; >+ } >+ > switch (opcode) { > case SMB2_OP_NEGPROT: > /* This call needs to be run as root */ >@@ -1620,6 +1638,10 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req) > return NT_STATUS_OK; > } > >+ if (req->compound_related) { >+ req->sconn->smb2.compound_related_in_progress = false; >+ } >+ > smb2_setup_nbt_length(req->out.vector, req->out.vector_count); > > /* Set credit for this operation (zero credits if this >@@ -1670,6 +1692,8 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req) > return NT_STATUS_OK; > } > >+static NTSTATUS smbd_smb2_request_next_incoming(struct smbd_server_connection *sconn); >+ > void smbd_smb2_request_dispatch_immediate(struct tevent_context *ctx, > struct tevent_immediate *im, > void *private_data) >@@ -1692,9 +1716,13 @@ void smbd_smb2_request_dispatch_immediate(struct tevent_context *ctx, > smbd_server_connection_terminate(sconn, nt_errstr(status)); > return; > } >-} > >-static NTSTATUS smbd_smb2_request_next_incoming(struct smbd_server_connection *sconn); >+ status = smbd_smb2_request_next_incoming(sconn); >+ if (!NT_STATUS_IS_OK(status)) { >+ smbd_server_connection_terminate(sconn, nt_errstr(status)); >+ return; >+ } >+} > > static void smbd_smb2_request_writev_done(struct tevent_req *subreq) > { >@@ -2331,6 +2359,14 @@ static NTSTATUS smbd_smb2_request_next_incoming(struct smbd_server_connection *s > size_t cur_send_queue_len; > struct tevent_req *subreq; > >+ if (sconn->smb2.compound_related_in_progress) { >+ /* >+ * Can't read another until the related >+ * compound is done. >+ */ >+ return NT_STATUS_OK; >+ } >+ > if (tevent_queue_length(sconn->smb2.recv_queue) > 0) { > /* > * if there is already a smbd_smb2_request_read >-- >1.7.3.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Flags:
metze
:
review-
Actions:
View
Attachments on
bug 8407
:
6807
|
6808
|
6809
|
6810
|
6811
|
6812
|
6814
|
6815
|
6855