ws2_32: Ignore IPV6_V6ONLY setsockopt for AF_INET sockets.
Signed-off-by: Anton Romanov <theli.ua@gmail.com> Signed-off-by: Bruno Jesus <00cpxxx@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
0bcc46874f
commit
531dcf2dd3
|
@ -6016,7 +6016,6 @@ int WINAPI WS_setsockopt(SOCKET s, int level, int optname,
|
||||||
case WS_IPV6_MULTICAST_HOPS:
|
case WS_IPV6_MULTICAST_HOPS:
|
||||||
case WS_IPV6_MULTICAST_LOOP:
|
case WS_IPV6_MULTICAST_LOOP:
|
||||||
case WS_IPV6_UNICAST_HOPS:
|
case WS_IPV6_UNICAST_HOPS:
|
||||||
case WS_IPV6_V6ONLY:
|
|
||||||
#ifdef IPV6_UNICAST_IF
|
#ifdef IPV6_UNICAST_IF
|
||||||
case WS_IPV6_UNICAST_IF:
|
case WS_IPV6_UNICAST_IF:
|
||||||
#endif
|
#endif
|
||||||
|
@ -6027,6 +6026,30 @@ int WINAPI WS_setsockopt(SOCKET s, int level, int optname,
|
||||||
case WS_IPV6_PROTECTION_LEVEL:
|
case WS_IPV6_PROTECTION_LEVEL:
|
||||||
FIXME("IPV6_PROTECTION_LEVEL is ignored!\n");
|
FIXME("IPV6_PROTECTION_LEVEL is ignored!\n");
|
||||||
return 0;
|
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:
|
default:
|
||||||
FIXME("Unknown IPPROTO_IPV6 optname 0x%08x\n", optname);
|
FIXME("Unknown IPPROTO_IPV6 optname 0x%08x\n", optname);
|
||||||
return SOCKET_ERROR;
|
return SOCKET_ERROR;
|
||||||
|
|
|
@ -6189,12 +6189,60 @@ static void test_ipv6only(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
v4 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
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 */
|
/* bind on IPv4 socket should succeed - IPV6_V6ONLY is enabled by default */
|
||||||
ret = bind(v4, (struct sockaddr*)&sin4, sizeof(sin4));
|
ret = bind(v4, (struct sockaddr*)&sin4, sizeof(sin4));
|
||||||
ok(!ret, "Could not bind IPv4 address (LastError: %d)\n", WSAGetLastError());
|
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(v4);
|
||||||
closesocket(v6);
|
closesocket(v6);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue