From 7f610a2c6e57cbc48f9c0bdfa6e39f9b2068e586 Mon Sep 17 00:00:00 2001 From: Fabio Alessandrelli Date: Wed, 7 Aug 2024 09:43:34 +0200 Subject: [PATCH] [WS] Fix set_no_delay on Windows Windows socket implementation is, as usual, broken in many ways. This includes `setsockopt` failing to set `TCP_NODELAY` if the socket is still in a connecting state. This also means we need to keep polling the IP resolver until the socket reaches the CONNECTED state (so it can set the TCP_NODELAY after the connection is successful). --- modules/websocket/wsl_peer.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/websocket/wsl_peer.cpp b/modules/websocket/wsl_peer.cpp index 3c63aa4fbfd5..0a9a4053e3a4 100644 --- a/modules/websocket/wsl_peer.cpp +++ b/modules/websocket/wsl_peer.cpp @@ -99,6 +99,8 @@ void WSLPeer::Resolver::try_next_candidate(Ref &p_tcp) { p_tcp->poll(); StreamPeerTCP::Status status = p_tcp->get_status(); if (status == StreamPeerTCP::STATUS_CONNECTED) { + // On Windows, setting TCP_NODELAY may fail if the socket is still connecting. + p_tcp->set_no_delay(true); ip_candidates.clear(); return; } else if (status == StreamPeerTCP::STATUS_CONNECTING) { @@ -112,7 +114,6 @@ void WSLPeer::Resolver::try_next_candidate(Ref &p_tcp) { while (ip_candidates.size()) { Error err = p_tcp->connect_to_host(ip_candidates.pop_front(), port); if (err == OK) { - p_tcp->set_no_delay(true); return; } else { p_tcp->disconnect_from_host(); @@ -311,7 +312,7 @@ void WSLPeer::_do_client_handshake() { ERR_FAIL_COND(tcp.is_null()); // Try to connect to candidates. - if (resolver.has_more_candidates()) { + if (resolver.has_more_candidates() || tcp->get_status() == StreamPeerTCP::STATUS_CONNECTING) { resolver.try_next_candidate(tcp); if (resolver.has_more_candidates()) { return; // Still pending.