From f438ce099b15d433c2bbd0e1ddc8ab17ef924d76 Mon Sep 17 00:00:00 2001 From: Jay Satiro Date: Tue, 7 Feb 2023 03:14:34 -0500 Subject: [PATCH] multi: stop sending empty HTTP/3 UDP datagrams on Windows MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit - Limit the 0-sized send procedure that is used to reset a SOCKET's FD_WRITE to TCP sockets only. Prior to this change the reset was used on UDP sockets as well, but unlike TCP sockets a 0-sized send actually sends out a datagram. Assisted-by: Marc Hörsken Ref: https://github.com/curl/curl/pull/9203 Fixes https://github.com/curl/curl/issues/9086 Closes https://github.com/curl/curl/pull/10430 --- lib/multi.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/multi.c b/lib/multi.c index 403274814b..f020a0b64a 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -1110,6 +1110,22 @@ CURLMcode curl_multi_fdset(struct Curl_multi *multi, return CURLM_OK; } +#ifdef USE_WINSOCK +/* Reset FD_WRITE for TCP sockets. Nothing is actually sent. UDP sockets can't + * be reset this way because an empty datagram would be sent. #9203 + * + * "On Windows the internal state of FD_WRITE as returned from + * WSAEnumNetworkEvents is only reset after successful send()." + */ +static void reset_socket_fdwrite(curl_socket_t s) +{ + int t; + int l = (int)sizeof(t); + if(!getsockopt(s, SOL_SOCKET, SO_TYPE, (char *)&t, &l) && t == SOCK_STREAM) + send(s, NULL, 0, 0); +} +#endif + #define NUM_POLLS_ON_STACK 10 static CURLMcode multi_wait(struct Curl_multi *multi, @@ -1231,7 +1247,7 @@ static CURLMcode multi_wait(struct Curl_multi *multi, s = sockbunch[i]; #ifdef USE_WINSOCK mask |= FD_WRITE|FD_CONNECT|FD_CLOSE; - send(s, NULL, 0, 0); /* reset FD_WRITE */ + reset_socket_fdwrite(s); #endif ufds[nfds].fd = s; ufds[nfds].events = POLLOUT; @@ -1265,7 +1281,7 @@ static CURLMcode multi_wait(struct Curl_multi *multi, mask |= FD_OOB; if(extra_fds[i].events & CURL_WAIT_POLLOUT) { mask |= FD_WRITE|FD_CONNECT|FD_CLOSE; - send(extra_fds[i].fd, NULL, 0, 0); /* reset FD_WRITE */ + reset_socket_fdwrite(extra_fds[i].fd); } if(WSAEventSelect(extra_fds[i].fd, multi->wsa_event, mask) != 0) { if(ufds_malloc) -- 2.47.3