/
MsQuicHelpers.cs
85 lines (71 loc) · 2.83 KB
/
MsQuicHelpers.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System.Diagnostics;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Microsoft.Quic;
using static Microsoft.Quic.MsQuic;
namespace System.Net.Quic;
internal static class MsQuicHelpers
{
internal static bool TryParse(this EndPoint endPoint, out string? host, out IPAddress? address, out int port)
{
if (endPoint is DnsEndPoint dnsEndPoint)
{
host = IPAddress.TryParse(dnsEndPoint.Host, out address) ? null : dnsEndPoint.Host;
port = dnsEndPoint.Port;
return true;
}
if (endPoint is IPEndPoint ipEndPoint)
{
host = null;
address = ipEndPoint.Address;
port = ipEndPoint.Port;
return true;
}
host = default;
address = default;
port = default;
return false;
}
internal static unsafe IPEndPoint ToIPEndPoint(this ref QuicAddr quicAddress, AddressFamily? addressFamilyOverride = null)
{
// MsQuic always uses storage size as if IPv6 was used
Span<byte> addressBytes = new Span<byte>((byte*)Unsafe.AsPointer(ref quicAddress), Internals.SocketAddress.IPv6AddressSize);
return new Internals.SocketAddress(addressFamilyOverride ?? SocketAddressPal.GetAddressFamily(addressBytes), addressBytes).GetIPEndPoint();
}
internal static unsafe QuicAddr ToQuicAddr(this IPEndPoint ipEndPoint)
{
// TODO: is the layout same for SocketAddress.Buffer and QuicAddr on all platforms?
QuicAddr result = default;
Span<byte> rawAddress = MemoryMarshal.AsBytes(MemoryMarshal.CreateSpan(ref result, 1));
Internals.SocketAddress address = IPEndPointExtensions.Serialize(ipEndPoint);
Debug.Assert(address.Size <= rawAddress.Length);
address.Buffer.AsSpan(0, address.Size).CopyTo(rawAddress);
return result;
}
internal static unsafe T GetMsQuicParameter<T>(MsQuicSafeHandle handle, uint parameter)
where T : unmanaged
{
T value;
uint length = (uint)sizeof(T);
int status = MsQuicApi.Api.GetParam(
handle,
parameter,
&length,
(byte*)&value);
ThrowHelper.ThrowIfMsQuicError(status, $"GetParam({handle}, {parameter}) failed");
return value;
}
internal static unsafe void SetMsQuicParameter<T>(MsQuicSafeHandle handle, uint parameter, T value)
where T : unmanaged
{
int status = MsQuicApi.Api.SetParam(
handle,
parameter,
(uint)sizeof(T),
(byte*)&value);
ThrowHelper.ThrowIfMsQuicError(status, $"SetParam({handle}, {parameter}) failed");
}
}