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