mirror of
https://github.com/ryujinx-mirror/ryujinx.git
synced 2024-10-21 07:41:41 +00:00
137 lines
4 KiB
C#
137 lines
4 KiB
C#
|
using Ryujinx.Common.Memory;
|
|||
|
using Ryujinx.HLE.Utilities;
|
|||
|
using System;
|
|||
|
using System.Diagnostics;
|
|||
|
using System.Net.Sockets;
|
|||
|
using System.Runtime.CompilerServices;
|
|||
|
using System.Runtime.InteropServices;
|
|||
|
using System.Text;
|
|||
|
|
|||
|
namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres.Types
|
|||
|
{
|
|||
|
class AddrInfoSerialized
|
|||
|
{
|
|||
|
public AddrInfoSerializedHeader Header;
|
|||
|
public AddrInfo4? SocketAddress;
|
|||
|
public Array4<byte>? RawIPv4Address;
|
|||
|
public string CanonicalName;
|
|||
|
|
|||
|
public AddrInfoSerialized(AddrInfoSerializedHeader header, AddrInfo4? address, Array4<byte>? rawIPv4Address, string canonicalName)
|
|||
|
{
|
|||
|
Header = header;
|
|||
|
SocketAddress = address;
|
|||
|
RawIPv4Address = rawIPv4Address;
|
|||
|
CanonicalName = canonicalName;
|
|||
|
}
|
|||
|
|
|||
|
public static AddrInfoSerialized Read(ReadOnlySpan<byte> buffer, out ReadOnlySpan<byte> rest)
|
|||
|
{
|
|||
|
if (!MemoryMarshal.TryRead(buffer, out AddrInfoSerializedHeader header))
|
|||
|
{
|
|||
|
rest = buffer;
|
|||
|
|
|||
|
return null;
|
|||
|
}
|
|||
|
|
|||
|
AddrInfo4? socketAddress = null;
|
|||
|
Array4<byte>? rawIPv4Address = null;
|
|||
|
string canonicalName = null;
|
|||
|
|
|||
|
buffer = buffer[Unsafe.SizeOf<AddrInfoSerializedHeader>()..];
|
|||
|
|
|||
|
header.ToHostOrder();
|
|||
|
|
|||
|
if (header.Magic != SfdnsresContants.AddrInfoMagic)
|
|||
|
{
|
|||
|
rest = buffer;
|
|||
|
|
|||
|
return null;
|
|||
|
}
|
|||
|
|
|||
|
Debug.Assert(header.Magic == SfdnsresContants.AddrInfoMagic);
|
|||
|
|
|||
|
if (header.Family == (int)AddressFamily.InterNetwork)
|
|||
|
{
|
|||
|
socketAddress = MemoryMarshal.Read<AddrInfo4>(buffer);
|
|||
|
socketAddress.Value.ToHostOrder();
|
|||
|
|
|||
|
buffer = buffer[Unsafe.SizeOf<AddrInfo4>()..];
|
|||
|
}
|
|||
|
// AF_INET6
|
|||
|
else if (header.Family == 28)
|
|||
|
{
|
|||
|
throw new NotImplementedException();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// Nintendo hardcode 4 bytes in that case here.
|
|||
|
Array4<byte> address = MemoryMarshal.Read<Array4<byte>>(buffer);
|
|||
|
AddrInfo4.RawIpv4AddressNetworkEndianSwap(ref address);
|
|||
|
|
|||
|
rawIPv4Address = address;
|
|||
|
|
|||
|
buffer = buffer[Unsafe.SizeOf<Array4<byte>>()..];
|
|||
|
}
|
|||
|
|
|||
|
canonicalName = StringUtils.ReadUtf8String(buffer, out int dataRead);
|
|||
|
buffer = buffer[dataRead..];
|
|||
|
|
|||
|
rest = buffer;
|
|||
|
|
|||
|
return new AddrInfoSerialized(header, socketAddress, rawIPv4Address, canonicalName);
|
|||
|
}
|
|||
|
|
|||
|
public Span<byte> Write(Span<byte> buffer)
|
|||
|
{
|
|||
|
int familly = Header.Family;
|
|||
|
|
|||
|
Header.ToNetworkOrder();
|
|||
|
|
|||
|
MemoryMarshal.Write(buffer, ref Header);
|
|||
|
|
|||
|
buffer = buffer[Unsafe.SizeOf<AddrInfoSerializedHeader>()..];
|
|||
|
|
|||
|
if (familly == (int)AddressFamily.InterNetwork)
|
|||
|
{
|
|||
|
AddrInfo4 socketAddress = SocketAddress.Value;
|
|||
|
socketAddress.ToNetworkOrder();
|
|||
|
|
|||
|
MemoryMarshal.Write(buffer, ref socketAddress);
|
|||
|
|
|||
|
buffer = buffer[Unsafe.SizeOf<AddrInfo4>()..];
|
|||
|
}
|
|||
|
// AF_INET6
|
|||
|
else if (familly == 28)
|
|||
|
{
|
|||
|
throw new NotImplementedException();
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
Array4<byte> rawIPv4Address = RawIPv4Address.Value;
|
|||
|
AddrInfo4.RawIpv4AddressNetworkEndianSwap(ref rawIPv4Address);
|
|||
|
|
|||
|
MemoryMarshal.Write(buffer, ref rawIPv4Address);
|
|||
|
|
|||
|
buffer = buffer[Unsafe.SizeOf<Array4<byte>>()..];
|
|||
|
}
|
|||
|
|
|||
|
if (CanonicalName == null)
|
|||
|
{
|
|||
|
buffer[0] = 0;
|
|||
|
|
|||
|
buffer = buffer[1..];
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
byte[] canonicalName = Encoding.ASCII.GetBytes(CanonicalName + '\0');
|
|||
|
|
|||
|
canonicalName.CopyTo(buffer);
|
|||
|
|
|||
|
buffer = buffer[canonicalName.Length..];
|
|||
|
}
|
|||
|
|
|||
|
return buffer;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|