Zebediah Figura : ws2_32: Set default socket options in the server.

Alexandre Julliard julliard at winehq.org
Thu Oct 1 15:50:30 CDT 2020


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

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Wed Sep 30 10:37:51 2020 -0500

ws2_32: Set default socket options in the server.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ws2_32/socket.c | 39 -------------------------------
 server/sock.c        | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+), 39 deletions(-)

diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index d7802cc9cd..a187d2de8e 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -7519,7 +7519,6 @@ SOCKET WINAPI WSASocketW(int af, int type, int protocol,
     HANDLE handle;
     SOCKET ret;
     DWORD err;
-    int unixaf, unixtype, ipxptype = -1;
 
    /*
       FIXME: The "advanced" parameters of WSASocketW (lpProtocolInfo,
@@ -7590,18 +7589,6 @@ SOCKET WINAPI WSASocketW(int af, int type, int protocol,
         }
     }
 
-    /*
-       Windows has an extension to the IPX protocol that allows one to create sockets
-       and set the IPX packet type at the same time, to do that a caller will use
-       a protocol like NSPROTO_IPX + <PACKET TYPE>
-    */
-    if (IS_IPX_PROTO(protocol))
-        ipxptype = protocol - WS_NSPROTO_IPX;
-
-    /* convert the socket family, type and protocol */
-    unixaf = convert_af_w2u(af);
-    unixtype = convert_socktype_w2u(type);
-
     RtlInitUnicodeString(&string, afdW);
     InitializeObjectAttributes(&attr, &string, (flags & WSA_FLAG_NO_HANDLE_INHERIT) ? 0 : OBJ_INHERIT, NULL, NULL);
     if ((status = NtOpenFile(&handle, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, &attr,
@@ -7636,32 +7623,6 @@ SOCKET WINAPI WSASocketW(int af, int type, int protocol,
     ret = HANDLE2SOCKET(handle);
     TRACE("\tcreated %04lx\n", ret );
 
-    if (ipxptype > 0)
-        set_ipx_packettype(ret, ipxptype);
-
-    if (unixaf == AF_INET || unixaf == AF_INET6)
-    {
-        /* ensure IP_DONTFRAGMENT is disabled for SOCK_DGRAM and SOCK_RAW, enabled for SOCK_STREAM */
-        if (unixtype == SOCK_DGRAM || unixtype == SOCK_RAW) /* in Linux the global default can be enabled */
-            set_dont_fragment(ret, unixaf == AF_INET6 ? IPPROTO_IPV6 : IPPROTO_IP, FALSE);
-        else if (unixtype == SOCK_STREAM)
-            set_dont_fragment(ret, unixaf == AF_INET6 ? IPPROTO_IPV6 : IPPROTO_IP, TRUE);
-    }
-
-#ifdef IPV6_V6ONLY
-    if (unixaf == AF_INET6)
-    {
-        int fd = get_sock_fd(ret, 0, NULL);
-        if (fd != -1)
-        {
-            /* IPV6_V6ONLY is set by default on Windows */
-            int enable = 1;
-            if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &enable, sizeof(enable)))
-                WARN("\tsetting IPV6_V6ONLY failed - errno = %i\n", errno);
-            release_sock_fd(ret, fd);
-        }
-    }
-#endif
     if (!socket_list_add(ret))
     {
         CloseHandle(handle);
diff --git a/server/sock.c b/server/sock.c
index f0227c5906..52e85b1e51 100644
--- a/server/sock.c
+++ b/server/sock.c
@@ -712,6 +712,36 @@ static int get_unix_protocol( int protocol )
     }
 }
 
+static void set_dont_fragment( int fd, int level, int value )
+{
+    int optname;
+
+    if (level == IPPROTO_IP)
+    {
+#ifdef IP_DONTFRAG
+        optname = IP_DONTFRAG;
+#elif defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO) && defined(IP_PMTUDISC_DONT)
+        optname = IP_MTU_DISCOVER;
+        value = value ? IP_PMTUDISC_DO : IP_PMTUDISC_DONT;
+#else
+        return;
+#endif
+    }
+    else
+    {
+#ifdef IPV6_DONTFRAG
+        optname = IPV6_DONTFRAG;
+#elif defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO) && defined(IPV6_PMTUDISC_DONT)
+        optname = IPV6_MTU_DISCOVER;
+        value = value ? IPV6_PMTUDISC_DO : IPV6_PMTUDISC_DONT;
+#else
+        return;
+#endif
+    }
+
+    setsockopt( fd, level, optname, &value, sizeof(value) );
+}
+
 static int init_socket( struct sock *sock, int family, int type, int protocol, unsigned int flags )
 {
     unsigned int options = 0;
@@ -746,6 +776,41 @@ static int init_socket( struct sock *sock, int family, int type, int protocol, u
         return -1;
     }
     fcntl(sockfd, F_SETFL, O_NONBLOCK); /* make socket nonblocking */
+
+    if (family == WS_AF_IPX && protocol >= WS_NSPROTO_IPX && protocol <= WS_NSPROTO_IPX + 255)
+    {
+#ifdef HAS_IPX
+        int ipx_type = protocol - WS_NSPROTO_IPX;
+
+#ifdef SOL_IPX
+        setsockopt( sockfd, SOL_IPX, IPX_TYPE, &ipx_type, sizeof(ipx_type) );
+#else
+        struct ipx val;
+        /* Should we retrieve val using a getsockopt call and then
+         * set the modified one? */
+        val.ipx_pt = ipx_type;
+        setsockopt( sockfd, 0, SO_DEFAULT_HEADERS, &val, sizeof(val) );
+#endif
+#endif
+    }
+
+    if (unix_family == AF_INET || unix_family == AF_INET6)
+    {
+        /* ensure IP_DONTFRAGMENT is disabled for SOCK_DGRAM and SOCK_RAW, enabled for SOCK_STREAM */
+        if (unix_type == SOCK_DGRAM || unix_type == SOCK_RAW) /* in Linux the global default can be enabled */
+            set_dont_fragment( sockfd, unix_family == AF_INET6 ? IPPROTO_IPV6 : IPPROTO_IP, FALSE );
+        else if (unix_type == SOCK_STREAM)
+            set_dont_fragment( sockfd, unix_family == AF_INET6 ? IPPROTO_IPV6 : IPPROTO_IP, TRUE );
+    }
+
+#ifdef IPV6_V6ONLY
+    if (unix_family == AF_INET6)
+    {
+        static const int enable = 1;
+        setsockopt( sockfd, IPPROTO_IPV6, IPV6_V6ONLY, &enable, sizeof(enable) );
+    }
+#endif
+
     sock->state  = (type != SOCK_STREAM) ? (FD_READ|FD_WRITE) : 0;
     sock->flags  = flags;
     sock->proto  = unix_protocol;




More information about the wine-cvs mailing list