[PATCH] ws2_32: Allow user to enable IP dual stack (v3)
Matthieu Nottale
matthieu.nottale at infinit.io
Tue Jul 5 08:33:59 CDT 2016
IP dual stack (v4+v6) should be disabled by default, but previous code
was setting IPV6_V6ONLY in bind() which prevented user to override it.
This patch moves setting IPV6_V6ONLY to socket creation time.
Signed-off-by: Matthieu Nottale <matthieu.nottale at infinit.io>
---
dlls/ws2_32/socket.c | 22 ++++++++-------------
dlls/ws2_32/tests/sock.c | 51
++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 59 insertions(+), 14 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index b0af3d7..1770d25 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -3240,20 +3240,6 @@ int WINAPI WS_bind(SOCKET s, const struct
WS_sockaddr* name, int namelen)
}
else
{
-#ifdef IPV6_V6ONLY
- const struct sockaddr_in6 *in6 = (const struct
sockaddr_in6*) &uaddr;
- if (name->sa_family == WS_AF_INET6 &&
- !memcmp(&in6->sin6_addr, &in6addr_any,
sizeof(struct in6_addr)))
- {
- int enable = 1;
- if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,
&enable, sizeof(enable)) == -1)
- {
- release_sock_fd( s, fd );
- SetLastError(WSAEAFNOSUPPORT);
- return SOCKET_ERROR;
- }
- }
-#endif
if (name->sa_family == WS_AF_INET)
{
struct sockaddr_in *in4 = (struct sockaddr_in*)
&uaddr;
@@ -7163,6 +7149,14 @@ SOCKET WINAPI WSASocketW(int af, int type, int
protocol,
TRACE("\tcreated %04lx\n", ret );
if (ipxptype > 0)
set_ipx_packettype(ret, ipxptype);
+#ifdef IPV6_V6ONLY
+ if (unixaf == AF_INET6)
+ {
+ /* AF_INET6 sockets have IPV6_V6ONLY enabled by default. */
+ int enable = 1;
+ WS_setsockopt(ret, WS_IPPROTO_IPV6, WS_IPV6_V6ONLY, &enable,
sizeof(enable));
+ }
+#endif
return ret;
}
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index 6853279..ea97804 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -6082,6 +6082,8 @@ static void test_ipv6only(void)
struct sockaddr_in sin4;
struct sockaddr_in6 sin6;
int ret;
+ DWORD enabled = 0;
+ int len = sizeof(enabled);
memset(&sin4, 0, sizeof(sin4));
sin4.sin_family = AF_INET;
@@ -6114,6 +6116,55 @@ static void test_ipv6only(void)
ok(!ret, "Could not bind IPv4 address (LastError: %d; %d expected
if IPv6 binds to IPv4 as well).\n",
WSAGetLastError(), WSAEADDRINUSE);
+ if (v4 != INVALID_SOCKET)
+ closesocket(v4);
+ if (v6 != INVALID_SOCKET)
+ closesocket(v6);
+
+ /* Test again, this time disabling V6ONLY. */
+ v6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
+ if (v6 == INVALID_SOCKET) {
+ skip("Could not create IPv6 socket (LastError: %d; %d expected
if IPv6 not available).\n",
+ WSAGetLastError(), WSAEAFNOSUPPORT);
+ goto end;
+ }
+ enabled = 2;
+ len = sizeof(enabled);
+ ret = getsockopt(v6, IPPROTO_IPV6, IPV6_V6ONLY, &enabled, &len);
+ if (ret) {
+ ok(!ret, "Failed to check IPV6_V6ONLY ((LastError: %d).\n",
WSAGetLastError());
+ goto end;
+ }
+ ok(enabled == 1, "IPV6_V6ONLY is not enabled by default.\n");
+ ret = setsockopt(v6, IPPROTO_IPV6, IPV6_V6ONLY, &enabled, len);
+ if (ret) {
+ ok(!ret, "Failed to disable IPV6_V6ONLY (LastError: %d).\n",
WSAGetLastError());
+ goto end;
+ }
+ ret = bind(v6, (struct sockaddr*)&sin6, sizeof(sin6));
+ if (ret) {
+ skip("Could not bind IPv6 address (LastError: %d).\n",
+ WSAGetLastError());
+ goto end;
+ }
+ enabled = 2;
+ len = sizeof(enabled);
+ ret = getsockopt(v6, IPPROTO_IPV6, IPV6_V6ONLY, &enabled, &len);
+ if (ret) {
+ ok(!ret, "Failed to check IPV6_V6ONLY (LastError: %d).\n",
WSAGetLastError());
+ goto end;
+ }
+ ok(!enabled, "IPV6_V6ONLY is enabled after bind.\n");
+ v4 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+ if (v4 == INVALID_SOCKET) {
+ skip("Could not create IPv4 socket (LastError: %d).\n",
+ WSAGetLastError());
+ goto end;
+ }
+ WSASetLastError(0xdeadbeef);
+ ret = bind(v4, (struct sockaddr*)&sin4, sizeof(sin4));
+ ok(WSAGetLastError() == WSAEADDRINUSE, "Failed to disable
IPV6_V6ONLY (LastError: %d; %d expected if IPv6 binds to IPv4 as
well).\n",
+ WSAGetLastError(), WSAEADDRINUSE);
end:
if (v4 != INVALID_SOCKET)
closesocket(v4);
--
2.5.0
More information about the wine-patches
mailing list