// The .NET Foundation licenses this file to you under the MIT license.
using System.Net.Sockets;
+using System.Runtime.InteropServices;
using static System.Net.Quic.Implementations.MsQuic.Internal.MsQuicNativeMethods;
namespace System.Net.Quic.Implementations.MsQuic.Internal
internal const ushort IPv4 = 2;
internal const ushort IPv6 = 23;
- internal static IPEndPoint INetToIPEndPoint(ref SOCKADDR_INET inetAddress)
+ internal static unsafe IPEndPoint INetToIPEndPoint(ref SOCKADDR_INET inetAddress)
{
if (inetAddress.si_family == IPv4)
{
- return new IPEndPoint(new IPAddress(inetAddress.Ipv4.Address), (ushort)IPAddress.NetworkToHostOrder((short)inetAddress.Ipv4.sin_port));
+ return new IPEndPoint(new IPAddress(MemoryMarshal.CreateReadOnlySpan<byte>(ref inetAddress.Ipv4.sin_addr[0], 4)), (ushort)IPAddress.NetworkToHostOrder((short)inetAddress.Ipv4.sin_port));
}
else
{
- return new IPEndPoint(new IPAddress(inetAddress.Ipv6.Address), (ushort)IPAddress.NetworkToHostOrder((short)inetAddress.Ipv6._port));
+ return new IPEndPoint(new IPAddress(MemoryMarshal.CreateReadOnlySpan<byte>(ref inetAddress.Ipv6.sin6_addr[0], 16)), (ushort)IPAddress.NetworkToHostOrder((short)inetAddress.Ipv6.sin6_port));
}
}
- internal static SOCKADDR_INET IPEndPointToINet(IPEndPoint endpoint)
+ internal static unsafe SOCKADDR_INET IPEndPointToINet(IPEndPoint endpoint)
{
SOCKADDR_INET socketAddress = default;
byte[] buffer = endpoint.Address.GetAddressBytes();
switch (endpoint.Address.AddressFamily)
{
case AddressFamily.InterNetwork:
- socketAddress.Ipv4.sin_addr0 = buffer[0];
- socketAddress.Ipv4.sin_addr1 = buffer[1];
- socketAddress.Ipv4.sin_addr2 = buffer[2];
- socketAddress.Ipv4.sin_addr3 = buffer[3];
+ endpoint.Address.TryWriteBytes(MemoryMarshal.CreateSpan<byte>(ref socketAddress.Ipv4.sin_addr[0], 4), out _);
socketAddress.Ipv4.sin_family = IPv4;
break;
case AddressFamily.InterNetworkV6:
- socketAddress.Ipv6._addr0 = buffer[0];
- socketAddress.Ipv6._addr1 = buffer[1];
- socketAddress.Ipv6._addr2 = buffer[2];
- socketAddress.Ipv6._addr3 = buffer[3];
- socketAddress.Ipv6._addr4 = buffer[4];
- socketAddress.Ipv6._addr5 = buffer[5];
- socketAddress.Ipv6._addr6 = buffer[6];
- socketAddress.Ipv6._addr7 = buffer[7];
- socketAddress.Ipv6._addr8 = buffer[8];
- socketAddress.Ipv6._addr9 = buffer[9];
- socketAddress.Ipv6._addr10 = buffer[10];
- socketAddress.Ipv6._addr11 = buffer[11];
- socketAddress.Ipv6._addr12 = buffer[12];
- socketAddress.Ipv6._addr13 = buffer[13];
- socketAddress.Ipv6._addr14 = buffer[14];
- socketAddress.Ipv6._addr15 = buffer[15];
- socketAddress.Ipv6._family = IPv6;
+ endpoint.Address.TryWriteBytes(MemoryMarshal.CreateSpan<byte>(ref socketAddress.Ipv6.sin6_addr[0], 16), out _);
+ socketAddress.Ipv6.sin6_family = IPv6;
break;
default:
throw new ArgumentException(SR.net_quic_addressfamily_notsupported);
private static void SetPort(AddressFamily addressFamily, ref SOCKADDR_INET socketAddrInet, int originalPort)
{
ushort convertedPort = (ushort)IPAddress.HostToNetworkOrder((short)originalPort);
- switch (addressFamily)
- {
- case AddressFamily.InterNetwork:
- socketAddrInet.Ipv4.sin_port = convertedPort;
- break;
- case AddressFamily.InterNetworkV6:
- default:
- socketAddrInet.Ipv6._port = convertedPort;
- break;
- }
+ socketAddrInet.Ipv4.sin_port = convertedPort;
}
}
}
{
internal ushort sin_family;
internal ushort sin_port;
- internal byte sin_addr0;
- internal byte sin_addr1;
- internal byte sin_addr2;
- internal byte sin_addr3;
-
- internal byte[] Address
- {
- get
- {
- return new byte[] { sin_addr0, sin_addr1, sin_addr2, sin_addr3 };
- }
- }
+ internal fixed byte sin_addr[4];
}
// TODO: rename to C#-like
[StructLayout(LayoutKind.Sequential)]
internal struct SOCKADDR_IN6
{
- internal ushort _family;
- internal ushort _port;
- internal uint _flowinfo;
- internal byte _addr0;
- internal byte _addr1;
- internal byte _addr2;
- internal byte _addr3;
- internal byte _addr4;
- internal byte _addr5;
- internal byte _addr6;
- internal byte _addr7;
- internal byte _addr8;
- internal byte _addr9;
- internal byte _addr10;
- internal byte _addr11;
- internal byte _addr12;
- internal byte _addr13;
- internal byte _addr14;
- internal byte _addr15;
- internal uint _scope_id;
-
- internal byte[] Address
- {
- get
- {
- return new byte[] {
- _addr0, _addr1, _addr2, _addr3,
- _addr4, _addr5, _addr6, _addr7,
- _addr8, _addr9, _addr10, _addr11,
- _addr12, _addr13, _addr14, _addr15 };
- }
- }
+ internal ushort sin6_family;
+ internal ushort sin6_port;
+ internal uint sin6_flowinfo;
+ internal fixed byte sin6_addr[16];
+ internal uint sin6_scope_id;
}
// TODO: rename to C#-like