Anton Romanov : ws2_32: Ignore IPV6_V6ONLY setsockopt for AF_INET sockets.
Alexandre Julliard
julliard at winehq.org
Thu Jan 12 14:45:44 CST 2017
Module: wine
Branch: master
Commit: 531dcf2dd3b1c5e9848afce422a6e0f2ee497597
URL: http://source.winehq.org/git/wine.git/?a=commit;h=531dcf2dd3b1c5e9848afce422a6e0f2ee497597
Author: Anton Romanov <theli.ua at gmail.com>
Date: Wed Jan 11 21:27:08 2017 -0800
ws2_32: Ignore IPV6_V6ONLY setsockopt for AF_INET sockets.
Signed-off-by: Anton Romanov <theli.ua at gmail.com>
Signed-off-by: Bruno Jesus <00cpxxx at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
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 6bf3c9d..4977bbf 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 (bound == 0 && uaddr.addr.sa_family == AF_INET)
+ {
+ /* 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
+ */
+ WARN("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 ba755a5..5856718 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);
More information about the wine-cvs
mailing list