From b23d6f89d5512bef68ab1d07fd84f25b44b99e6d Mon Sep 17 00:00:00 2001 From: matt335672 <30179339+matt335672@users.noreply.github.com> Date: Thu, 11 Jan 2024 11:53:54 +0000 Subject: [PATCH] Improve performance on long fat networks (LFNs) On Linux, the TCP send buffer size is increased to 32768 if it is less that this (which it normally is). This however has the effect of disabling dynamic buffer sizing, leading to a maximum available bandwidth of max_bandwidth = 262144 (bits) / round_trip_time (secs) This is not noticeable on a LAN with an RTT of around 0.5ms, but very noticeable on a WAN with an RTT of 0.25s. Comments in the config file and manpage in this area are improved, as is the logging if the parameters are actually set. --- common/os_calls.c | 17 ---------------- docs/man/xrdp.ini.5.in | 4 +++- xrdp/xrdp.ini.in | 5 ++++- xrdp/xrdp_listen.c | 46 ++++++++++++++++++++---------------------- 4 files changed, 29 insertions(+), 43 deletions(-) diff --git a/common/os_calls.c b/common/os_calls.c index 765ad472..5a71d000 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -438,23 +438,6 @@ g_tcp_socket(void) } } - option_len = sizeof(option_value); - - if (getsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char *)&option_value, - &option_len) == 0) - { - if (option_value < (1024 * 32)) - { - option_value = 1024 * 32; - option_len = sizeof(option_value); - if (setsockopt(rv, SOL_SOCKET, SO_SNDBUF, (char *)&option_value, - option_len) < 0) - { - LOG(LOG_LEVEL_ERROR, "g_tcp_socket: setsockopt() failed"); - } - } - } - return rv; } diff --git a/docs/man/xrdp.ini.5.in b/docs/man/xrdp.ini.5.in index be6c82e3..e44327ce 100644 --- a/docs/man/xrdp.ini.5.in +++ b/docs/man/xrdp.ini.5.in @@ -177,7 +177,9 @@ If set to \fB1\fP, \fBtrue\fP or \fByes\fP, no buffering will be performed in th \fBtcp_send_buffer_bytes\fP=\fIbuffer_size\fP .TP \fBtcp_recv_buffer_bytes\fP=\fIbuffer_size\fP -Specify send/recv buffer sizes in bytes. The default value depends on operating system. +Specify send/recv buffer sizes in bytes. The default value depends on +the operating system. It is recommended not to set these on systems with +dynamic TCP buffer sizing .TP \fBtls_ciphers\fP=\fIcipher_suite\fP diff --git a/xrdp/xrdp.ini.in b/xrdp/xrdp.ini.in index 93c23196..826a29fa 100644 --- a/xrdp/xrdp.ini.in +++ b/xrdp/xrdp.ini.in @@ -35,7 +35,10 @@ tcp_nodelay=true ; if the network connection disappear without close messages the connection will be closed tcp_keepalive=true -; set tcp send/recv buffer (for experts) +; set tcp send/recv buffer +; These parameters are largely historic. On systems with dynamic TCP +; buffer sizes, setting them manually will either impact performance or +; waste memory #tcp_send_buffer_bytes=32768 #tcp_recv_buffer_bytes=32768 diff --git a/xrdp/xrdp_listen.c b/xrdp/xrdp_listen.c index 5dd9c19b..099b7735 100644 --- a/xrdp/xrdp_listen.c +++ b/xrdp/xrdp_listen.c @@ -716,47 +716,45 @@ xrdp_listen_process_startup_params(struct xrdp_listen *self) if (startup_params->tcp_send_buffer_bytes > 0) { bytes = startup_params->tcp_send_buffer_bytes; - LOG(LOG_LEVEL_INFO, "setting send buffer to %d bytes", - bytes); if (g_sck_set_send_buffer_bytes(ltrans->sck, bytes) != 0) { LOG(LOG_LEVEL_WARNING, "error setting send buffer"); } + else if (g_sck_get_send_buffer_bytes(ltrans->sck, &bytes) != 0) + { + LOG(LOG_LEVEL_WARNING, "error getting send buffer"); + } + else if (bytes != startup_params->tcp_send_buffer_bytes) + { + LOG(LOG_LEVEL_WARNING, "send buffer set to %d " + "bytes but %d bytes requested", bytes, + startup_params->tcp_send_buffer_bytes); + } else { - if (g_sck_get_send_buffer_bytes(ltrans->sck, &bytes) != 0) - { - LOG(LOG_LEVEL_WARNING, "error getting send " - "buffer"); - } - else - { - LOG(LOG_LEVEL_INFO, "send buffer set to %d " - "bytes", bytes); - } + LOG(LOG_LEVEL_INFO, "send buffer set to %d bytes", bytes); } } if (startup_params->tcp_recv_buffer_bytes > 0) { bytes = startup_params->tcp_recv_buffer_bytes; - LOG(LOG_LEVEL_INFO, "setting recv buffer to %d bytes", - bytes); if (g_sck_set_recv_buffer_bytes(ltrans->sck, bytes) != 0) { LOG(LOG_LEVEL_WARNING, "error setting recv buffer"); } + else if (g_sck_get_recv_buffer_bytes(ltrans->sck, &bytes) != 0) + { + LOG(LOG_LEVEL_WARNING, "error getting recv buffer"); + } + else if (bytes != startup_params->tcp_recv_buffer_bytes) + { + LOG(LOG_LEVEL_WARNING, "recv buffer set to %d " + "bytes but %d bytes requested", bytes, + startup_params->tcp_recv_buffer_bytes); + } else { - if (g_sck_get_recv_buffer_bytes(ltrans->sck, &bytes) != 0) - { - LOG(LOG_LEVEL_WARNING, "error getting recv " - "buffer"); - } - else - { - LOG(LOG_LEVEL_INFO, "recv buffer set to %d " - "bytes", bytes); - } + LOG(LOG_LEVEL_INFO, "recv buffer set to %d bytes", bytes); } } }