smbd:smb2: update outstanding request counters before sending a reply
authorMichael Adam <obnox@samba.org>
Tue, 23 Feb 2016 19:54:34 +0000 (20:54 +0100)
committerJeremy Allison <jra@samba.org>
Mon, 21 Mar 2016 23:23:21 +0000 (00:23 +0100)
This is part of the channel sequence number treatment of multi-channel.

Pair-Programmed-With: Guenther Deschner <gd@samba.org>

Signed-off-by: Michael Adam <obnox@samba.org>
Signed-off-by: Guenther Deschner <gd@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/smbd/smb2_server.c

index 01892e1847be91b1b7ce9b5c2f81e13cc864b7fa..ae125dffefcb77ebbd829ab10b3d1738a58809d3 100644 (file)
@@ -2676,6 +2676,40 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
        return return_value;
 }
 
+static void smbd_smb2_request_reply_update_counts(struct smbd_smb2_request *req)
+{
+       struct smbXsrv_connection *xconn = req->xconn;
+       const uint8_t *inhdr;
+       uint16_t channel_sequence;
+       struct smbXsrv_open *op;
+
+       if (!req->request_counters_updated) {
+               return;
+       }
+
+       if (xconn->protocol < PROTOCOL_SMB2_22) {
+               return;
+       }
+
+       if (req->compat_chain_fsp == NULL) {
+               return;
+       }
+
+       op = req->compat_chain_fsp->op;
+       if (op == NULL) {
+               return;
+       }
+
+       inhdr = SMBD_SMB2_IN_HDR_PTR(req);
+       channel_sequence = SVAL(inhdr, SMB2_HDR_CHANNEL_SEQUENCE);
+
+       if (op->global->channel_sequence == channel_sequence) {
+               op->request_count -= 1;
+       } else {
+               op->pre_request_count -= 1;
+       }
+}
+
 static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
 {
        struct smbXsrv_connection *xconn = req->xconn;
@@ -2689,6 +2723,9 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
        req->subreq = NULL;
        TALLOC_FREE(req->async_te);
 
+       /* MS-SMB2: 3.3.4.1 Sending Any Outgoing Message */
+       smbd_smb2_request_reply_update_counts(req);
+
        if (req->do_encryption &&
            (firsttf->iov_len == 0) &&
            (req->first_key.length == 0) &&