Skip to content

Commit

Permalink
Refactor MsQuic's native IP address types. (#53461)
Browse files Browse the repository at this point in the history
* Use fixed buffers in MsQuic's native IP address types.
And handle them more efficiently when moving between them and .NET's IPAddresses.

* Update the names of all SOCKADDR_IN6's fields.

* Remove a redundant switch in MsQuicAddressHelpers.SetPort.
  • Loading branch information
teo-tsirpanis authored May 31, 2021
1 parent d5cef92 commit 3846a9c
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// 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
Expand All @@ -11,19 +12,19 @@ internal static class MsQuicAddressHelpers
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();
Expand All @@ -32,30 +33,12 @@ internal static SOCKADDR_INET IPEndPointToINet(IPEndPoint endpoint)
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);
Expand All @@ -69,16 +52,7 @@ internal static SOCKADDR_INET IPEndPointToINet(IPEndPoint endpoint)
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;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -588,56 +588,18 @@ internal struct SOCKADDR_IN
{
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
Expand Down

0 comments on commit 3846a9c

Please sign in to comment.