s3:smbd: force multi-channel to be turned off without FreeBSD/Linux support
authorStefan Metzmacher <metze@samba.org>
Mon, 8 Jun 2020 10:23:47 +0000 (12:23 +0200)
committerStefan Metzmacher <metze@samba.org>
Wed, 8 Jul 2020 15:54:40 +0000 (15:54 +0000)
For now it's safer to disable multi-channel without having support
for TIOCOUTQ/FIONWRITE on tcp sockets.

Using a fixed retransmission timeout (rto) of 1 second would be ok,
but we better require kernel support for requesting for unacked bytes
in the kernel send queue.

"force:server multi channel support = yes" can be used to overwrite
the compile time restriction (mainly for testing).

BUG: https://bugzilla.samba.org/show_bug.cgi?id=11897

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Günther Deschner <gd@samba.org>
docs-xml/smbdotconf/protocol/servermultichannelsupport.xml
source3/smbd/globals.h
source3/smbd/smb2_server.c
source3/smbd/smbXsrv_client.c

index e39785427a6a83f75fd8c7b65d8b682fd1c57b3e..5f87298b4bd1b48a54ee998c4e15e4594b422811 100644 (file)
     it may result in data corruption under some race conditions.
     Future releases may improve this situation.
     </para>
+
+    <para>Due to dependencies to kernel APIs of Linux or FreeBSD, it's only possible
+    to use this feature on Linux and FreeBSD for now. For testing this restriction
+    can be overwritten by specifying <constant>force:server multi channel support=yes</constant>
+    in addition.</para>
 </description>
 
 <value type="default">no</value>
index 1276ffa0084dd345f057c851d2c91eddcf1bfb23..176c9053f3a42ed56a97879e836d714de8f8b574 100644 (file)
@@ -250,6 +250,8 @@ NTSTATUS smbd_smb2_process_negprot(struct smbXsrv_connection *xconn,
 
 DATA_BLOB smbd_smb2_generate_outbody(struct smbd_smb2_request *req, size_t size);
 
+bool smbXsrv_server_multi_channel_enabled(void);
+
 NTSTATUS smbd_smb2_request_error_ex(struct smbd_smb2_request *req,
                                    NTSTATUS status,
                                    DATA_BLOB *info,
index 31a5a5f868c21c988d8ffd9837910721ad5b93c5..a147f858c91e456e15bcdade9e171c0ebf7bcfbd 100644 (file)
 /* SIOCOUTQ TIOCOUTQ are the same */
 #define __IOCTL_SEND_QUEUE_SIZE_OPCODE TIOCOUTQ
 #define __HAVE_TCP_INFO_RTO 1
+#define __ALLOW_MULTI_CHANNEL_SUPPORT 1
 #elif defined(FREEBSD)
 #define __IOCTL_SEND_QUEUE_SIZE_OPCODE FIONWRITE
 #define __HAVE_TCP_INFO_RTO 1
+#define __ALLOW_MULTI_CHANNEL_SUPPORT 1
 #endif
 
 #include "lib/crypto/gnutls_helpers.h"
@@ -1116,6 +1118,30 @@ static NTSTATUS smbd_smb2_request_setup_out(struct smbd_smb2_request *req)
        return NT_STATUS_OK;
 }
 
+bool smbXsrv_server_multi_channel_enabled(void)
+{
+       bool enabled = lp_server_multi_channel_support();
+#ifndef __ALLOW_MULTI_CHANNEL_SUPPORT
+       bool forced = false;
+       /*
+        * If we don't have support from the kernel
+        * to ask for the un-acked number of bytes
+        * in the socket send queue, we better
+        * don't support multi-channel.
+        */
+       forced = lp_parm_bool(-1, "force", "server multi channel support", false);
+       if (enabled && !forced) {
+               D_NOTICE("'server multi channel support' enabled "
+                        "but not supported on %s (%s)\n",
+                        SYSTEM_UNAME_SYSNAME, SYSTEM_UNAME_RELEASE);
+               DEBUGADD(DBGLVL_NOTICE, ("Please report this on "
+                       "https://bugzilla.samba.org/show_bug.cgi?id=11897\n"));
+               enabled = false;
+       }
+#endif /* ! __ALLOW_MULTI_CHANNEL_SUPPORT */
+       return enabled;
+}
+
 static NTSTATUS smbXsrv_connection_get_rto_usecs(struct smbXsrv_connection *xconn,
                                                 uint32_t *_rto_usecs)
 {
index c6114d4b8dcfce6089e2d201a3d7b67401dfc6d2..f61ab3da35b0ecef54c3dcd9d053104c289945b5 100644 (file)
@@ -522,7 +522,8 @@ NTSTATUS smbXsrv_client_create(TALLOC_CTX *mem_ctx,
        client->raw_ev_ctx = ev_ctx;
        client->msg_ctx = msg_ctx;
 
-       client->server_multi_channel_enabled = lp_server_multi_channel_support();
+       client->server_multi_channel_enabled =
+               smbXsrv_server_multi_channel_enabled();
        if (client->server_multi_channel_enabled) {
                client->next_channel_id = 1;
        }