From 8b8c5c4154f581c5d79585017443dffc1602bdf6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 8 Jun 2020 12:23:47 +0200 Subject: [PATCH] s3:smbd: force multi-channel to be turned off without FreeBSD/Linux support MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Günther Deschner --- .../protocol/servermultichannelsupport.xml | 5 ++++ source3/smbd/globals.h | 2 ++ source3/smbd/smb2_server.c | 26 +++++++++++++++++++ source3/smbd/smbXsrv_client.c | 3 ++- 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/docs-xml/smbdotconf/protocol/servermultichannelsupport.xml b/docs-xml/smbdotconf/protocol/servermultichannelsupport.xml index e39785427a6..5f87298b4bd 100644 --- a/docs-xml/smbdotconf/protocol/servermultichannelsupport.xml +++ b/docs-xml/smbdotconf/protocol/servermultichannelsupport.xml @@ -15,6 +15,11 @@ it may result in data corruption under some race conditions. Future releases may improve this situation. + + 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 force:server multi channel support=yes + in addition. no diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 1276ffa0084..176c9053f3a 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -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, diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index 31a5a5f868c..a147f858c91 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -37,9 +37,11 @@ /* 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) { diff --git a/source3/smbd/smbXsrv_client.c b/source3/smbd/smbXsrv_client.c index c6114d4b8dc..f61ab3da35b 100644 --- a/source3/smbd/smbXsrv_client.c +++ b/source3/smbd/smbXsrv_client.c @@ -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; } -- 2.34.1