From: Viktor Szakats Date: Tue, 2 Dec 2025 16:45:18 +0000 (+0100) Subject: sws: fix binding to unix socket on Windows X-Git-Tag: rc-8_18_0-1~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f97e62ff147feff09e1a29a2db6b4a7f928d75a0;p=thirdparty%2Fcurl.git sws: fix binding to unix socket on Windows Windows 10.17063+ (having unix socket support) fails to set for unix sockets the `SO_REUSEADDR` option, with error 10045 (`WSAEOPNOTSUPP`), and also fails to set `SO_KEEPALIVE` with error 10042 (`WSAENOPROTOOPT`). Fix by not enabling these socket options on Windows for unix sockets. Also: - fixing test 1435, 1436 to run in CI. - fixing the `socksd` test server for test 1467, 1468, 1470. But, also disable these for now due to another Windows issue: #19825 Ref: https://stackoverflow.com/questions/68791319/unix-domain-socket-bind-failed-in-windows/68794755#68794755 Ref: #19810 Closes #19812 --- diff --git a/tests/data/test1467 b/tests/data/test1467 index 69b04d8bf4..46cb69059b 100644 --- a/tests/data/test1467 +++ b/tests/data/test1467 @@ -30,9 +30,11 @@ Funny-head: yesyes # # Client-side +# --socks5 cannot accept Windows absolute paths proxy UnixSockets +!win32 http diff --git a/tests/data/test1468 b/tests/data/test1468 index 7cb9b13456..1ed654adcc 100644 --- a/tests/data/test1468 +++ b/tests/data/test1468 @@ -31,9 +31,11 @@ Funny-head: yesyes # # Client-side +# --socks5h cannot accept Windows absolute paths proxy UnixSockets +!win32 http diff --git a/tests/data/test1470 b/tests/data/test1470 index c93af27f7d..691fcc9a44 100644 --- a/tests/data/test1470 +++ b/tests/data/test1470 @@ -32,9 +32,11 @@ Funny-head: yesyes # # Client-side +# --proxy cannot accept Windows absolute paths proxy UnixSockets +!win32 https diff --git a/tests/server/sws.c b/tests/server/sws.c index 56135a8326..c7ce249224 100644 --- a/tests/server/sws.c +++ b/tests/server/sws.c @@ -1863,14 +1863,20 @@ static curl_socket_t accept_connection(curl_socket_t sock) return CURL_SOCKET_BAD; } - if(setsockopt(msgsock, SOL_SOCKET, SO_KEEPALIVE, - (void *)&flag, sizeof(flag))) { - error = SOCKERRNO; - logmsg("setsockopt(SO_KEEPALIVE) failed with error (%d) %s", - error, curlx_strerror(error, errbuf, sizeof(errbuf))); - sclose(msgsock); - return CURL_SOCKET_BAD; +#if defined(_WIN32) && defined(USE_UNIX_SOCKETS) + if(socket_domain != AF_UNIX) { +#endif + if(setsockopt(msgsock, SOL_SOCKET, SO_KEEPALIVE, + (void *)&flag, sizeof(flag))) { + error = SOCKERRNO; + logmsg("setsockopt(SO_KEEPALIVE) failed with error (%d) %s", + error, curlx_strerror(error, errbuf, sizeof(errbuf))); + sclose(msgsock); + return CURL_SOCKET_BAD; + } +#if defined(_WIN32) && defined(USE_UNIX_SOCKETS) } +#endif /* ** As soon as this server accepts a connection from the test harness it @@ -2176,13 +2182,20 @@ static int test_sws(int argc, char *argv[]) goto sws_cleanup; } - flag = 1; - if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&flag, sizeof(flag))) { - error = SOCKERRNO; - logmsg("setsockopt(SO_REUSEADDR) failed with error (%d) %s", - error, curlx_strerror(error, errbuf, sizeof(errbuf))); - goto sws_cleanup; +#if defined(_WIN32) && defined(USE_UNIX_SOCKETS) + if(socket_domain != AF_UNIX) { +#endif + flag = 1; + if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, + (void *)&flag, sizeof(flag))) { + error = SOCKERRNO; + logmsg("setsockopt(SO_REUSEADDR) failed with error (%d) %s", + error, curlx_strerror(error, errbuf, sizeof(errbuf))); + goto sws_cleanup; + } +#if defined(_WIN32) && defined(USE_UNIX_SOCKETS) } +#endif if(curlx_nonblock(sock, TRUE)) { error = SOCKERRNO; logmsg("curlx_nonblock failed with error (%d) %s", diff --git a/tests/server/util.c b/tests/server/util.c index 624826571a..b021aa43dc 100644 --- a/tests/server/util.c +++ b/tests/server/util.c @@ -763,42 +763,48 @@ curl_socket_t sockdaemon(curl_socket_t sock, (void)unix_socket; #endif - do { - attempt++; - flag = 1; - rc = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, - (void *)&flag, sizeof(flag)); - if(rc) { - error = SOCKERRNO; - logmsg("setsockopt(SO_REUSEADDR) failed with error (%d) %s", - error, curlx_strerror(error, errbuf, sizeof(errbuf))); - if(maxretr) { - rc = curlx_wait_ms(delay); - if(rc) { - /* should not happen */ - error = SOCKERRNO; - logmsg("curlx_wait_ms() failed with error (%d) %s", - error, curlx_strerror(error, errbuf, sizeof(errbuf))); - sclose(sock); - return CURL_SOCKET_BAD; - } - if(got_exit_signal) { - logmsg("signalled to die, exiting..."); - sclose(sock); - return CURL_SOCKET_BAD; +#if defined(_WIN32) && defined(USE_UNIX_SOCKETS) + if(socket_domain != AF_UNIX) { +#endif + do { + attempt++; + flag = 1; + rc = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, + (void *)&flag, sizeof(flag)); + if(rc) { + error = SOCKERRNO; + logmsg("setsockopt(SO_REUSEADDR) failed with error (%d) %s", + error, curlx_strerror(error, errbuf, sizeof(errbuf))); + if(maxretr) { + rc = curlx_wait_ms(delay); + if(rc) { + /* should not happen */ + error = SOCKERRNO; + logmsg("curlx_wait_ms() failed with error (%d) %s", + error, curlx_strerror(error, errbuf, sizeof(errbuf))); + sclose(sock); + return CURL_SOCKET_BAD; + } + if(got_exit_signal) { + logmsg("signalled to die, exiting..."); + sclose(sock); + return CURL_SOCKET_BAD; + } + totdelay += delay; + delay *= 2; /* double the sleep for next attempt */ } - totdelay += delay; - delay *= 2; /* double the sleep for next attempt */ } - } - } while(rc && maxretr--); + } while(rc && maxretr--); - if(rc) { - logmsg("setsockopt(SO_REUSEADDR) failed %d times in %d ms. Error (%d) %s", - attempt, totdelay, - error, curlx_strerror(error, errbuf, sizeof(errbuf))); - logmsg("Continuing anyway..."); + if(rc) { + logmsg("setsockopt(SO_REUSEADDR) failed %d times in %d ms. " + "Error (%d) %s", attempt, totdelay, + error, curlx_strerror(error, errbuf, sizeof(errbuf))); + logmsg("Continuing anyway..."); + } +#if defined(_WIN32) && defined(USE_UNIX_SOCKETS) } +#endif /* When the specified listener port is zero, it is actually a request to let the system choose a non-zero available port. */