add network test feature (PING/PONG with latency stats)

New frame types PING (0x0B) and PONG (0x0C), each carrying an 8-byte
nonce. Server echoes PING nonce verbatim in PONG. Client sends pings
at random 10-100ms intervals, correlates nonces to measure RTT.

Stats shown live: sent/recv counts, loss %, average latency, jitter
(mean absolute delta of consecutive RTTs). Test button toggles on/off.

Updated both Rust server (echo in main.rs) and C# client (PingTest.cs,
SessionManager routing, MainForm Test button + stats label).
This commit is contained in:
2026-08-13 08:28:59 +00:00
parent a2d3643d69
commit 279af33fd8
7 changed files with 242 additions and 4 deletions
+25
View File
@@ -14,6 +14,7 @@ sealed class SessionManager : IDisposable
byte[]? _serverMac;
string _serverHostname = "";
UpstreamEntry[] _upstreams = [];
PingTest? _pingTest;
// Serialized OPEN: only one outstanding at a time.
readonly object _openLock = new();
@@ -47,6 +48,22 @@ sealed class SessionManager : IDisposable
_link.SendBroadcast(new Frame.Discover());
}
public PingTest? StartPing()
{
if (_link == null || _serverMac == null)
return null;
_pingTest?.Stop();
_pingTest = new PingTest(_link, _serverMac);
_pingTest.Start();
return _pingTest;
}
public void StopPing()
{
_pingTest?.Stop();
_pingTest = null;
}
public void HandleFrame(Frame frame, byte[] srcMac)
{
switch (frame)
@@ -85,6 +102,13 @@ sealed class SessionManager : IDisposable
if (_sessions.TryRemove(close.SessionId, out var s))
s.Dispose();
break;
case Frame.Pong pong:
_pingTest?.HandlePong(pong.Nonce);
break;
case Frame.Ping _:
break;
}
}
@@ -227,6 +251,7 @@ sealed class SessionManager : IDisposable
public void StopAll()
{
StopPing();
foreach (var kv in _listeners)
kv.Value.Listener.Stop();
_listeners.Clear();