]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
sws: fix binding to unix socket on Windows
authorViktor Szakats <commit@vsz.me>
Tue, 2 Dec 2025 16:45:18 +0000 (17:45 +0100)
committerViktor Szakats <commit@vsz.me>
Thu, 4 Dec 2025 21:49:03 +0000 (22:49 +0100)
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

tests/data/test1467
tests/data/test1468
tests/data/test1470
tests/server/sws.c
tests/server/util.c

index 69b04d8bf485816502c56d1a9a084c83343c701b..46cb69059ba51f6c04922da8532da4276ff63761 100644 (file)
@@ -30,9 +30,11 @@ Funny-head: yesyes
 #
 # Client-side
 <client>
+# --socks5 cannot accept Windows absolute paths
 <features>
 proxy
 UnixSockets
+!win32
 </features>
 <server>
 http
index 7cb9b13456295abc7a0a32c4d3727a7bb2a00149..1ed654adcc8a5590d85e00f6d97746cfc02bf63c 100644 (file)
@@ -31,9 +31,11 @@ Funny-head: yesyes
 #
 # Client-side
 <client>
+# --socks5h cannot accept Windows absolute paths
 <features>
 proxy
 UnixSockets
+!win32
 </features>
 <server>
 http
index c93af27f7db34be24a55dc52cd67e001817decb9..691fcc9a44cc367236d8b91410d7c39af1a0c144 100644 (file)
@@ -32,9 +32,11 @@ Funny-head: yesyes
 #
 # Client-side
 <client>
+# --proxy cannot accept Windows absolute paths
 <features>
 proxy
 UnixSockets
+!win32
 </features>
 <server>
 https
index 56135a8326363cd150418f282a0dff5e34ded8eb..c7ce24922418a78d2b4371ec3f450e565b4ae858 100644 (file)
@@ -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",
index 624826571a9f1ac6e1653318f4456bf52d458f39..b021aa43dc91b7b09afcdf93112f6e6d6897ed47 100644 (file)
@@ -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. */