feat(quic): replace probe UDP data plane with QUIC datagrams
This commit is contained in:
1 parent
4609048865
commit
b964dc2bbc
53 files changed
+2413
-411
No files matched your search
@@ -11,7 +11,7 @@ namespace MoShiro.Measurement;
|
||||
internal sealed class EchoRows
|
||||
{
|
||||
/// <summary>UDP:没有在这段时间内回来的包就是丢了。</summary>
|
||||
public const long UdpGraceUs = 2_000_000;
|
||||
public const long DatagramGraceUs = 2_000_000;
|
||||
|
||||
/// <summary>
|
||||
/// TCP 不会丢包,只会延迟(重传、队头阻塞):一次几秒的中断之后,积压的回显会陆续回来,RTT 就是那几秒。
|
||||
@@ -65,26 +65,27 @@ internal sealed class EchoRows
|
||||
/// <summary>
|
||||
/// UDP 回显,拨号方(Probe):按声明的速率发包,t1 在发出时记录,回复到达时回填 t4。回复丢失的行 t4 缺失(Agent 一侧再补 t2/t3)。
|
||||
/// </summary>
|
||||
public sealed class UdpEchoDialer : BlockBase
|
||||
public sealed class DatagramEchoDialer : BlockBase
|
||||
{
|
||||
private readonly EchoRows _rows;
|
||||
|
||||
public UdpEchoDialer(BlockEnv env, BlockSpec spec)
|
||||
public DatagramEchoDialer(BlockEnv env, BlockSpec spec)
|
||||
: base(env, spec)
|
||||
{
|
||||
_rows = new EchoRows(spec.Kind, 16384, EchoRows.UdpGraceUs, settleOnReply: false);
|
||||
_rows = new EchoRows(spec.Kind, 16384, EchoRows.DatagramGraceUs, settleOnReply: false);
|
||||
}
|
||||
|
||||
public override long Produced => _rows.Count;
|
||||
|
||||
public override async Task RunAsync(CancellationToken ct)
|
||||
{
|
||||
UdpMux udp = Env.Udp!;
|
||||
QuicDatagramTransport datagrams = Env.Datagrams!;
|
||||
DataSession session = Env.Session() ?? throw new BlockFaultException("no data session");
|
||||
await datagrams.WaitUntilConnectedAsync(ct);
|
||||
IPEndPoint target = PeerEndpoint(Spec.Port);
|
||||
int size = (int)Spec.Int("size");
|
||||
byte[] packet = new byte[size];
|
||||
udp.Register(Spec.StreamId, OnPacket);
|
||||
datagrams.Register(Spec.StreamId, OnPacket);
|
||||
try
|
||||
{
|
||||
using var timer = new PeriodicTimer(TimeSpan.FromSeconds(1.0 / Spec.Int("rate_hz")), Env.Time);
|
||||
@@ -92,8 +93,8 @@ public sealed class UdpEchoDialer : BlockBase
|
||||
{
|
||||
long t1 = Env.Clock.NowUs();
|
||||
uint seq = _rows.Add(size, t1);
|
||||
UdpPacket.Write(packet, new UdpHeader(UdpPacketType.EchoRequest, session.SessionId, Spec.StreamId, seq, t1), session.Key);
|
||||
udp.Send(target, packet);
|
||||
MeasurementDatagram.Write(packet, new MeasurementDatagramHeader(MeasurementDatagramType.EchoRequest, session.SessionId, Spec.StreamId, seq, t1), session.Key);
|
||||
datagrams.Send(session, target, packet);
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
@@ -102,7 +103,7 @@ public sealed class UdpEchoDialer : BlockBase
|
||||
}
|
||||
finally
|
||||
{
|
||||
udp.Unregister(Spec.StreamId);
|
||||
datagrams.Unregister(Spec.StreamId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,9 +119,9 @@ public sealed class UdpEchoDialer : BlockBase
|
||||
return 1;
|
||||
}
|
||||
|
||||
private void OnPacket(in UdpDelivery delivery)
|
||||
private void OnPacket(in QuicDatagramDelivery delivery)
|
||||
{
|
||||
if (delivery.Header.Type == UdpPacketType.EchoReply)
|
||||
if (delivery.Header.Type == MeasurementDatagramType.EchoReply)
|
||||
{
|
||||
_rows.Reply(delivery.Header.Seq, delivery.ReceiveUs);
|
||||
}
|
||||
@@ -128,11 +129,11 @@ public sealed class UdpEchoDialer : BlockBase
|
||||
}
|
||||
|
||||
/// <summary>UDP 回显,监听方(Agent):校验后立即回复一个等长的包,记录 t2(到达)和 t3(回复发出),按序号留给合并。</summary>
|
||||
public sealed class UdpEchoListener : BlockBase
|
||||
public sealed class DatagramEchoListener : BlockBase
|
||||
{
|
||||
private readonly RowStore _records;
|
||||
|
||||
public UdpEchoListener(BlockEnv env, BlockSpec spec)
|
||||
public DatagramEchoListener(BlockEnv env, BlockSpec spec)
|
||||
: base(env, spec)
|
||||
{
|
||||
_records = new RowStore(spec.Kind.FindStream("msg")!, Side.Agent, 32768);
|
||||
@@ -142,26 +143,26 @@ public sealed class UdpEchoListener : BlockBase
|
||||
|
||||
public override async Task RunAsync(CancellationToken ct)
|
||||
{
|
||||
Env.Udp!.Register(Spec.StreamId, OnPacket);
|
||||
Env.Datagrams!.Register(Spec.StreamId, OnPacket);
|
||||
try
|
||||
{
|
||||
await WaitUntilCancelledAsync(ct);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Env.Udp.Unregister(Spec.StreamId);
|
||||
Env.Datagrams.Unregister(Spec.StreamId);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPacket(in UdpDelivery delivery)
|
||||
private void OnPacket(in QuicDatagramDelivery delivery)
|
||||
{
|
||||
if (delivery.Header.Type != UdpPacketType.EchoRequest)
|
||||
if (delivery.Header.Type != MeasurementDatagramType.EchoRequest)
|
||||
{
|
||||
return; // Data:探活包,只用来保持 NAT 映射和让准入策略学到源地址
|
||||
}
|
||||
|
||||
long t2 = delivery.ReceiveUs;
|
||||
delivery.ReplyAs(UdpPacketType.EchoReply);
|
||||
delivery.ReplyAs(MeasurementDatagramType.EchoReply);
|
||||
Span<long> row = [t2, Env.Clock.NowUs()];
|
||||
_records.SetRow(delivery.Header.Seq, row);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user