feat(quic): replace probe UDP data plane with QUIC datagrams

This commit is contained in:
justme committed 2026-10-10 02:59:56 +08:00
1 parent 4609048865
commit b964dc2bbc
53 files changed
+2413 -411

No files matched your search

@@ -21,7 +21,7 @@ public sealed class AgentEndToEndTests
AgentHarness agent = await AgentHarness.StartAsync(_backend);
await agent.OverrideLineTasksAsync(rateHz: 30);
ProbeSimulator probe = await agent.ConnectProbeAsync();
LineTaskSet set = await probe.WaitForTasksAsync(s => s.Tasks.Any(t => t.Kind == "udp_echo" && t.Port == agent.App.UdpPorts[0]));
LineTaskSet set = await probe.WaitForTasksAsync(s => s.Tasks.Any(t => t.Kind == "udp_echo" && t.Port == agent.App.QuicPorts[0]));
return (agent, probe, set.Tasks.Single(t => t.Kind == "udp_echo"));
}
@@ -159,8 +159,8 @@ public sealed class AgentEndToEndTests
// The probe process restarts: a new session with its own streams; sequence numbers start from 0 again
await using ProbeSimulator second = first.Restarted();
await second.ConnectAsync("127.0.0.1", agent.App.ControlPort, agent.TlsPublicKey, agent.App.UdpPorts[0], agent.NodeId);
LineTaskSet set = await second.WaitForTasksAsync(s => s.Tasks.Any(t => t.Kind == "udp_echo" && t.Port == agent.App.UdpPorts[0]));
await second.ConnectAsync("127.0.0.1", agent.App.ControlPort, agent.TlsPublicKey, agent.App.QuicPorts[0], agent.NodeId);
LineTaskSet set = await second.WaitForTasksAsync(s => s.Tasks.Any(t => t.Kind == "udp_echo" && t.Port == agent.App.QuicPorts[0]));
LineTask udp2 = set.Tasks.Single(t => t.Kind == "udp_echo");
Assert.NotEqual(udp.StreamId, udp2.StreamId);
@@ -221,11 +221,11 @@ public sealed class AgentEndToEndTests
await using AgentHarness agent = await AgentHarness.StartAsync(_backend);
await agent.CreateProbeAsync();
await using var stranger = new ProbeSimulator("prb_stranger", Fleet.Identity.NodeIdentity.Generate());
await Assert.ThrowsAnyAsync<Exception>(() => stranger.ConnectAsync("127.0.0.1", agent.App.ControlPort, agent.TlsPublicKey, agent.App.UdpPorts[0], agent.NodeId));
await Assert.ThrowsAnyAsync<Exception>(() => stranger.ConnectAsync("127.0.0.1", agent.App.ControlPort, agent.TlsPublicKey, agent.App.QuicPorts[0], agent.NodeId));
// 证书公钥不对(中间人)也不会连上
await using ProbeSimulator probe = await agent.CreateProbeAsync();
await Assert.ThrowsAnyAsync<Exception>(() => probe.ConnectAsync("127.0.0.1", agent.App.ControlPort, Fleet.Identity.NodeIdentity.Generate().PublicKeySpki, agent.App.UdpPorts[0], agent.NodeId));
await Assert.ThrowsAnyAsync<Exception>(() => probe.ConnectAsync("127.0.0.1", agent.App.ControlPort, Fleet.Identity.NodeIdentity.Generate().PublicKeySpki, agent.App.QuicPorts[0], agent.NodeId));
}
[Fact]
@@ -335,7 +335,7 @@ public sealed class AgentEndToEndTests
await using AgentHarness agent = await AgentHarness.StartAsync(_backend, config => config.Limits.MaxTotalMbps = 20);
await agent.OverrideLineTasksAsync();
var phase = new TestPhase { Kind = "udp_train", DurationSeconds = 1, Params = { ["port"] = System.Text.Json.JsonSerializer.SerializeToElement(agent.App.UdpPorts[0]) } };
var phase = new TestPhase { Kind = "udp_train", DurationSeconds = 1, Params = { ["port"] = System.Text.Json.JsonSerializer.SerializeToElement(agent.App.QuicPorts[0]) } };
var run = new TestRunParams { TestId = new TestId("tst_x"), ProbeId = new ProbeId("prb_nobody"), Plan = "x", Phases = [phase] };
Assert.Equal("probe_offline", agent.App.Tests.Start(run).Error.Code.Value);
@@ -58,7 +58,7 @@ public sealed class AgentHarness : IAsyncDisposable
var config = new AgentConfig
{
Fleet = { Server = backend.BaseAddress.ToString(), IdentityDir = directory },
Listen = { Bind = "127.0.0.1", ControlPort = 0, UdpPorts = [0], TcpPorts = [0] },
Listen = { Bind = "127.0.0.1", ControlPort = 0, QuicPorts = [0], TcpPorts = [0] },
};
configure?.Invoke(config);
LoadedNodeIdentity identity = LoadedNodeIdentity.Load(directory);
@@ -87,7 +87,7 @@ public sealed class AgentHarness : IAsyncDisposable
public async Task<ProbeSimulator> ConnectProbeAsync()
{
ProbeSimulator probe = await CreateProbeAsync();
await probe.ConnectAsync("127.0.0.1", App.ControlPort, TlsPublicKey, App.UdpPorts[0], NodeId);
await probe.ConnectAsync("127.0.0.1", App.ControlPort, TlsPublicKey, App.QuicPorts[0], NodeId);
return probe;
}
@@ -104,7 +104,7 @@ public sealed class AgentHarness : IAsyncDisposable
}
string kind = task["kind"]!.GetValue<string>();
var parameters = new JsonObject { ["port"] = kind == "udp_echo" ? App.UdpPorts[0] : App.TcpPorts[0] };
var parameters = new JsonObject { ["port"] = kind == "udp_echo" ? App.QuicPorts[0] : App.TcpPorts[0] };
// 默认的 connect 模板在这些用例里不需要(也占预算):对这个 Agent 关掉它
bool enabled = kind != "connect";
if (rateHz is { } hz && kind != "connect")