From 2e5de43564bdaf348b65166b9b2de99dba470708 Mon Sep 17 00:00:00 2001 From: akallabeth Date: Fri, 12 Sep 2025 09:39:24 +0200 Subject: [PATCH] [core,tcp] unify setting of TCP_NODELAY --- libfreerdp/core/peer.c | 32 +--------------------------- libfreerdp/core/tcp.c | 48 ++++++++++++++++++++++++++++++++++++------ libfreerdp/core/tcp.h | 2 ++ 3 files changed, 44 insertions(+), 38 deletions(-) diff --git a/libfreerdp/core/peer.c b/libfreerdp/core/peer.c index 1b9ca700b..cd456b9c7 100644 --- a/libfreerdp/core/peer.c +++ b/libfreerdp/core/peer.c @@ -1443,44 +1443,14 @@ const char* freerdp_peer_os_minor_type_string(freerdp_peer* client) freerdp_peer* freerdp_peer_new(int sockfd) { - UINT32 option_value = 0; - socklen_t option_len = 0; freerdp_peer* client = (freerdp_peer*)calloc(1, sizeof(freerdp_peer)); if (!client) return NULL; - option_value = TRUE; - option_len = sizeof(option_value); - if (sockfd >= 0) { - int type = -1; - socklen_t typelen = sizeof(type); - const int rc = getsockopt(sockfd, SOL_SOCKET, SO_TYPE, &type, &typelen); - if (rc < 0) - { - char buffer[128] = { 0 }; - WLog_DBG(TAG, "can't get SOL_SOCKET|SO_TYPE, continuing anyway (%s)", - winpr_strerror(errno, buffer, sizeof(buffer))); - } - else if (type == SOCK_STREAM) - { - const int sr = - setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (void*)&option_value, option_len); - if (sr < 0) - { - /* local unix sockets don't have the TCP_NODELAY implemented, so don't make this - * error fatal */ - char buffer[128] = { 0 }; - WLog_DBG(TAG, "can't set TCP_NODELAY, continuing anyway (%s)", - winpr_strerror(errno, buffer, sizeof(buffer))); - } - } - else - { - WLog_DBG(TAG, "Socket SOL_SOCKET|SO_TYPE %d unsupported, continuing anyway", type); - } + (void)freerdp_tcp_set_nodelay(WLog_Get(TAG), WLOG_DEBUG, sockfd); } if (client) diff --git a/libfreerdp/core/tcp.c b/libfreerdp/core/tcp.c index f76081daa..b2e5544c6 100644 --- a/libfreerdp/core/tcp.c +++ b/libfreerdp/core/tcp.c @@ -1115,8 +1115,6 @@ int freerdp_tcp_default_connect(rdpContext* context, rdpSettings* settings, cons int port, DWORD timeout) { int sockfd = 0; - UINT32 optval = 0; - socklen_t optlen = 0; BOOL ipcSocket = FALSE; BOOL useExternalDefinedSocket = FALSE; @@ -1287,16 +1285,14 @@ int freerdp_tcp_default_connect(rdpContext* context, rdpSettings* settings, cons } } - optval = 1; - optlen = sizeof(optval); - if (!ipcSocket && !useExternalDefinedSocket) { - if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (void*)&optval, optlen) < 0) - WLog_ERR(TAG, "unable to set TCP_NODELAY"); + (void)freerdp_tcp_set_nodelay(WLog_Get(TAG), WLOG_ERROR, sockfd); } /* receive buffer must be a least 32 K */ + UINT32 optval = 0; + socklen_t optlen = 0; if (getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (void*)&optval, &optlen) == 0) { if (optval < (1024 * 32)) @@ -1512,3 +1508,41 @@ fail: transport_layer_free(layer); return NULL; } + +BOOL freerdp_tcp_set_nodelay(wLog* log, DWORD level, int sockfd) +{ + WINPR_ASSERT(log); + + int type = -1; + socklen_t typelen = sizeof(type); + const int rc = getsockopt(sockfd, SOL_SOCKET, SO_TYPE, &type, &typelen); + if (rc < 0) + { + char buffer[128] = { 0 }; + WLog_Print(log, level, "can't get SOL_SOCKET|SO_TYPE (%s)", + winpr_strerror(errno, buffer, sizeof(buffer))); + return FALSE; + } + else if (type == SOCK_STREAM) + { + int option_value = -1; + const socklen_t option_len = sizeof(option_value); + const int sr = + setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (void*)&option_value, option_len); + if (sr < 0) + { + /* local unix sockets don't have the TCP_NODELAY implemented, so don't make this + * error fatal */ + char buffer[128] = { 0 }; + WLog_Print(log, level, "can't set TCP_NODELAY (%s)", + winpr_strerror(errno, buffer, sizeof(buffer))); + return FALSE; + } + } + else + { + WLog_Print(log, level, "Socket SOL_SOCKET|SO_TYPE %d unsupported", type); + return FALSE; + } + return TRUE; +} diff --git a/libfreerdp/core/tcp.h b/libfreerdp/core/tcp.h index 21a0dcf41..7512d932d 100644 --- a/libfreerdp/core/tcp.h +++ b/libfreerdp/core/tcp.h @@ -112,4 +112,6 @@ FREERDP_LOCAL struct addrinfo* freerdp_tcp_resolve_host(const char* hostname, in int ai_flags); FREERDP_LOCAL char* freerdp_tcp_address_to_string(const struct sockaddr_storage* addr, BOOL* pIPv6); +FREERDP_LOCAL BOOL freerdp_tcp_set_nodelay(wLog* log, DWORD level, int sockfd); + #endif /* FREERDP_LIB_CORE_TCP_H */