sfdnsres: Implement NSD resolution (#2962)

This fix a missing implementation usage of NSD on IResolver when
requested on GetAddrInfoRequest* and GetHostByNameRequest*.
This commit is contained in:
Mary 2022-01-03 22:12:50 +01:00 committed by GitHub
parent e24be5edfc
commit 60f03cb78a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 32 deletions

View file

@ -13,12 +13,19 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd
[Service("nsd:u")] // Max sessions: 20 [Service("nsd:u")] // Max sessions: 20
class IManager : IpcService class IManager : IpcService
{ {
private readonly NsdSettings _nsdSettings; public static readonly NsdSettings NsdSettings;
private readonly FqdnResolver _fqdnResolver; private readonly FqdnResolver _fqdnResolver;
private bool _isInitialized = false; private bool _isInitialized = false;
public IManager(ServiceCtx context) public IManager(ServiceCtx context)
{
_fqdnResolver = new FqdnResolver();
_isInitialized = true;
}
static IManager()
{ {
// TODO: Load nsd settings through the savedata 0x80000000000000B0 (nsdsave:/). // TODO: Load nsd settings through the savedata 0x80000000000000B0 (nsdsave:/).
@ -32,16 +39,12 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd
// return ResultCode.InvalidSettingsValue; // return ResultCode.InvalidSettingsValue;
} }
_nsdSettings = new NsdSettings NsdSettings = new NsdSettings
{ {
Initialized = true, Initialized = true,
TestMode = (bool)testMode, TestMode = (bool)testMode,
Environment = (string)environmentIdentifier Environment = (string)environmentIdentifier
}; };
_fqdnResolver = new FqdnResolver(_nsdSettings);
_isInitialized = true;
} }
[CommandHipc(5)] // 11.0.0+ [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); 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. // 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; return ResultCode.InvalidSettingsValue;
} }
@ -327,7 +330,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd
} }
*/ */
if (!_nsdSettings.TestMode) if (!NsdSettings.TestMode)
{ {
return ResultCode.InvalidSettingsValue; return ResultCode.InvalidSettingsValue;
} }

View file

@ -6,16 +6,9 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd.Manager
{ {
private const string _dummyAddress = "unknown.dummy.nintendo.net"; private const string _dummyAddress = "unknown.dummy.nintendo.net";
private NsdSettings _nsdSettings;
public FqdnResolver(NsdSettings nsdSettings)
{
_nsdSettings = nsdSettings;
}
public ResultCode GetEnvironmentIdentifier(out string identifier) public ResultCode GetEnvironmentIdentifier(out string identifier)
{ {
if (_nsdSettings.TestMode) if (IManager.NsdSettings.TestMode)
{ {
identifier = "err"; identifier = "err";
@ -23,13 +16,13 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd.Manager
} }
else else
{ {
identifier = _nsdSettings.Environment; identifier = IManager.NsdSettings.Environment;
} }
return ResultCode.Success; 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" || if (address == "api.sect.srv.nintendo.net" ||
address == "ctest.cdn.nintendo.net" || address == "ctest.cdn.nintendo.net" ||
@ -41,16 +34,16 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd.Manager
else else
{ {
// TODO: Load Environment from the savedata. // TODO: Load Environment from the savedata.
address = address.Replace("%", _nsdSettings.Environment); address = address.Replace("%", IManager.NsdSettings.Environment);
resolvedAddress = ""; resolvedAddress = "";
if (_nsdSettings == null) if (IManager.NsdSettings == null)
{ {
return ResultCode.SettingsNotInitialized; return ResultCode.SettingsNotInitialized;
} }
if (!_nsdSettings.Initialized) if (!IManager.NsdSettings.Initialized)
{ {
return ResultCode.SettingsNotLoaded; return ResultCode.SettingsNotLoaded;
} }
@ -84,14 +77,14 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Nsd.Manager
string address = Encoding.UTF8.GetString(addressBuffer).TrimEnd('\0'); string address = Encoding.UTF8.GetString(addressBuffer).TrimEnd('\0');
resultCode = Resolve(context, address, out resolvedAddress); resultCode = Resolve(address, out resolvedAddress);
if (resultCode != ResultCode.Success) if (resultCode != ResultCode.Success)
{ {
resolvedAddress = _dummyAddress; resolvedAddress = _dummyAddress;
} }
if (_nsdSettings.TestMode) if (IManager.NsdSettings.TestMode)
{ {
return ResultCode.Success; return ResultCode.Success;
} }

View file

@ -1,5 +1,6 @@
using Ryujinx.Common.Logging; using Ryujinx.Common.Logging;
using Ryujinx.Cpu; 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.Proxy;
using Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres.Types; using Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres.Types;
using Ryujinx.Memory; using Ryujinx.Memory;
@ -242,7 +243,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
ulong optionsBufferPosition, ulong optionsBufferPosition,
ulong optionsBufferSize) ulong optionsBufferSize)
{ {
string name = MemoryHelper.ReadAsciiString(context.Memory, inputBufferPosition, (int)inputBufferSize); string host = MemoryHelper.ReadAsciiString(context.Memory, inputBufferPosition, (int)inputBufferSize);
// TODO: Use params. // TODO: Use params.
bool enableNsdResolve = (context.RequestData.ReadInt32() & 1) != 0; bool enableNsdResolve = (context.RequestData.ReadInt32() & 1) != 0;
@ -260,20 +261,28 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
GaiError errno = GaiError.Overflow; GaiError errno = GaiError.Overflow;
ulong serializedSize = 0; ulong serializedSize = 0;
if (name.Length <= byte.MaxValue) if (host.Length <= byte.MaxValue)
{ {
string targetHost = name; if (enableNsdResolve)
{
if (FqdnResolver.Resolve(host, out string newAddress) == Nsd.ResultCode.Success)
{
host = newAddress;
}
}
if (DnsBlacklist.IsHostBlocked(name)) string targetHost = host;
if (DnsBlacklist.IsHostBlocked(host))
{ {
Logger.Info?.Print(LogClass.ServiceSfdnsres, $"DNS Blocked: {name}"); Logger.Info?.Print(LogClass.ServiceSfdnsres, $"DNS Blocked: {host}");
netDbErrorCode = NetDbError.HostNotFound; netDbErrorCode = NetDbError.HostNotFound;
errno = GaiError.NoData; errno = GaiError.NoData;
} }
else else
{ {
Logger.Info?.Print(LogClass.ServiceSfdnsres, $"Trying to resolve: {name}"); Logger.Info?.Print(LogClass.ServiceSfdnsres, $"Trying to resolve: {host}");
try try
{ {
@ -452,6 +461,14 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
if (host.Length <= byte.MaxValue) if (host.Length <= byte.MaxValue)
{ {
if (enableNsdResolve)
{
if (FqdnResolver.Resolve(host, out string newAddress) == Nsd.ResultCode.Success)
{
host = newAddress;
}
}
string targetHost = host; string targetHost = host;
if (DnsBlacklist.IsHostBlocked(host)) if (DnsBlacklist.IsHostBlocked(host))