Zebediah Figura : ws2_32: Move the getsockopt(IPV6_DONTFRAG) implementation to ntdll.

Alexandre Julliard julliard at winehq.org
Wed Jul 28 15:37:42 CDT 2021


Module: wine
Branch: master
Commit: a615e67792bd5edcf0577f6e176f7095253c558f
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=a615e67792bd5edcf0577f6e176f7095253c558f

Author: Zebediah Figura <zfigura at codeweavers.com>
Date:   Wed Jul 28 10:17:06 2021 -0500

ws2_32: Move the getsockopt(IPV6_DONTFRAG) implementation to ntdll.

Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/unix/socket.c | 33 +++++++++++++++++++++++++++
 dlls/ws2_32/socket.c     | 59 +++---------------------------------------------
 include/wine/afd.h       |  1 +
 3 files changed, 37 insertions(+), 56 deletions(-)

diff --git a/dlls/ntdll/unix/socket.c b/dlls/ntdll/unix/socket.c
index f0dc00a9651..fbfd873b3b9 100644
--- a/dlls/ntdll/unix/socket.c
+++ b/dlls/ntdll/unix/socket.c
@@ -1807,6 +1807,39 @@ NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc
             return do_setsockopt( handle, io, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, in_buffer, in_size );
 #endif
 
+        case IOCTL_AFD_WINE_GET_IPV6_DONTFRAG:
+        {
+            socklen_t len = out_size;
+            int ret;
+
+            if ((status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL )))
+                return status;
+
+#ifdef IPV6_DONTFRAG
+            ret = getsockopt( fd, IPPROTO_IPV6, IPV6_DONTFRAG, out_buffer, &len );
+#elif defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DONT)
+            {
+                int value;
+
+                len = sizeof(value);
+                ret = getsockopt( fd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &value, &len );
+                if (!ret) *(DWORD *)out_buffer = (value != IPV6_PMTUDISC_DONT);
+            }
+#else
+            {
+                static int once;
+
+                if (!once++)
+                    FIXME( "IPV6_DONTFRAGMENT is not supported on this platform\n" );
+                ret = 0; /* fake success */
+            }
+#endif
+            if (needs_close) close( fd );
+            if (ret) return sock_errno_to_status( errno );
+            io->Information = len;
+            return STATUS_SUCCESS;
+        }
+
         default:
         {
             if ((code >> 16) == FILE_DEVICE_NETWORK)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index f02d668ece4..837e8021248 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -742,60 +742,6 @@ static BOOL set_dont_fragment(SOCKET s, int level, BOOL value)
     return value;
 }
 
-static BOOL get_dont_fragment(SOCKET s, int level, BOOL *out)
-{
-    int fd, optname, value, not_expected;
-    socklen_t optlen = sizeof(value);
-
-    if (level == IPPROTO_IP)
-    {
-#ifdef IP_DONTFRAG
-        optname = IP_DONTFRAG;
-        not_expected = 0;
-#elif defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
-        optname = IP_MTU_DISCOVER;
-        not_expected = IP_PMTUDISC_DONT;
-#else
-        static int once;
-        if (!once++)
-            FIXME("IP_DONTFRAGMENT for IPv4 not supported in this platform\n");
-        return TRUE; /* fake success */
-#endif
-    }
-    else
-    {
-#ifdef IPV6_DONTFRAG
-        optname = IPV6_DONTFRAG;
-        not_expected = 0;
-#elif defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DONT)
-        optname = IPV6_MTU_DISCOVER;
-        not_expected = IPV6_PMTUDISC_DONT;
-#else
-        static int once;
-        if (!once++)
-            FIXME("IP_DONTFRAGMENT for IPv6 not supported in this platform\n");
-        return TRUE; /* fake success */
-#endif
-    }
-
-    fd = get_sock_fd(s, 0, NULL);
-    if (fd == -1) return FALSE;
-
-    if (!getsockopt(fd, level, optname, &value, &optlen))
-    {
-        *out = value != not_expected;
-        value = TRUE;
-    }
-    else
-    {
-        WSASetLastError(wsaErrno());
-        value = FALSE;
-    }
-
-    release_sock_fd(s, fd);
-    return value;
-}
-
 struct per_thread_data *get_per_thread_data(void)
 {
     struct per_thread_data * ptb = NtCurrentTeb()->WinSockData;
@@ -2511,6 +2457,9 @@ INT WINAPI WS_getsockopt(SOCKET s, INT level,
     case WS_IPPROTO_IPV6:
         switch(optname)
         {
+        case WS_IPV6_DONTFRAG:
+            return server_getsockopt( s, IOCTL_AFD_WINE_GET_IPV6_DONTFRAG, optval, optlen );
+
         case WS_IPV6_MULTICAST_IF:
         case WS_IPV6_MULTICAST_HOPS:
         case WS_IPV6_MULTICAST_LOOP:
@@ -2529,8 +2478,6 @@ INT WINAPI WS_getsockopt(SOCKET s, INT level,
             }
             release_sock_fd( s, fd );
             return ret;
-        case WS_IPV6_DONTFRAG:
-            return get_dont_fragment(s, IPPROTO_IPV6, (BOOL *)optval) ? 0 : SOCKET_ERROR;
 
         default:
             FIXME( "unrecognized IPv6 option %u\n", optname );
diff --git a/include/wine/afd.h b/include/wine/afd.h
index dda07695f75..bb8fd68f059 100644
--- a/include/wine/afd.h
+++ b/include/wine/afd.h
@@ -208,6 +208,7 @@ struct afd_get_events_params
 #define IOCTL_AFD_WINE_GET_IP_UNICAST_IF                WINE_AFD_IOC(263)
 #define IOCTL_AFD_WINE_SET_IP_UNICAST_IF                WINE_AFD_IOC(264)
 #define IOCTL_AFD_WINE_SET_IPV6_ADD_MEMBERSHIP          WINE_AFD_IOC(265)
+#define IOCTL_AFD_WINE_GET_IPV6_DONTFRAG                WINE_AFD_IOC(266)
 
 struct afd_create_params
 {




More information about the wine-cvs mailing list