[PATCH v3] ws2_32:Succeed IPV6_V6ONLY setsockopt for AF_INET sockets ignoring it
Anton Romanov
theli.ua at gmail.com
Thu Jan 12 11:03:26 CST 2017
Fixes https://bugs.winehq.org/show_bug.cgi?id=42194
(Magic The Gathering Online not able to login)
Signed-off-by: Anton Romanov <theli.ua at gmail.com>
---
dlls/ws2_32/socket.c | 25 +++++++++++++++++++++++-
dlls/ws2_32/tests/sock.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 73 insertions(+), 2 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 6bf3c9da93..8e45a1a7f6 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -6016,7 +6016,6 @@ int WINAPI WS_setsockopt(SOCKET s, int level, int optname,
case WS_IPV6_MULTICAST_HOPS:
case WS_IPV6_MULTICAST_LOOP:
case WS_IPV6_UNICAST_HOPS:
- case WS_IPV6_V6ONLY:
#ifdef IPV6_UNICAST_IF
case WS_IPV6_UNICAST_IF:
#endif
@@ -6027,6 +6026,30 @@ int WINAPI WS_setsockopt(SOCKET s, int level, int optname,
case WS_IPV6_PROTECTION_LEVEL:
FIXME("IPV6_PROTECTION_LEVEL is ignored!\n");
return 0;
+ case WS_IPV6_V6ONLY:
+ {
+ union generic_unix_sockaddr uaddr;
+ socklen_t uaddrlen;
+ int bound;
+
+ fd = get_sock_fd( s, 0, NULL );
+ if (fd == -1) return SOCKET_ERROR;
+
+ bound = is_fd_bound(fd, &uaddr, &uaddrlen);
+ release_sock_fd( s, fd );
+ if (uaddr.addr.sa_family == AF_INET && bound == 0)
+ {
+ /* Changing IPV6_V6ONLY succeeds on AF_INET (IPv4) socket
+ * on Windows (with IPv6 support) if the socket is unbound.
+ * It is essentially a noop, though Windows does store the value
+ */
+ FIXME("Silently ignoring IPPROTO_IPV6+IPV6_V6ONLY on AF_INET socket\n");
+ return 0;
+ }
+ level = IPPROTO_IPV6;
+ optname = IPV6_V6ONLY;
+ break;
+ }
default:
FIXME("Unknown IPPROTO_IPV6 optname 0x%08x\n", optname);
return SOCKET_ERROR;
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index ba755a5d2f..585671823c 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -6189,12 +6189,60 @@ static void test_ipv6only(void)
}
v4 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- ok(v4 != INVALID_SOCKET, "Could not create IPv6 socket (LastError: %d)\n", WSAGetLastError());
+ ok(v4 != INVALID_SOCKET, "Could not create IPv4 socket (LastError: %d)\n", WSAGetLastError());
+
+todo_wine {
+ enabled = 2;
+ ret = getsockopt(v4, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, &len);
+ ok(!ret, "getsockopt(IPV6_ONLY) failed (LastError: %d)\n", WSAGetLastError());
+ ok(enabled == 1, "expected 1, got %d\n", enabled);
+}
+
+ enabled = 0;
+ len = sizeof(enabled);
+ ret = setsockopt(v4, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, len);
+ ok(!ret, "setsockopt(IPV6_ONLY) failed (LastError: %d)\n", WSAGetLastError());
+
+todo_wine {
+ enabled = 2;
+ ret = getsockopt(v4, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, &len);
+ ok(!ret, "getsockopt(IPV6_ONLY) failed (LastError: %d)\n", WSAGetLastError());
+ ok(!enabled, "expected 0, got %d\n", enabled);
+}
+
+ enabled = 1;
+ len = sizeof(enabled);
+ ret = setsockopt(v4, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, len);
+ ok(!ret, "setsockopt(IPV6_ONLY) failed (LastError: %d)\n", WSAGetLastError());
/* bind on IPv4 socket should succeed - IPV6_V6ONLY is enabled by default */
ret = bind(v4, (struct sockaddr*)&sin4, sizeof(sin4));
ok(!ret, "Could not bind IPv4 address (LastError: %d)\n", WSAGetLastError());
+todo_wine {
+ enabled = 2;
+ ret = getsockopt(v4, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, &len);
+ ok(!ret, "getsockopt(IPV6_ONLY) failed (LastError: %d)\n", WSAGetLastError());
+ ok(enabled == 1, "expected 1, got %d\n", enabled);
+}
+
+ enabled = 0;
+ len = sizeof(enabled);
+ ret = setsockopt(v4, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, len);
+ ok(ret, "setsockopt(IPV6_ONLY) succeeded (LastError: %d)\n", WSAGetLastError());
+
+todo_wine {
+ enabled = 0;
+ ret = getsockopt(v4, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, &len);
+ ok(!ret, "getsockopt(IPV6_ONLY) failed (LastError: %d)\n", WSAGetLastError());
+ ok(enabled == 1, "expected 1, got %d\n", enabled);
+}
+
+ enabled = 1;
+ len = sizeof(enabled);
+ ret = setsockopt(v4, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, len);
+ ok(ret, "setsockopt(IPV6_ONLY) succeeded (LastError: %d)\n", WSAGetLastError());
+
closesocket(v4);
closesocket(v6);
--
2.11.0
More information about the wine-patches
mailing list