58 lines
2.5 KiB
C#
58 lines
2.5 KiB
C#
using System.Net;
|
|
using System.Security.Cryptography;
|
|
using System.Security.Cryptography.X509Certificates;
|
|
using Fleet.Core;
|
|
|
|
namespace MoShiro.Measurement.Tests;
|
|
|
|
public sealed class QuicSettingsTests
|
|
{
|
|
[Theory]
|
|
[InlineData(1100, null, false)]
|
|
[InlineData(null, 70_000, false)]
|
|
[InlineData(1400, 1300, false)]
|
|
[InlineData(1280, 1500, true)]
|
|
[InlineData(null, null, true)]
|
|
public void Validate_RejectsMtuOutsideTheSupportedRangeOrOutOfOrder(int? min, int? max, bool valid) =>
|
|
Assert.Equal(valid, new QuicSettings { MinMtu = min, MaxMtu = max }.Validate() is null);
|
|
|
|
/// <summary>设置真的写进了 MsQuic:最大 MTU 压低后数据报上限随之变小,最小 MTU 抬高后一连上就是大包(不用等路径探测)。</summary>
|
|
[Theory]
|
|
[InlineData(1200, 1280, 1200, 1280)]
|
|
[InlineData(1500, 1500, 1400, 1500)]
|
|
public async Task Settings_ChangeTheDatagramLimitOfTheConnection(int min, int max, int atLeast, int atMost)
|
|
{
|
|
var settings = new QuicSettings { MinMtu = min, MaxMtu = max };
|
|
var log = new NullLog();
|
|
using ECDsa key = ECDsa.Create(ECCurve.NamedCurves.nistP256);
|
|
var request = new CertificateRequest("CN=localhost", key, HashAlgorithmName.SHA256);
|
|
using X509Certificate2 certificate = request.CreateSelfSigned(DateTimeOffset.UnixEpoch, DateTimeOffset.UnixEpoch.AddYears(100));
|
|
await using var listener = new MsQuicListener(IPAddress.Loopback, [0], certificate, (_, _) => { }, log, null, settings);
|
|
listener.Start();
|
|
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(15));
|
|
MsQuicConnection client = await MsQuicConnection.ConnectAsync(IPAddress.Loopback, listener.BoundPorts[0], 0, key.ExportSubjectPublicKeyInfo(), (_, _) => { }, log, timeout.Token, settings);
|
|
try
|
|
{
|
|
while (!client.IsReady)
|
|
{
|
|
await Task.Delay(10, timeout.Token);
|
|
}
|
|
|
|
// 路径 MTU 探测还可能在往上走,给它一点时间;上限始终不能超过设置的最大 MTU
|
|
await Task.Delay(1500, timeout.Token);
|
|
Assert.InRange(client.MaxDatagramBytes, atLeast - 100, atMost);
|
|
}
|
|
finally
|
|
{
|
|
await client.DisposeAsync().AsTask().WaitAsync(TimeSpan.FromSeconds(3));
|
|
}
|
|
}
|
|
|
|
private sealed class NullLog : INodeLog
|
|
{
|
|
public void Write(NodeLogLevel level, string message, params (string Key, object? Value)[] fields)
|
|
{
|
|
}
|
|
}
|
|
}
|