[SCM] Samba Shared Repository - branch v3-6-test updated

Karolin Seeger kseeger at samba.org
Thu Sep 15 12:27:34 MDT 2011


The branch, v3-6-test has been updated
       via  151bea2 s3:smb2_server: keep compound_related on struct smbd_smb2_request
       via  bd377e8 Based on metze's fix for Bug 8407 - SMB2 server can return requests out-of-order when processing a compound request.
       via  90e4b68 s3:smb2_server: make sure we prefer responses over requests on the client socket
      from  7d2006c Fix bug 8433, segfault in iconv.c

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-6-test


- Log -----------------------------------------------------------------
commit 151bea2cc30f5a3e3cfaafd9e080f0d510f9563e
Author: Stefan Metzmacher <metze at samba.org>
Date:   Thu Aug 25 23:33:41 2011 +0200

    s3:smb2_server: keep compound_related on struct smbd_smb2_request
    
    metze
    (cherry picked from commit 0d450d166bab952daf37d922e5c2e5cac16f1cc3)
    
    The last 3 patches address bug #8407 (SMB2 server can return requests
    out-of-order when processing a compound request).

commit bd377e89a6bc5fa20485bf9614c06159c9785cdf
Author: Jeremy Allison <jra at samba.org>
Date:   Fri Aug 26 14:23:26 2011 -0700

    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 726b4685aa25b0b3b4470bfec5d514fb2db7a95e)

commit 90e4b68a3b0e46c238753e66ededa16de3104302
Author: Stefan Metzmacher <metze at samba.org>
Date:   Fri Aug 5 20:34:43 2011 +0200

    s3:smb2_server: make sure we prefer responses over requests on the client socket
    
    metze
    
    Autobuild-User: Stefan Metzmacher <metze at samba.org>
    Autobuild-Date: Fri Aug 12 16:46:43 CEST 2011 on sn-devel-104
    (cherry picked from commit 42cde0480bd6a5e2dddaa66917e1fa71e6a4edcd)

-----------------------------------------------------------------------

Summary of changes:
 source3/smbd/globals.h     |    2 +
 source3/smbd/smb2_server.c |  107 +++++++++++++++++++++++++++++++++++++-------
 2 files changed, 93 insertions(+), 16 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 58e03a5..abeaed4 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;
@@ -601,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 0cc80ed..d7a40ed 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;
@@ -884,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. */
@@ -1175,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 */
@@ -1621,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
@@ -1671,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)
@@ -1693,6 +1716,12 @@ void smbd_smb2_request_dispatch_immediate(struct tevent_context *ctx,
 		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;
+	}
 }
 
 static void smbd_smb2_request_writev_done(struct tevent_req *subreq)
@@ -1702,17 +1731,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 +2353,55 @@ 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 (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
+		 * 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 +2430,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 +2486,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++;
 


-- 
Samba Shared Repository


More information about the samba-cvs mailing list