[PATCH v3] ws2_32: Return WSAEAFNOSUPPORT when ip4/6 disabled
Currently, when IPv6 is disabled by the kernel, attempting to use the 'WebRequest' API with .NET native causes a crash. This can be recreated using the following gist: https://gist.github.com/redmcg/7d81ef833c77bee6965b5f441006f697 This patch fixes the crash by returning WSAEAFNOSUPPORT, as expected by .NET. See: https://referencesource.microsoft.com/#System/net/System/Net/Sockets/Socket.... Signed-off-by: Brendan McGrath <brendan(a)redmandi.com> --- Changes since v2: - Add the 'Signed-off-by' tag dlls/ws2_32/socket.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index df068fe8527..956ead2e9d5 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -7646,6 +7646,8 @@ SOCKET WINAPI WSASocketW(int af, int type, int protocol, /* invalid combination of valid parameters, like SOCK_STREAM + IPPROTO_UDP */ if (err == WSAEINVAL) err = WSAESOCKTNOSUPPORT; + else if (err == WSAEOPNOTSUPP && (unixaf == AF_INET || unixaf == AF_INET6)) + err = WSAEAFNOSUPPORT; else if (err == WSAEOPNOTSUPP) err = WSAEPROTONOSUPPORT; } -- 2.17.1
Brendan McGrath <brendan(a)redmandi.com> writes:
Currently, when IPv6 is disabled by the kernel, attempting to use the 'WebRequest' API with .NET native causes a crash. This can be recreated using the following gist: https://gist.github.com/redmcg/7d81ef833c77bee6965b5f441006f697
This patch fixes the crash by returning WSAEAFNOSUPPORT, as expected by .NET. See: https://referencesource.microsoft.com/#System/net/System/Net/Sockets/Socket....
Signed-off-by: Brendan McGrath <brendan(a)redmandi.com> ---
It breaks the tests: ../../../tools/runtest -q -P wine -T ../../.. -M ws2_32.dll -p ws2_32_test.exe.so sock && touch sock.ok sock.c:2554: Test failed: Expected 10043, received 10047 sock.c:2561: Test failed: Expected 10043, received 10047 make[1]: *** [Makefile:220: sock.ok] Error 2 -- Alexandre Julliard julliard(a)winehq.org
Currently, when IPv6 is disabled by the kernel, attempting to use the 'WebRequest' API with .NET native causes a crash. This can be recreated using the following gist: https://gist.github.com/redmcg/7d81ef833c77bee6965b5f441006f697 This patch fixes the crash by returning WSAEAFNOSUPPORT, as expected by .NET. See: https://referencesource.microsoft.com/#System/net/System/Net/Sockets/Socket.... Signed-off-by: Brendan McGrath <brendan(a)redmandi.com> --- Changes since v3: - fix broken tests (by only returning WSAEAFNOSUPPORT on assumed working protocol combinations) dlls/ws2_32/socket.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index df068fe8527..d77b6404105 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -7646,8 +7646,19 @@ SOCKET WINAPI WSASocketW(int af, int type, int protocol, /* invalid combination of valid parameters, like SOCK_STREAM + IPPROTO_UDP */ if (err == WSAEINVAL) err = WSAESOCKTNOSUPPORT; - else if (err == WSAEOPNOTSUPP) - err = WSAEPROTONOSUPPORT; + else if (err == WSAEOPNOTSUPP) { + if (unixtype == SOCK_STREAM && protocol == IPPROTO_TCP && + (unixaf == AF_INET || unixaf == AF_INET6)) + err = WSAEAFNOSUPPORT; + else if (unixtype == SOCK_DGRAM && protocol == IPPROTO_IP && + (unixaf == AF_INET || unixaf == AF_INET6)) + err = WSAEAFNOSUPPORT; + else if (unixtype == SOCK_DGRAM && protocol == IPPROTO_IPV6 && + unixaf == AF_INET6) + err = WSAEAFNOSUPPORT; + else + err = WSAEPROTONOSUPPORT; + } } done: -- 2.17.1
Brendan McGrath <brendan(a)redmandi.com> writes:
@@ -7646,8 +7646,19 @@ SOCKET WINAPI WSASocketW(int af, int type, int protocol, /* invalid combination of valid parameters, like SOCK_STREAM + IPPROTO_UDP */ if (err == WSAEINVAL) err = WSAESOCKTNOSUPPORT; - else if (err == WSAEOPNOTSUPP) - err = WSAEPROTONOSUPPORT; + else if (err == WSAEOPNOTSUPP) { + if (unixtype == SOCK_STREAM && protocol == IPPROTO_TCP && + (unixaf == AF_INET || unixaf == AF_INET6)) + err = WSAEAFNOSUPPORT; + else if (unixtype == SOCK_DGRAM && protocol == IPPROTO_IP && + (unixaf == AF_INET || unixaf == AF_INET6)) + err = WSAEAFNOSUPPORT; + else if (unixtype == SOCK_DGRAM && protocol == IPPROTO_IPV6 && + unixaf == AF_INET6) + err = WSAEAFNOSUPPORT; + else + err = WSAEPROTONOSUPPORT; + }
I'd suggest to find a way to return the specific error from the server, instead of mapping everything to the same error on the server side and trying to guess the specific error afterwards. -- Alexandre Julliard julliard(a)winehq.org
Currently, when IPv6 is disabled by the kernel, attempting to use the 'WebRequest' API with .NET native causes a crash. This can be recreated using the following gist: https://gist.github.com/redmcg/7d81ef833c77bee6965b5f441006f697 This patch fixes the crash by returning WSAEAFNOSUPPORT, as expected by .NET. See: https://referencesource.microsoft.com/#System/net/System/Net/Sockets/Socket.... Signed-off-by: Brendan McGrath <brendan(a)redmandi.com> --- Changes since v4: - from the server: map EAFNOSUPPORT from the kernel to STATUS_NOT_IMPLEMENTED - in ws2_32: map STATUS_NOT_IMPLEMENTED to WSAEAFNOSUPPORT It's still a bit ugly - but short of changing the design by removing the need for a NTSTATUS - I'm not sure there's a better way. dlls/ws2_32/socket.c | 1 + server/sock.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index df068fe8527..1d433086f11 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -1067,6 +1067,7 @@ static inline DWORD NtStatusToWSAError( const DWORD status ) case STATUS_BUFFER_OVERFLOW: wserr = WSAEMSGSIZE; break; case STATUS_NOT_SUPPORTED: wserr = WSAEOPNOTSUPP; break; case STATUS_HOST_UNREACHABLE: wserr = WSAEHOSTUNREACH; break; + case STATUS_NOT_IMPLEMENTED: wserr = WSAEAFNOSUPPORT; break; default: wserr = RtlNtStatusToDosError( status ); diff --git a/server/sock.c b/server/sock.c index a8e6e28599b..dfcbab530fe 100644 --- a/server/sock.c +++ b/server/sock.c @@ -912,8 +912,8 @@ static int sock_get_ntstatus( int err ) case EPROTONOSUPPORT: case ESOCKTNOSUPPORT: case EPFNOSUPPORT: - case EAFNOSUPPORT: case EPROTOTYPE: return STATUS_NOT_SUPPORTED; + case EAFNOSUPPORT: return STATUS_NOT_IMPLEMENTED; case ENOPROTOOPT: return STATUS_INVALID_PARAMETER; case EOPNOTSUPP: return STATUS_NOT_SUPPORTED; case EADDRINUSE: return STATUS_ADDRESS_ALREADY_ASSOCIATED; -- 2.17.1
Just following up on version 5 of this patch as I haven't heard any feedback (and want to make sure it hasn't been overlooked). On 16/11/18 10:27 am, Brendan McGrath wrote:
Currently, when IPv6 is disabled by the kernel, attempting to use the 'WebRequest' API with .NET native causes a crash. This can be recreated using the following gist: https://gist.github.com/redmcg/7d81ef833c77bee6965b5f441006f697
This patch fixes the crash by returning WSAEAFNOSUPPORT, as expected by .NET. See: https://referencesource.microsoft.com/#System/net/System/Net/Sockets/Socket....
Signed-off-by: Brendan McGrath <brendan(a)redmandi.com> --- Changes since v4: - from the server: map EAFNOSUPPORT from the kernel to STATUS_NOT_IMPLEMENTED - in ws2_32: map STATUS_NOT_IMPLEMENTED to WSAEAFNOSUPPORT
It's still a bit ugly - but short of changing the design by removing the need for a NTSTATUS - I'm not sure there's a better way.
dlls/ws2_32/socket.c | 1 + server/sock.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index df068fe8527..1d433086f11 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -1067,6 +1067,7 @@ static inline DWORD NtStatusToWSAError( const DWORD status ) case STATUS_BUFFER_OVERFLOW: wserr = WSAEMSGSIZE; break; case STATUS_NOT_SUPPORTED: wserr = WSAEOPNOTSUPP; break; case STATUS_HOST_UNREACHABLE: wserr = WSAEHOSTUNREACH; break; + case STATUS_NOT_IMPLEMENTED: wserr = WSAEAFNOSUPPORT; break;
default: wserr = RtlNtStatusToDosError( status ); diff --git a/server/sock.c b/server/sock.c index a8e6e28599b..dfcbab530fe 100644 --- a/server/sock.c +++ b/server/sock.c @@ -912,8 +912,8 @@ static int sock_get_ntstatus( int err ) case EPROTONOSUPPORT: case ESOCKTNOSUPPORT: case EPFNOSUPPORT: - case EAFNOSUPPORT: case EPROTOTYPE: return STATUS_NOT_SUPPORTED; + case EAFNOSUPPORT: return STATUS_NOT_IMPLEMENTED; case ENOPROTOOPT: return STATUS_INVALID_PARAMETER; case EOPNOTSUPP: return STATUS_NOT_SUPPORTED; case EADDRINUSE: return STATUS_ADDRESS_ALREADY_ASSOCIATED;
Brendan McGrath <brendan(a)redmandi.com> writes:
Just following up on version 5 of this patch as I haven't heard any feedback (and want to make sure it hasn't been overlooked).
I fixed it a different way, hopefully it works now. -- Alexandre Julliard julliard(a)winehq.org
It does. Thanks for that. On 22/11/18 6:09 am, Alexandre Julliard wrote:
Brendan McGrath <brendan(a)redmandi.com> writes:
Just following up on version 5 of this patch as I haven't heard any feedback (and want to make sure it hasn't been overlooked). I fixed it a different way, hopefully it works now.
participants (2)
-
Alexandre Julliard -
Brendan McGrath