From 60f03cb78a4c7b66ee72dbbfee4b1998474a604a Mon Sep 17 00:00:00 2001 From: Mary Date: Mon, 3 Jan 2022 22:12:50 +0100 Subject: [PATCH] sfdnsres: Implement NSD resolution (#2962) This fix a missing implementation usage of NSD on IResolver when requested on GetAddrInfoRequest* and GetHostByNameRequest*. --- .../HOS/Services/Sockets/Nsd/IManager.cs | 23 ++++++++------ .../Sockets/Nsd/Manager/FqdnResolver.cs | 23 +++++--------- .../Services/Sockets/Sfdnsres/IResolver.cs | 31 ++++++++++++++----- 3 files changed, 45 insertions(+), 32 deletions(-) diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Nsd/IManager.cs b/Ryujinx.HLE/HOS/Services/Sockets/Nsd/IManager.cs index a9bd7ff815..647fb395ab 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Nsd/IManager.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Nsd/IManager.cs @@ -13,12 +13,19 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd [Service("nsd:u")] // Max sessions: 20 class IManager : IpcService { - private readonly NsdSettings _nsdSettings; + public static readonly NsdSettings NsdSettings; private readonly FqdnResolver _fqdnResolver; private bool _isInitialized = false; public IManager(ServiceCtx context) + { + _fqdnResolver = new FqdnResolver(); + + _isInitialized = true; + } + + static IManager() { // TODO: Load nsd settings through the savedata 0x80000000000000B0 (nsdsave:/). @@ -32,16 +39,12 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd // return ResultCode.InvalidSettingsValue; } - _nsdSettings = new NsdSettings + NsdSettings = new NsdSettings { Initialized = true, - TestMode = (bool)testMode, + TestMode = (bool)testMode, Environment = (string)environmentIdentifier }; - - _fqdnResolver = new FqdnResolver(_nsdSettings); - - _isInitialized = true; } [CommandHipc(5)] // 11.0.0+ @@ -107,7 +110,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd { NxSettings.Settings.TryGetValue("nsd!environment_identifier", out object environmentIdentifier); - if ((string)environmentIdentifier == _nsdSettings.Environment) + if ((string)environmentIdentifier == NsdSettings.Environment) { // TODO: Call nn::fs::DeleteSystemFile() to delete the savedata file and return ResultCode. } @@ -298,7 +301,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd } */ - if (!_nsdSettings.TestMode) + if (!NsdSettings.TestMode) { return ResultCode.InvalidSettingsValue; } @@ -327,7 +330,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd } */ - if (!_nsdSettings.TestMode) + if (!NsdSettings.TestMode) { return ResultCode.InvalidSettingsValue; } diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Manager/FqdnResolver.cs b/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Manager/FqdnResolver.cs index 2e23f3fb1c..4096e431f1 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Manager/FqdnResolver.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Nsd/Manager/FqdnResolver.cs @@ -6,16 +6,9 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd.Manager { private const string _dummyAddress = "unknown.dummy.nintendo.net"; - private NsdSettings _nsdSettings; - - public FqdnResolver(NsdSettings nsdSettings) - { - _nsdSettings = nsdSettings; - } - public ResultCode GetEnvironmentIdentifier(out string identifier) { - if (_nsdSettings.TestMode) + if (IManager.NsdSettings.TestMode) { identifier = "err"; @@ -23,13 +16,13 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd.Manager } else { - identifier = _nsdSettings.Environment; + identifier = IManager.NsdSettings.Environment; } return ResultCode.Success; } - public ResultCode Resolve(ServiceCtx context, string address, out string resolvedAddress) + public static ResultCode Resolve(string address, out string resolvedAddress) { if (address == "api.sect.srv.nintendo.net" || address == "ctest.cdn.nintendo.net" || @@ -41,16 +34,16 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd.Manager else { // TODO: Load Environment from the savedata. - address = address.Replace("%", _nsdSettings.Environment); + address = address.Replace("%", IManager.NsdSettings.Environment); resolvedAddress = ""; - if (_nsdSettings == null) + if (IManager.NsdSettings == null) { return ResultCode.SettingsNotInitialized; } - if (!_nsdSettings.Initialized) + if (!IManager.NsdSettings.Initialized) { return ResultCode.SettingsNotLoaded; } @@ -84,14 +77,14 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd.Manager string address = Encoding.UTF8.GetString(addressBuffer).TrimEnd('\0'); - resultCode = Resolve(context, address, out resolvedAddress); + resultCode = Resolve(address, out resolvedAddress); if (resultCode != ResultCode.Success) { resolvedAddress = _dummyAddress; } - if (_nsdSettings.TestMode) + if (IManager.NsdSettings.TestMode) { return ResultCode.Success; } diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs b/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs index c569915f62..32346dc7b1 100644 --- a/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs +++ b/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs @@ -1,5 +1,6 @@ using Ryujinx.Common.Logging; using Ryujinx.Cpu; +using Ryujinx.HLE.HOS.Services.Sockets.Nsd.Manager; using Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres.Proxy; using Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres.Types; using Ryujinx.Memory; @@ -242,7 +243,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres ulong optionsBufferPosition, ulong optionsBufferSize) { - string name = MemoryHelper.ReadAsciiString(context.Memory, inputBufferPosition, (int)inputBufferSize); + string host = MemoryHelper.ReadAsciiString(context.Memory, inputBufferPosition, (int)inputBufferSize); // TODO: Use params. bool enableNsdResolve = (context.RequestData.ReadInt32() & 1) != 0; @@ -260,20 +261,28 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres GaiError errno = GaiError.Overflow; ulong serializedSize = 0; - if (name.Length <= byte.MaxValue) + if (host.Length <= byte.MaxValue) { - string targetHost = name; - - if (DnsBlacklist.IsHostBlocked(name)) + if (enableNsdResolve) { - Logger.Info?.Print(LogClass.ServiceSfdnsres, $"DNS Blocked: {name}"); + if (FqdnResolver.Resolve(host, out string newAddress) == Nsd.ResultCode.Success) + { + host = newAddress; + } + } + + string targetHost = host; + + if (DnsBlacklist.IsHostBlocked(host)) + { + Logger.Info?.Print(LogClass.ServiceSfdnsres, $"DNS Blocked: {host}"); netDbErrorCode = NetDbError.HostNotFound; errno = GaiError.NoData; } else { - Logger.Info?.Print(LogClass.ServiceSfdnsres, $"Trying to resolve: {name}"); + Logger.Info?.Print(LogClass.ServiceSfdnsres, $"Trying to resolve: {host}"); try { @@ -452,6 +461,14 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres if (host.Length <= byte.MaxValue) { + if (enableNsdResolve) + { + if (FqdnResolver.Resolve(host, out string newAddress) == Nsd.ResultCode.Success) + { + host = newAddress; + } + } + string targetHost = host; if (DnsBlacklist.IsHostBlocked(host))