Fix GetHostByNameRequestWithOptions and GetHostByAddrRequestWithOptions (#2943)

This commit is contained in:
gdkchan 2021-12-28 08:22:58 -03:00 committed by GitHub
parent f65d01b5d3
commit 6dacc4c577
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -57,7 +57,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
ulong outputBufferPosition = context.Request.ReceiveBuff[0].Position; 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, 0, 0); return GetHostByNameRequestImpl(context, inputBufferPosition, inputBufferSize, outputBufferPosition, outputBufferSize, false, 0, 0);
} }
[CommandHipc(3)] [CommandHipc(3)]
@ -70,7 +70,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
ulong outputBufferPosition = context.Request.ReceiveBuff[0].Position; 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, 0, 0); return GetHostByAddrRequestImpl(context, inputBufferPosition, inputBufferSize, outputBufferPosition, outputBufferSize, false, 0, 0);
} }
[CommandHipc(4)] [CommandHipc(4)]
@ -192,7 +192,15 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
(ulong outputBufferPosition, ulong outputBufferSize) = context.Request.GetBufferType0x22(); (ulong outputBufferPosition, ulong outputBufferSize) = context.Request.GetBufferType0x22();
(ulong optionsBufferPosition, ulong optionsBufferSize) = context.Request.GetBufferType0x21(); (ulong optionsBufferPosition, ulong optionsBufferSize) = context.Request.GetBufferType0x21();
return GetHostByNameRequestImpl(context, inputBufferPosition, inputBufferSize, outputBufferPosition, outputBufferSize, optionsBufferPosition, optionsBufferSize); return GetHostByNameRequestImpl(
context,
inputBufferPosition,
inputBufferSize,
outputBufferPosition,
outputBufferSize,
true,
optionsBufferPosition,
optionsBufferSize);
} }
[CommandHipc(11)] // 5.0.0+ [CommandHipc(11)] // 5.0.0+
@ -203,20 +211,36 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
(ulong outputBufferPosition, ulong outputBufferSize) = context.Request.GetBufferType0x22(); (ulong outputBufferPosition, ulong outputBufferSize) = context.Request.GetBufferType0x22();
(ulong optionsBufferPosition, ulong optionsBufferSize) = context.Request.GetBufferType0x21(); (ulong optionsBufferPosition, ulong optionsBufferSize) = context.Request.GetBufferType0x21();
return GetHostByAddrRequestImpl(context, inputBufferPosition, inputBufferSize, outputBufferPosition, outputBufferSize, optionsBufferPosition, optionsBufferSize); return GetHostByAddrRequestImpl(
context,
inputBufferPosition,
inputBufferSize,
outputBufferPosition,
outputBufferSize,
true,
optionsBufferPosition,
optionsBufferSize);
} }
[CommandHipc(12)] // 5.0.0+ [CommandHipc(12)] // 5.0.0+
// 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) // 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) public ResultCode GetAddrInfoRequestWithOptions(ServiceCtx context)
{ {
(ulong responseBufferPosition, ulong responseBufferSize) = context.Request.GetBufferType0x22(); (ulong outputBufferPosition, ulong outputBufferSize) = context.Request.GetBufferType0x22();
(ulong optionsBufferPosition, ulong optionsBufferSize) = context.Request.GetBufferType0x21(); (ulong optionsBufferPosition, ulong optionsBufferSize) = context.Request.GetBufferType0x21();
return GetAddrInfoRequestImpl(context, responseBufferPosition, responseBufferSize, true, optionsBufferPosition, optionsBufferSize); return GetAddrInfoRequestImpl(context, outputBufferPosition, outputBufferSize, true, optionsBufferPosition, optionsBufferSize);
} }
private ResultCode GetHostByNameRequestImpl(ServiceCtx context, ulong inputBufferPosition, ulong inputBufferSize, ulong outputBufferPosition, ulong outputBufferSize, ulong optionsBufferPosition, ulong optionsBufferSize) private static ResultCode GetHostByNameRequestImpl(
ServiceCtx context,
ulong inputBufferPosition,
ulong inputBufferSize,
ulong outputBufferPosition,
ulong outputBufferSize,
bool withOptions,
ulong optionsBufferPosition,
ulong optionsBufferSize)
{ {
string name = MemoryHelper.ReadAsciiString(context.Memory, inputBufferPosition, (int)inputBufferSize); string name = MemoryHelper.ReadAsciiString(context.Memory, inputBufferPosition, (int)inputBufferSize);
@ -225,7 +249,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
int timeOut = context.RequestData.ReadInt32(); int timeOut = context.RequestData.ReadInt32();
ulong pidPlaceholder = context.RequestData.ReadUInt64(); ulong pidPlaceholder = context.RequestData.ReadUInt64();
if (optionsBufferSize > 0) if (withOptions)
{ {
// TODO: Parse and use options. // TODO: Parse and use options.
} }
@ -283,14 +307,20 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
} }
} }
context.ResponseData.Write((int)netDbErrorCode); WriteResponse(context, withOptions, serializedSize, errno, netDbErrorCode);
context.ResponseData.Write((int)errno);
context.ResponseData.Write(serializedSize);
return ResultCode.Success; return ResultCode.Success;
} }
private ResultCode GetHostByAddrRequestImpl(ServiceCtx context, ulong inputBufferPosition, ulong inputBufferSize, ulong outputBufferPosition, ulong outputBufferSize, ulong optionsBufferPosition, ulong optionsBufferSize) private static ResultCode GetHostByAddrRequestImpl(
ServiceCtx context,
ulong inputBufferPosition,
ulong inputBufferSize,
ulong outputBufferPosition,
ulong outputBufferSize,
bool withOptions,
ulong optionsBufferPosition,
ulong optionsBufferSize)
{ {
byte[] rawIp = new byte[inputBufferSize]; byte[] rawIp = new byte[inputBufferSize];
@ -302,7 +332,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
int timeOut = context.RequestData.ReadInt32(); int timeOut = context.RequestData.ReadInt32();
ulong pidPlaceholder = context.RequestData.ReadUInt64(); ulong pidPlaceholder = context.RequestData.ReadUInt64();
if (optionsBufferSize > 0) if (withOptions)
{ {
// TODO: Parse and use options. // TODO: Parse and use options.
} }
@ -338,14 +368,12 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
serializedSize = SerializeHostEntries(context, outputBufferPosition, outputBufferSize, hostEntry, GetIpv4Addresses(hostEntry)); serializedSize = SerializeHostEntries(context, outputBufferPosition, outputBufferSize, hostEntry, GetIpv4Addresses(hostEntry));
} }
context.ResponseData.Write((int)netDbErrorCode); WriteResponse(context, withOptions, serializedSize, errno, netDbErrorCode);
context.ResponseData.Write((int)errno);
context.ResponseData.Write(serializedSize);
return ResultCode.Success; return ResultCode.Success;
} }
private ulong SerializeHostEntries(ServiceCtx context, ulong outputBufferPosition, ulong outputBufferSize, IPHostEntry hostEntry, IEnumerable<IPAddress> addresses = null) private static ulong SerializeHostEntries(ServiceCtx context, ulong outputBufferPosition, ulong outputBufferSize, IPHostEntry hostEntry, IEnumerable<IPAddress> addresses = null)
{ {
ulong originalBufferPosition = outputBufferPosition; ulong originalBufferPosition = outputBufferPosition;
ulong bufferPosition = originalBufferPosition; ulong bufferPosition = originalBufferPosition;
@ -391,7 +419,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
return bufferPosition - originalBufferPosition; return bufferPosition - originalBufferPosition;
} }
private ResultCode GetAddrInfoRequestImpl( private static ResultCode GetAddrInfoRequestImpl(
ServiceCtx context, ServiceCtx context,
ulong responseBufferPosition, ulong responseBufferPosition,
ulong responseBufferSize, ulong responseBufferSize,
@ -416,8 +444,6 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
ulong pidPlaceHolder = context.RequestData.ReadUInt64(); ulong pidPlaceHolder = context.RequestData.ReadUInt64();
Logger.Stub?.PrintStub(LogClass.ServiceSfdnsres, new { enableNsdResolve, cancelHandle, pidPlaceHolder, host, service });
IPHostEntry hostEntry = null; IPHostEntry hostEntry = null;
NetDbError netDbErrorCode = NetDbError.Success; NetDbError netDbErrorCode = NetDbError.Success;
@ -463,24 +489,12 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
serializedSize = SerializeAddrInfos(context, responseBufferPosition, responseBufferSize, hostEntry, port); serializedSize = SerializeAddrInfos(context, responseBufferPosition, responseBufferSize, hostEntry, port);
} }
if (withOptions) WriteResponse(context, withOptions, serializedSize, errno, netDbErrorCode);
{
context.ResponseData.Write(serializedSize);
context.ResponseData.Write((int)errno);
context.ResponseData.Write((int)netDbErrorCode);
context.ResponseData.Write(0);
}
else
{
context.ResponseData.Write((int)netDbErrorCode);
context.ResponseData.Write((int)errno);
context.ResponseData.Write(serializedSize);
}
return ResultCode.Success; return ResultCode.Success;
} }
private void DeserializeAddrInfos(IVirtualMemoryManager memory, ulong address, ulong size) private static void DeserializeAddrInfos(IVirtualMemoryManager memory, ulong address, ulong size)
{ {
ulong endAddress = address + size; ulong endAddress = address + size;
@ -496,23 +510,11 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
address += (ulong)Unsafe.SizeOf<AddrInfoSerializedHeader>() + header.AddressLength; address += (ulong)Unsafe.SizeOf<AddrInfoSerializedHeader>() + header.AddressLength;
// ai_canonname // ai_canonname
string canonname = string.Empty; string canonname = MemoryHelper.ReadAsciiString(memory, address);
while (true)
{
byte chr = memory.Read<byte>(address++);
if (chr == 0)
{
break;
}
canonname += (char)chr;
}
} }
} }
private ulong SerializeAddrInfos(ServiceCtx context, ulong responseBufferPosition, ulong responseBufferSize, IPHostEntry hostEntry, int port) private static ulong SerializeAddrInfos(ServiceCtx context, ulong responseBufferPosition, ulong responseBufferSize, IPHostEntry hostEntry, int port)
{ {
ulong originalBufferPosition = (ulong)responseBufferPosition; ulong originalBufferPosition = (ulong)responseBufferPosition;
ulong bufferPosition = originalBufferPosition; ulong bufferPosition = originalBufferPosition;
@ -550,12 +552,34 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
return bufferPosition - originalBufferPosition; return bufferPosition - originalBufferPosition;
} }
private IEnumerable<IPAddress> GetIpv4Addresses(IPHostEntry hostEntry) private static void WriteResponse(
ServiceCtx context,
bool withOptions,
ulong serializedSize,
GaiError errno,
NetDbError netDbErrorCode)
{
if (withOptions)
{
context.ResponseData.Write((int)serializedSize);
context.ResponseData.Write((int)errno);
context.ResponseData.Write((int)netDbErrorCode);
context.ResponseData.Write(0);
}
else
{
context.ResponseData.Write((int)netDbErrorCode);
context.ResponseData.Write((int)errno);
context.ResponseData.Write((int)serializedSize);
}
}
private static IEnumerable<IPAddress> GetIpv4Addresses(IPHostEntry hostEntry)
{ {
return hostEntry.AddressList.Where(x => x.AddressFamily == AddressFamily.InterNetwork); return hostEntry.AddressList.Where(x => x.AddressFamily == AddressFamily.InterNetwork);
} }
private NetDbError ConvertSocketErrorCodeToNetDbError(int errorCode) private static NetDbError ConvertSocketErrorCodeToNetDbError(int errorCode)
{ {
return errorCode switch return errorCode switch
{ {
@ -567,7 +591,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
}; };
} }
private GaiError ConvertSocketErrorCodeToGaiError(int errorCode, GaiError errno) private static GaiError ConvertSocketErrorCodeToGaiError(int errorCode, GaiError errno)
{ {
return errorCode switch return errorCode switch
{ {