diff options
Diffstat (limited to 'src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs')
| -rw-r--r-- | src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs | 220 |
1 files changed, 123 insertions, 97 deletions
diff --git a/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs b/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs index 64c3acbb..93960d13 100644 --- a/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs +++ b/src/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs @@ -28,8 +28,10 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres public ResultCode SetDnsAddressesPrivateRequest(ServiceCtx context) { uint cancelHandleRequest = context.RequestData.ReadUInt32(); - ulong bufferPosition = context.Request.SendBuff[0].Position; - ulong bufferSize = context.Request.SendBuff[0].Size; +#pragma warning disable IDE0059 // Remove unnecessary value assignment + ulong bufferPosition = context.Request.SendBuff[0].Position; + ulong bufferSize = context.Request.SendBuff[0].Size; +#pragma warning restore IDE0059 // TODO: This is stubbed in 2.0.0+, reverse 1.0.0 version for the sake of completeness. Logger.Stub?.PrintStub(LogClass.ServiceSfdnsres, new { cancelHandleRequest }); @@ -42,8 +44,10 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres public ResultCode GetDnsAddressPrivateRequest(ServiceCtx context) { uint cancelHandleRequest = context.RequestData.ReadUInt32(); - ulong bufferPosition = context.Request.ReceiveBuff[0].Position; - ulong bufferSize = context.Request.ReceiveBuff[0].Size; +#pragma warning disable IDE0059 // Remove unnecessary value assignment + ulong bufferPosition = context.Request.ReceiveBuff[0].Position; + ulong bufferSize = context.Request.ReceiveBuff[0].Size; +#pragma warning restore IDE0059 // TODO: This is stubbed in 2.0.0+, reverse 1.0.0 version for the sake of completeness. Logger.Stub?.PrintStub(LogClass.ServiceSfdnsres, new { cancelHandleRequest }); @@ -56,10 +60,10 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres public ResultCode GetHostByNameRequest(ServiceCtx context) { ulong inputBufferPosition = context.Request.SendBuff[0].Position; - ulong inputBufferSize = context.Request.SendBuff[0].Size; + ulong inputBufferSize = context.Request.SendBuff[0].Size; ulong outputBufferPosition = context.Request.ReceiveBuff[0].Position; - ulong outputBufferSize = context.Request.ReceiveBuff[0].Size; + ulong outputBufferSize = context.Request.ReceiveBuff[0].Size; return GetHostByNameRequestImpl(context, inputBufferPosition, inputBufferSize, outputBufferPosition, outputBufferSize, false, 0, 0); } @@ -69,10 +73,10 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres public ResultCode GetHostByAddrRequest(ServiceCtx context) { ulong inputBufferPosition = context.Request.SendBuff[0].Position; - ulong inputBufferSize = context.Request.SendBuff[0].Size; + ulong inputBufferSize = context.Request.SendBuff[0].Size; ulong outputBufferPosition = context.Request.ReceiveBuff[0].Position; - ulong outputBufferSize = context.Request.ReceiveBuff[0].Size; + ulong outputBufferSize = context.Request.ReceiveBuff[0].Size; return GetHostByAddrRequestImpl(context, inputBufferPosition, inputBufferSize, outputBufferPosition, outputBufferSize, false, 0, 0); } @@ -82,20 +86,20 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres public ResultCode GetHostStringErrorRequest(ServiceCtx context) { ResultCode resultCode = ResultCode.NotAllocated; - NetDbError errorCode = (NetDbError)context.RequestData.ReadInt32(); + NetDbError errorCode = (NetDbError)context.RequestData.ReadInt32(); string errorString = errorCode switch { - NetDbError.Success => "Resolver Error 0 (no error)", + NetDbError.Success => "Resolver Error 0 (no error)", NetDbError.HostNotFound => "Unknown host", - NetDbError.TryAgain => "Host name lookup failure", - NetDbError.NoRecovery => "Unknown server error", - NetDbError.NoData => "No address associated with name", - _ => (errorCode <= NetDbError.Internal) ? "Resolver internal error" : "Unknown resolver error" + NetDbError.TryAgain => "Host name lookup failure", + NetDbError.NoRecovery => "Unknown server error", + NetDbError.NoData => "No address associated with name", + _ => (errorCode <= NetDbError.Internal) ? "Resolver internal error" : "Unknown resolver error", }; ulong bufferPosition = context.Request.ReceiveBuff[0].Position; - ulong bufferSize = context.Request.ReceiveBuff[0].Size; + ulong bufferSize = context.Request.ReceiveBuff[0].Size; if ((ulong)(errorString.Length + 1) <= bufferSize) { @@ -112,7 +116,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres public ResultCode GetGaiStringErrorRequest(ServiceCtx context) { ResultCode resultCode = ResultCode.NotAllocated; - GaiError errorCode = (GaiError)context.RequestData.ReadInt32(); + GaiError errorCode = (GaiError)context.RequestData.ReadInt32(); if (errorCode > GaiError.Max) { @@ -122,25 +126,25 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres string errorString = errorCode switch { GaiError.AddressFamily => "Address family for hostname not supported", - GaiError.Again => "Temporary failure in name resolution", - GaiError.BadFlags => "Invalid value for ai_flags", - GaiError.Fail => "Non-recoverable failure in name resolution", - GaiError.Family => "ai_family not supported", - GaiError.Memory => "Memory allocation failure", - GaiError.NoData => "No address associated with hostname", - GaiError.NoName => "hostname nor servname provided, or not known", - GaiError.Service => "servname not supported for ai_socktype", - GaiError.SocketType => "ai_socktype not supported", - GaiError.System => "System error returned in errno", - GaiError.BadHints => "Invalid value for hints", - GaiError.Protocol => "Resolved protocol is unknown", - GaiError.Overflow => "Argument buffer overflow", - GaiError.Max => "Unknown error", - _ => "Success" + GaiError.Again => "Temporary failure in name resolution", + GaiError.BadFlags => "Invalid value for ai_flags", + GaiError.Fail => "Non-recoverable failure in name resolution", + GaiError.Family => "ai_family not supported", + GaiError.Memory => "Memory allocation failure", + GaiError.NoData => "No address associated with hostname", + GaiError.NoName => "hostname nor servname provided, or not known", + GaiError.Service => "servname not supported for ai_socktype", + GaiError.SocketType => "ai_socktype not supported", + GaiError.System => "System error returned in errno", + GaiError.BadHints => "Invalid value for hints", + GaiError.Protocol => "Resolved protocol is unknown", + GaiError.Overflow => "Argument buffer overflow", + GaiError.Max => "Unknown error", + _ => "Success", }; ulong bufferPosition = context.Request.ReceiveBuff[0].Position; - ulong bufferSize = context.Request.ReceiveBuff[0].Size; + ulong bufferSize = context.Request.ReceiveBuff[0].Size; if ((ulong)(errorString.Length + 1) <= bufferSize) { @@ -157,7 +161,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres public ResultCode GetAddrInfoRequest(ServiceCtx context) { ulong responseBufferPosition = context.Request.ReceiveBuff[0].Position; - ulong responseBufferSize = context.Request.ReceiveBuff[0].Size; + ulong responseBufferSize = context.Request.ReceiveBuff[0].Size; return GetAddrInfoRequestImpl(context, responseBufferPosition, responseBufferSize, false, 0, 0); } @@ -166,8 +170,10 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres // GetCancelHandleRequest(u64, pid) -> u32 public ResultCode GetCancelHandleRequest(ServiceCtx context) { - ulong pidPlaceHolder = context.RequestData.ReadUInt64(); - uint cancelHandleRequest = 0; +#pragma warning disable IDE0059 // Remove unnecessary value assignment + ulong pidPlaceHolder = context.RequestData.ReadUInt64(); +#pragma warning restore IDE0059 + uint cancelHandleRequest = 0; context.ResponseData.Write(cancelHandleRequest); @@ -180,8 +186,10 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres // CancelRequest(u32, u64, pid) public ResultCode CancelRequest(ServiceCtx context) { - uint cancelHandleRequest = context.RequestData.ReadUInt32(); - ulong pidPlaceHolder = context.RequestData.ReadUInt64(); + uint cancelHandleRequest = context.RequestData.ReadUInt32(); +#pragma warning disable IDE0059 // Remove unnecessary value assignment + ulong pidPlaceHolder = context.RequestData.ReadUInt64(); +#pragma warning restore IDE0059 Logger.Stub?.PrintStub(LogClass.ServiceSfdnsres, new { cancelHandleRequest }); @@ -192,8 +200,8 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres // GetHostByNameRequestWithOptions(u8, u32, u64, pid, buffer<unknown, 21, 0>, buffer<unknown, 21, 0>) -> (u32, u32, u32, buffer<unknown, 22, 0>) public ResultCode GetHostByNameRequestWithOptions(ServiceCtx context) { - (ulong inputBufferPosition, ulong inputBufferSize) = context.Request.GetBufferType0x21(); - (ulong outputBufferPosition, ulong outputBufferSize) = context.Request.GetBufferType0x22(); + (ulong inputBufferPosition, ulong inputBufferSize) = context.Request.GetBufferType0x21(); + (ulong outputBufferPosition, ulong outputBufferSize) = context.Request.GetBufferType0x22(); (ulong optionsBufferPosition, ulong optionsBufferSize) = context.Request.GetBufferType0x21(); return GetHostByNameRequestImpl( @@ -211,8 +219,8 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres // GetHostByAddrRequestWithOptions(u32, u32, u32, u64, pid, buffer<unknown, 21, 0>, buffer<unknown, 21, 0>) -> (u32, u32, u32, buffer<unknown, 22, 0>) public ResultCode GetHostByAddrRequestWithOptions(ServiceCtx context) { - (ulong inputBufferPosition, ulong inputBufferSize) = context.Request.GetBufferType0x21(); - (ulong outputBufferPosition, ulong outputBufferSize) = context.Request.GetBufferType0x22(); + (ulong inputBufferPosition, ulong inputBufferSize) = context.Request.GetBufferType0x21(); + (ulong outputBufferPosition, ulong outputBufferSize) = context.Request.GetBufferType0x22(); (ulong optionsBufferPosition, ulong optionsBufferSize) = context.Request.GetBufferType0x21(); return GetHostByAddrRequestImpl( @@ -230,7 +238,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres // GetAddrInfoRequestWithOptions(bool enable_nsd_resolve, u32, u64 pid_placeholder, pid, buffer<i8, 5, 0> host, buffer<i8, 5, 0> service, buffer<packed_addrinfo, 5, 0> hints, buffer<unknown, 21, 0>) -> (i32 ret, u32 bsd_errno, u32 unknown, u32 packed_addrinfo_size, buffer<packed_addrinfo, 22, 0> response) public ResultCode GetAddrInfoRequestWithOptions(ServiceCtx context) { - (ulong outputBufferPosition, ulong outputBufferSize) = context.Request.GetBufferType0x22(); + (ulong outputBufferPosition, ulong outputBufferSize) = context.Request.GetBufferType0x22(); (ulong optionsBufferPosition, ulong optionsBufferSize) = context.Request.GetBufferType0x21(); return GetAddrInfoRequestImpl(context, outputBufferPosition, outputBufferSize, true, optionsBufferPosition, optionsBufferSize); @@ -241,7 +249,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres public ResultCode ResolverSetOptionRequest(ServiceCtx context) { ulong bufferPosition = context.Request.SendBuff[0].Position; - ulong bufferSize = context.Request.SendBuff[0].Size; + ulong bufferSize = context.Request.SendBuff[0].Size; ulong unknown = context.RequestData.ReadUInt64(); @@ -254,7 +262,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres Logger.Stub?.PrintStub(LogClass.ServiceSfdnsres, new { unknown }); NetDbError netDbErrorCode = NetDbError.Success; - GaiError errno = GaiError.Success; + GaiError errno = GaiError.Success; context.ResponseData.Write((int)errno); context.ResponseData.Write((int)netDbErrorCode); @@ -294,9 +302,11 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres } // TODO: Use params. - bool enableNsdResolve = (context.RequestData.ReadInt32() & 1) != 0; - int timeOut = context.RequestData.ReadInt32(); - ulong pidPlaceholder = context.RequestData.ReadUInt64(); + bool enableNsdResolve = (context.RequestData.ReadInt32() & 1) != 0; +#pragma warning disable IDE0059 // Remove unnecessary value assignment + int timeOut = context.RequestData.ReadInt32(); + ulong pidPlaceholder = context.RequestData.ReadUInt64(); +#pragma warning restore IDE0059 if (withOptions) { @@ -306,8 +316,8 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres IPHostEntry hostEntry = null; NetDbError netDbErrorCode = NetDbError.Success; - GaiError errno = GaiError.Overflow; - int serializedSize = 0; + GaiError errno = GaiError.Overflow; + int serializedSize = 0; if (host.Length <= byte.MaxValue) { @@ -326,7 +336,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres Logger.Info?.Print(LogClass.ServiceSfdnsres, $"DNS Blocked: {host}"); netDbErrorCode = NetDbError.HostNotFound; - errno = GaiError.NoData; + errno = GaiError.NoData; } else { @@ -339,7 +349,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres catch (SocketException exception) { netDbErrorCode = ConvertSocketErrorCodeToNetDbError(exception.ErrorCode); - errno = ConvertSocketErrorCodeToGaiError(exception.ErrorCode, errno); + errno = ConvertSocketErrorCodeToGaiError(exception.ErrorCode, errno); } } } @@ -354,12 +364,12 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres if (!addresses.Any()) { - errno = GaiError.NoData; + errno = GaiError.NoData; netDbErrorCode = NetDbError.NoAddress; } else { - errno = GaiError.Success; + errno = GaiError.Success; serializedSize = SerializeHostEntries(context, outputBufferPosition, outputBufferSize, hostEntry, addresses); } } @@ -381,7 +391,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres { if (!context.Device.Configuration.EnableInternetAccess) { - Logger.Info?.Print(LogClass.ServiceSfdnsres, $"Guest network access disabled, DNS Blocked."); + Logger.Info?.Print(LogClass.ServiceSfdnsres, "Guest network access disabled, DNS Blocked."); WriteResponse(context, withOptions, 0, GaiError.NoData, NetDbError.HostNotFound); @@ -393,10 +403,12 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres context.Memory.Read(inputBufferPosition, rawIp); // TODO: Use params. - uint socketLength = context.RequestData.ReadUInt32(); - uint type = context.RequestData.ReadUInt32(); - int timeOut = context.RequestData.ReadInt32(); +#pragma warning disable IDE0059 // Remove unnecessary value assignment + uint socketLength = context.RequestData.ReadUInt32(); + uint type = context.RequestData.ReadUInt32(); + int timeOut = context.RequestData.ReadInt32(); ulong pidPlaceholder = context.RequestData.ReadUInt64(); +#pragma warning restore IDE0059 if (withOptions) { @@ -406,21 +418,21 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres IPHostEntry hostEntry = null; NetDbError netDbErrorCode = NetDbError.Success; - GaiError errno = GaiError.AddressFamily; - int serializedSize = 0; + GaiError errno = GaiError.AddressFamily; + int serializedSize = 0; if (rawIp.Length == 4) { try { - IPAddress address = new IPAddress(rawIp); + IPAddress address = new(rawIp); hostEntry = Dns.GetHostEntry(address); } catch (SocketException exception) { netDbErrorCode = ConvertSocketErrorCodeToNetDbError(exception.ErrorCode); - errno = ConvertSocketErrorCodeToGaiError(exception.ErrorCode, errno); + errno = ConvertSocketErrorCodeToGaiError(exception.ErrorCode, errno); } } else @@ -430,7 +442,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres if (hostEntry != null) { - errno = GaiError.Success; + errno = GaiError.Success; serializedSize = SerializeHostEntries(context, outputBufferPosition, outputBufferSize, hostEntry, GetIpv4Addresses(hostEntry)); } @@ -442,7 +454,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres private static int SerializeHostEntries(ServiceCtx context, ulong outputBufferPosition, ulong outputBufferSize, IPHostEntry hostEntry, IEnumerable<IPAddress> addresses = null) { ulong originalBufferPosition = outputBufferPosition; - ulong bufferPosition = originalBufferPosition; + ulong bufferPosition = originalBufferPosition; string hostName = hostEntry.HostName + '\0'; @@ -494,9 +506,11 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres ulong optionsBufferSize) { bool enableNsdResolve = (context.RequestData.ReadInt32() & 1) != 0; - uint cancelHandle = context.RequestData.ReadUInt32(); +#pragma warning disable IDE0059 // Remove unnecessary value assignment + uint cancelHandle = context.RequestData.ReadUInt32(); +#pragma warning restore IDE0059 - string host = MemoryHelper.ReadAsciiString(context.Memory, context.Request.SendBuff[0].Position, (long)context.Request.SendBuff[0].Size); + string host = MemoryHelper.ReadAsciiString(context.Memory, context.Request.SendBuff[0].Position, (long)context.Request.SendBuff[0].Size); string service = MemoryHelper.ReadAsciiString(context.Memory, context.Request.SendBuff[1].Position, (long)context.Request.SendBuff[1].Size); if (!context.Device.Configuration.EnableInternetAccess) @@ -509,21 +523,27 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres } // NOTE: We ignore hints for now. +#pragma warning disable IDE0059 // Remove unnecessary value assignment List<AddrInfoSerialized> hints = DeserializeAddrInfos(context.Memory, context.Request.SendBuff[2].Position, context.Request.SendBuff[2].Size); +#pragma warning restore IDE0059 if (withOptions) { // TODO: Find unknown, Parse and use options. +#pragma warning disable IDE0059 // Remove unnecessary value assignment uint unknown = context.RequestData.ReadUInt32(); +#pragma warning restore IDE0059 } +#pragma warning disable IDE0059 // Remove unnecessary value assignment ulong pidPlaceHolder = context.RequestData.ReadUInt64(); +#pragma warning restore IDE0059 IPHostEntry hostEntry = null; NetDbError netDbErrorCode = NetDbError.Success; - GaiError errno = GaiError.AddressFamily; - int serializedSize = 0; + GaiError errno = GaiError.AddressFamily; + int serializedSize = 0; if (host.Length <= byte.MaxValue) { @@ -542,7 +562,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres Logger.Info?.Print(LogClass.ServiceSfdnsres, $"DNS Blocked: {host}"); netDbErrorCode = NetDbError.HostNotFound; - errno = GaiError.NoData; + errno = GaiError.NoData; } else { @@ -555,7 +575,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres catch (SocketException exception) { netDbErrorCode = ConvertSocketErrorCodeToNetDbError(exception.ErrorCode); - errno = ConvertSocketErrorCodeToGaiError(exception.ErrorCode, errno); + errno = ConvertSocketErrorCodeToGaiError(exception.ErrorCode, errno); } } } @@ -566,10 +586,15 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres if (hostEntry != null) { - int.TryParse(service, out int port); - - errno = GaiError.Success; - serializedSize = SerializeAddrInfos(context, responseBufferPosition, responseBufferSize, hostEntry, port); + if (int.TryParse(service, out int port)) + { + errno = GaiError.Success; + serializedSize = SerializeAddrInfos(context, responseBufferPosition, responseBufferSize, hostEntry, port); + } + else + { + errno = GaiError.Service; + } } WriteResponse(context, withOptions, serializedSize, errno, netDbErrorCode); @@ -601,37 +626,38 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres private static int SerializeAddrInfos(ServiceCtx context, ulong responseBufferPosition, ulong responseBufferSize, IPHostEntry hostEntry, int port) { ulong originalBufferPosition = responseBufferPosition; - ulong bufferPosition = originalBufferPosition; +#pragma warning disable IDE0059 // Remove unnecessary value assignment + ulong bufferPosition = originalBufferPosition; byte[] hostName = Encoding.ASCII.GetBytes(hostEntry.HostName + '\0'); +#pragma warning restore IDE0059 - using (WritableRegion region = context.Memory.GetWritableRegion(responseBufferPosition, (int)responseBufferSize)) - { - Span<byte> data = region.Memory.Span; + using WritableRegion region = context.Memory.GetWritableRegion(responseBufferPosition, (int)responseBufferSize); - for (int i = 0; i < hostEntry.AddressList.Length; i++) - { - IPAddress ip = hostEntry.AddressList[i]; + Span<byte> data = region.Memory.Span; - if (ip.AddressFamily != AddressFamily.InterNetwork) - { - continue; - } - - // NOTE: 0 = Any - AddrInfoSerializedHeader header = new(ip, 0); - AddrInfo4 addr = new(ip, (short)port); - AddrInfoSerialized info = new(header, addr, null, hostEntry.HostName); + for (int i = 0; i < hostEntry.AddressList.Length; i++) + { + IPAddress ip = hostEntry.AddressList[i]; - data = info.Write(data); + if (ip.AddressFamily != AddressFamily.InterNetwork) + { + continue; } - uint sentinel = 0; - MemoryMarshal.Write(data, ref sentinel); - data = data[sizeof(uint)..]; + // NOTE: 0 = Any + AddrInfoSerializedHeader header = new(ip, 0); + AddrInfo4 addr = new(ip, (short)port); + AddrInfoSerialized info = new(header, addr, null, hostEntry.HostName); - return region.Memory.Span.Length - data.Length; + data = info.Write(data); } + + uint sentinel = 0; + MemoryMarshal.Write(data, ref sentinel); + data = data[sizeof(uint)..]; + + return region.Memory.Span.Length - data.Length; } private static void WriteResponse( @@ -669,7 +695,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres 11002 => NetDbError.TryAgain, 11003 => NetDbError.NoRecovery, 11004 => NetDbError.NoData, - _ => NetDbError.Internal + _ => NetDbError.Internal, }; } @@ -679,8 +705,8 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres { 11001 => GaiError.NoData, 10060 => GaiError.Again, - _ => errno + _ => errno, }; } } -}
\ No newline at end of file +} |
