agent: unify listening and dialing with directed mutual measurements

Replace Probe with Agent across node runtime, Fleet contracts, backend state, API and storage. Report incoming sessions and outgoing link health through each Agent uplink, and retain directed link controls and retry.

Update protocol fixtures and end-to-end coverage for the unified model; accept requested cancellation during the Fleet timeout test cleanup.
This commit is contained in:
justme committed 2026-10-21 11:55:36 +08:00
1 parent d5ebf29e57
commit ad5efc62ff
206 files changed
+4202 -4964

No files matched your search

@@ -29,8 +29,11 @@ public sealed class MsQuicConnectionTests
}
}
[Fact]
public async Task DatagramConnection_CanSendCloseAndReconnect_WithoutBlockingNativeWorkers()
[Theory]
[InlineData("127.0.0.1", "127.0.0.1")]
[InlineData("::", "127.0.0.1")]
[InlineData("::", "::1")]
public async Task DatagramConnection_CanSendCloseAndReconnect_WithoutBlockingNativeWorkers(string bind, string peer)
{
var log = new CaptureLog();
var counters = new DataPlaneCounters();
@@ -39,7 +42,7 @@ public sealed class MsQuicConnectionTests
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,
await using var listener = new MsQuicListener(IPAddress.Parse(bind), [0], certificate,
(connection, data) =>
{
// Bad measurement payloads must be counted without flooding logs.
@@ -55,7 +58,7 @@ public sealed class MsQuicConnectionTests
{
var reply = new TaskCompletionSource<byte[]>(TaskCreationOptions.RunContinuationsAsynchronously);
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(10));
MsQuicConnection client = await MsQuicConnection.ConnectAsync(IPAddress.Loopback, listener.BoundPorts[0], 0,
MsQuicConnection client = await MsQuicConnection.ConnectAsync(IPAddress.Parse(peer), listener.BoundPorts[0], 0,
key.ExportSubjectPublicKeyInfo(), (_, data) => reply.TrySetResult(data.ToArray()), log, timeout.Token);
try
{