From 9b5a0c388980b16f7adfceb1f57320087bfc6322 Mon Sep 17 00:00:00 2001 From: riperiperi Date: Tue, 28 Feb 2023 03:41:44 +0000 Subject: [PATCH] Sockets: Properly convert error codes on MacOS (#4491) * Sockets: Properly convert error codes on MacOS The error codes for MacOS are very different to how they are on windows or linux. An alternate mapping is used when the host operating system is MacOS. This PR also defaults IsDhcpEnabled to true when interfaceProperties.DhcpServerAddresses is not available. This change was already in `macos1`. * Address feedback --- .../StaticService/Types/IpAddressSetting.cs | 2 +- .../Sockets/Bsd/Impl/WinSockHelper.cs | 147 ++++++++++++------ 2 files changed, 104 insertions(+), 45 deletions(-) diff --git a/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpAddressSetting.cs b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpAddressSetting.cs index 5bb046abe..30667b928 100644 --- a/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpAddressSetting.cs +++ b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/Types/IpAddressSetting.cs @@ -15,7 +15,7 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService.Types public IpAddressSetting(IPInterfaceProperties interfaceProperties, UnicastIPAddressInformation unicastIPAddressInformation) { - IsDhcpEnabled = !OperatingSystem.IsMacOS() && interfaceProperties.DhcpServerAddresses.Count != 0; + IsDhcpEnabled = OperatingSystem.IsMacOS() || interfaceProperties.DhcpServerAddresses.Count != 0; Address = new IpV4Address(unicastIPAddressInformation.Address); IPv4Mask = new IpV4Address(unicastIPAddressInformation.IPv4Mask); GatewayAddress = new IpV4Address(interfaceProperties.GatewayAddresses[0].Address); diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/WinSockHelper.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/WinSockHelper.cs index 48439d7d3..5668d30b0 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/WinSockHelper.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Impl/WinSockHelper.cs @@ -1,4 +1,5 @@ -using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types; +using Ryujinx.HLE.HOS.Services.Sockets.Bsd.Types; +using System; using System.Collections.Generic; using System.Net.Sockets; @@ -9,85 +10,133 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Impl private static readonly Dictionary _errorMap = new() { // WSAEINTR - {WsaError.WSAEINTR, LinuxError.EINTR}, + { WsaError.WSAEINTR, LinuxError.EINTR }, // WSAEWOULDBLOCK - {WsaError.WSAEWOULDBLOCK, LinuxError.EWOULDBLOCK}, + { WsaError.WSAEWOULDBLOCK, LinuxError.EWOULDBLOCK }, // WSAEINPROGRESS - {WsaError.WSAEINPROGRESS, LinuxError.EINPROGRESS}, + { WsaError.WSAEINPROGRESS, LinuxError.EINPROGRESS }, // WSAEALREADY - {WsaError.WSAEALREADY, LinuxError.EALREADY}, + { WsaError.WSAEALREADY, LinuxError.EALREADY }, // WSAENOTSOCK - {WsaError.WSAENOTSOCK, LinuxError.ENOTSOCK}, + { WsaError.WSAENOTSOCK, LinuxError.ENOTSOCK }, // WSAEDESTADDRREQ - {WsaError.WSAEDESTADDRREQ, LinuxError.EDESTADDRREQ}, + { WsaError.WSAEDESTADDRREQ, LinuxError.EDESTADDRREQ }, // WSAEMSGSIZE - {WsaError.WSAEMSGSIZE, LinuxError.EMSGSIZE}, + { WsaError.WSAEMSGSIZE, LinuxError.EMSGSIZE }, // WSAEPROTOTYPE - {WsaError.WSAEPROTOTYPE, LinuxError.EPROTOTYPE}, + { WsaError.WSAEPROTOTYPE, LinuxError.EPROTOTYPE }, // WSAENOPROTOOPT - {WsaError.WSAENOPROTOOPT, LinuxError.ENOPROTOOPT}, + { WsaError.WSAENOPROTOOPT, LinuxError.ENOPROTOOPT }, // WSAEPROTONOSUPPORT - {WsaError.WSAEPROTONOSUPPORT, LinuxError.EPROTONOSUPPORT}, + { WsaError.WSAEPROTONOSUPPORT, LinuxError.EPROTONOSUPPORT }, // WSAESOCKTNOSUPPORT - {WsaError.WSAESOCKTNOSUPPORT, LinuxError.ESOCKTNOSUPPORT}, + { WsaError.WSAESOCKTNOSUPPORT, LinuxError.ESOCKTNOSUPPORT }, // WSAEOPNOTSUPP - {WsaError.WSAEOPNOTSUPP, LinuxError.EOPNOTSUPP}, + { WsaError.WSAEOPNOTSUPP, LinuxError.EOPNOTSUPP }, // WSAEPFNOSUPPORT - {WsaError.WSAEPFNOSUPPORT, LinuxError.EPFNOSUPPORT}, + { WsaError.WSAEPFNOSUPPORT, LinuxError.EPFNOSUPPORT }, // WSAEAFNOSUPPORT - {WsaError.WSAEAFNOSUPPORT, LinuxError.EAFNOSUPPORT}, + { WsaError.WSAEAFNOSUPPORT, LinuxError.EAFNOSUPPORT }, // WSAEADDRINUSE - {WsaError.WSAEADDRINUSE, LinuxError.EADDRINUSE}, + { WsaError.WSAEADDRINUSE, LinuxError.EADDRINUSE }, // WSAEADDRNOTAVAIL - {WsaError.WSAEADDRNOTAVAIL, LinuxError.EADDRNOTAVAIL}, + { WsaError.WSAEADDRNOTAVAIL, LinuxError.EADDRNOTAVAIL }, // WSAENETDOWN - {WsaError.WSAENETDOWN, LinuxError.ENETDOWN}, + { WsaError.WSAENETDOWN, LinuxError.ENETDOWN }, // WSAENETUNREACH - {WsaError.WSAENETUNREACH, LinuxError.ENETUNREACH}, + { WsaError.WSAENETUNREACH, LinuxError.ENETUNREACH }, // WSAENETRESET - {WsaError.WSAENETRESET, LinuxError.ENETRESET}, + { WsaError.WSAENETRESET, LinuxError.ENETRESET }, // WSAECONNABORTED - {WsaError.WSAECONNABORTED, LinuxError.ECONNABORTED}, + { WsaError.WSAECONNABORTED, LinuxError.ECONNABORTED }, // WSAECONNRESET - {WsaError.WSAECONNRESET, LinuxError.ECONNRESET}, + { WsaError.WSAECONNRESET, LinuxError.ECONNRESET }, // WSAENOBUFS - {WsaError.WSAENOBUFS, LinuxError.ENOBUFS}, + { WsaError.WSAENOBUFS, LinuxError.ENOBUFS }, // WSAEISCONN - {WsaError.WSAEISCONN, LinuxError.EISCONN}, + { WsaError.WSAEISCONN, LinuxError.EISCONN }, // WSAENOTCONN - {WsaError.WSAENOTCONN, LinuxError.ENOTCONN}, + { WsaError.WSAENOTCONN, LinuxError.ENOTCONN }, // WSAESHUTDOWN - {WsaError.WSAESHUTDOWN, LinuxError.ESHUTDOWN}, + { WsaError.WSAESHUTDOWN, LinuxError.ESHUTDOWN }, // WSAETOOMANYREFS - {WsaError.WSAETOOMANYREFS, LinuxError.ETOOMANYREFS}, + { WsaError.WSAETOOMANYREFS, LinuxError.ETOOMANYREFS }, // WSAETIMEDOUT - {WsaError.WSAETIMEDOUT, LinuxError.ETIMEDOUT}, + { WsaError.WSAETIMEDOUT, LinuxError.ETIMEDOUT }, // WSAECONNREFUSED - {WsaError.WSAECONNREFUSED, LinuxError.ECONNREFUSED}, + { WsaError.WSAECONNREFUSED, LinuxError.ECONNREFUSED }, // WSAELOOP - {WsaError.WSAELOOP, LinuxError.ELOOP}, + { WsaError.WSAELOOP, LinuxError.ELOOP }, // WSAENAMETOOLONG - {WsaError.WSAENAMETOOLONG, LinuxError.ENAMETOOLONG}, + { WsaError.WSAENAMETOOLONG, LinuxError.ENAMETOOLONG }, // WSAEHOSTDOWN - {WsaError.WSAEHOSTDOWN, LinuxError.EHOSTDOWN}, + { WsaError.WSAEHOSTDOWN, LinuxError.EHOSTDOWN }, // WSAEHOSTUNREACH - {WsaError.WSAEHOSTUNREACH, LinuxError.EHOSTUNREACH}, + { WsaError.WSAEHOSTUNREACH, LinuxError.EHOSTUNREACH }, // WSAENOTEMPTY - {WsaError.WSAENOTEMPTY, LinuxError.ENOTEMPTY}, + { WsaError.WSAENOTEMPTY, LinuxError.ENOTEMPTY }, // WSAEUSERS - {WsaError.WSAEUSERS, LinuxError.EUSERS}, + { WsaError.WSAEUSERS, LinuxError.EUSERS }, // WSAEDQUOT - {WsaError.WSAEDQUOT, LinuxError.EDQUOT}, + { WsaError.WSAEDQUOT, LinuxError.EDQUOT }, // WSAESTALE - {WsaError.WSAESTALE, LinuxError.ESTALE}, + { WsaError.WSAESTALE, LinuxError.ESTALE }, // WSAEREMOTE - {WsaError.WSAEREMOTE, LinuxError.EREMOTE}, + { WsaError.WSAEREMOTE, LinuxError.EREMOTE }, // WSAEINVAL - {WsaError.WSAEINVAL, LinuxError.EINVAL}, + { WsaError.WSAEINVAL, LinuxError.EINVAL }, // WSAEFAULT - {WsaError.WSAEFAULT, LinuxError.EFAULT}, + { WsaError.WSAEFAULT, LinuxError.EFAULT }, // NOERROR - {0, 0} + { 0, 0 } + }; + + private static readonly Dictionary _errorMapMacOs = new() + { + { 35, LinuxError.EAGAIN }, + { 11, LinuxError.EDEADLOCK }, + { 91, LinuxError.ENOMSG }, + { 90, LinuxError.EIDRM }, + { 77, LinuxError.ENOLCK }, + { 70, LinuxError.ESTALE }, + { 36, LinuxError.EINPROGRESS }, + { 37, LinuxError.EALREADY }, + { 38, LinuxError.ENOTSOCK }, + { 39, LinuxError.EDESTADDRREQ }, + { 40, LinuxError.EMSGSIZE }, + { 41, LinuxError.EPROTOTYPE }, + { 42, LinuxError.ENOPROTOOPT }, + { 43, LinuxError.EPROTONOSUPPORT }, + { 44, LinuxError.ESOCKTNOSUPPORT }, + { 45, LinuxError.EOPNOTSUPP }, + { 46, LinuxError.EPFNOSUPPORT }, + { 47, LinuxError.EAFNOSUPPORT }, + { 48, LinuxError.EADDRINUSE }, + { 49, LinuxError.EADDRNOTAVAIL }, + { 50, LinuxError.ENETDOWN }, + { 51, LinuxError.ENETUNREACH }, + { 52, LinuxError.ENETRESET }, + { 53, LinuxError.ECONNABORTED }, + { 54, LinuxError.ECONNRESET }, + { 55, LinuxError.ENOBUFS }, + { 56, LinuxError.EISCONN }, + { 57, LinuxError.ENOTCONN }, + { 58, LinuxError.ESHUTDOWN }, + { 60, LinuxError.ETIMEDOUT }, + { 61, LinuxError.ECONNREFUSED }, + { 64, LinuxError.EHOSTDOWN }, + { 65, LinuxError.EHOSTUNREACH }, + { 68, LinuxError.EUSERS }, + { 62, LinuxError.ELOOP }, + { 63, LinuxError.ENAMETOOLONG }, + { 66, LinuxError.ENOTEMPTY }, + { 69, LinuxError.EDQUOT }, + { 71, LinuxError.EREMOTE }, + { 78, LinuxError.ENOSYS }, + { 59, LinuxError.ETOOMANYREFS }, + { 92, LinuxError.EILSEQ }, + { 89, LinuxError.ECANCELED }, + { 84, LinuxError.EOVERFLOW } }; private static readonly Dictionary _soSocketOptionMap = new() @@ -136,12 +185,22 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd.Impl public static LinuxError ConvertError(WsaError errorCode) { - if (!_errorMap.TryGetValue(errorCode, out LinuxError errno)) + if (OperatingSystem.IsMacOS()) { - errno = (LinuxError)errorCode; + if (_errorMapMacOs.TryGetValue((int)errorCode, out LinuxError errno)) + { + return errno; + } + } + else + { + if (_errorMap.TryGetValue(errorCode, out LinuxError errno)) + { + return errno; + } } - return errno; + return (LinuxError)errorCode; } public static bool TryConvertSocketOption(BsdSocketOption option, SocketOptionLevel level, out SocketOptionName name)