Signed-off-by: Zebediah Figura z.figura12@gmail.com --- v2: remove diagnostic messages
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 d7802cc9cd8..a187d2de8e7 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 f0227c59067..52e85b1e518 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;