[PATCH] ws2_32: Allow user to enable IP dual stack (v4).

Bruno Jesus 00cpxxx at gmail.com
Mon Oct 17 16:03:34 CDT 2016


Hi, thanks for the retry. I'm not at home and I'm replying from mobile so I
can't help much, from the test results it is clear that MS broke the API
starting on Vista, the.tests need to be.enhaced so that they pass on both
pré vista and post xp. In the sockets tests I have made that many times due
to other API breaks, look for the word behavior around tests line 1760. So
you can split and make tests pass on all systems.


On Monday, October 17, 2016, Roman Pišl <rpisl at seznam.cz> wrote:

> 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.
>
> Based on https://www.winehq.org/pipermail/wine-patches/2016-
> July/151919.html
>
> Signed-off-by: Matthieu Nottale <matthieu.nottale at infinit.io
> <javascript:;>>
> Signed-off-by: Roman Pišl <rpisl at seznam.cz <javascript:;>>
> ---
>  dlls/ws2_32/socket.c     | 23 +++++++++-------------
>  dlls/ws2_32/tests/sock.c | 50 ++++++++++++++++++++++++++++++
> ++++++++++++++++--
>  2 files changed, 57 insertions(+), 16 deletions(-)
>
> diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
> index e8c5130..d14e9d6 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;
> @@ -7233,6 +7219,15 @@ 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)
> +        {
> +            int enable = 1;
> +            int fd = get_sock_fd(ret, 0, NULL);
> +            setsockopt(fd, IPPROTO_IPV6, 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 a144bd3..a676255 100644
> --- a/dlls/ws2_32/tests/sock.c
> +++ b/dlls/ws2_32/tests/sock.c
> @@ -1732,7 +1732,7 @@ static void test_so_reuseaddr(void)
>      DWORD err;
>
>      saddr.sin_family      = AF_INET;
> -    saddr.sin_port        = htons(9375);
> +    saddr.sin_port        = htons(SERVERPORT+1);
>      saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
>
>      s1=socket(AF_INET, SOCK_STREAM, 0);
> @@ -6110,6 +6110,8 @@ static void test_ipv6only(void)
>      struct sockaddr_in sin4;
>      struct sockaddr_in6 sin6;
>      int ret;
> +    int enabled;
> +    int len;
>
>      memset(&sin4, 0, sizeof(sin4));
>      sin4.sin_family = AF_INET;
> @@ -6142,6 +6144,50 @@ 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);
>
> +    closesocket(v4);
> +    closesocket(v6);
> +    v4 = INVALID_SOCKET;
> +    v6 = INVALID_SOCKET;
> +
> +    /* Test again, this time disabling V6ONLY. */
> +    sin4.sin_port = htons(SERVERPORT+2);
> +    sin6.sin6_port = htons(SERVERPORT+2);
> +
> +    v6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
> +    ok(v6 != INVALID_SOCKET, "Could not create IPv6 socket (LastError:
> %d; %d expected if IPv6 not available).\n",
> +        WSAGetLastError(), WSAEAFNOSUPPORT);
> +
> +    enabled = 2;
> +    len = sizeof(enabled);
> +    ret = getsockopt(v6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled,
> &len);
> +    if (ret) {
> +        skip("Could not check IPV6_V6ONLY (option not supported?)
> ((LastError: %d).\n", WSAGetLastError());
> +        goto end;
> +    }
> +    ok(enabled == 1, "IPV6_V6ONLY is not enabled by default.\n");
> +
> +    enabled = 0;
> +    ret = setsockopt(v6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, len);
> +    ok(!ret, "Failed to disable IPV6_V6ONLY (LastError: %d).\n",
> WSAGetLastError());
> +
> +    ret = bind(v6, (struct sockaddr*)&sin6, sizeof(sin6));
> +    ok(!ret, "Could not bind IPv6 address (LastError: %d).\n",
> WSAGetLastError());
> +
> +    enabled = 2;
> +    len = sizeof(enabled);
> +    getsockopt(v6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&enabled, &len);
> +    ok(enabled == 0, "IPV6_V6ONLY is enabled after bind.\n");
> +
> +    v4 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
> +    ok(v4 != INVALID_SOCKET, "Could not create IPv4 socket (LastError:
> %d).\n",
> +        WSAGetLastError());
> +
> +    WSASetLastError(0xdeadbeef);
> +    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);
> @@ -8024,7 +8070,7 @@ static void test_TransmitFile(void)
>      /* Setup a properly connected socket for transfers */
>      memset(&bindAddress, 0, sizeof(bindAddress));
>      bindAddress.sin_family = AF_INET;
> -    bindAddress.sin_port = htons(9375);
> +    bindAddress.sin_port = htons(SERVERPORT+1);
>      bindAddress.sin_addr.s_addr = inet_addr("127.0.0.1");
>      iret = bind(server, (struct sockaddr*)&bindAddress,
> sizeof(bindAddress));
>      if (iret != 0)
> --
> 2.7.3
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-devel/attachments/20161017/3912e4ba/attachment.html>


More information about the wine-devel mailing list