Files
fips/src
Johnathan Corgan 4c2f0143e4 fix(control): report the bound peer's traffic counters in show links
show_links rendered packets_sent, packets_recv, bytes_sent, bytes_recv and
last_recv_ms from the LinkStats held on the Link record, but nothing on the
data plane ever wrote that copy. Every send and receive counter write goes to
the separate LinkStats held on the active peer, which show_peers reads. So
every link reported zero however much traffic it carried, while show_peers
showed the traffic for the same link_id (GitHub issue #158). The two copies
were never connected: the Link counters have had no production writer since
they were added, and show_links read them from the day it was introduced.

Both render sites now take a link's counters from the peer bound to it, and
fall back to the link's own (zero) counters when no peer is bound yet, as for
a link still in handshake. That covers the on-loop handler and the
tick-published snapshot the control socket serves from, which must stay
byte-identical. A small helper on Node maps each peer's link_id to its
counters once per render.

The fix reads the counters rather than writing a second copy at each send
and receive site. Writing both would add a link lookup per packet on the hot
path and keep two sources of truth that every future writer must keep in
step, which is how this defect arose. Removing the unused Link counters
would change public methods, so that is left for a separate cleanup.

The counters follow the peer across address changes, while the row's
transport_id and remote_addr remain those the link was created with; that
matches how show_peers already keys the same counters by link_id. The
counters cover authenticated link frames only, so they are not expected to
equal the transport totals in show_transports. The response shape is
unchanged.

The new test establishes a real two-node link over the loopback
transport and checks each node's show_links row against that node's peer
counters, after first requiring the counters to be non-zero so a run with no
traffic cannot pass. It also requires node 1's received count to be non-zero
and no greater than node 0's sent count, a bound that does not come from the
same node's peer copy. It fails on the unfixed code with packets_sent 0
against 3, and breaking only the snapshot site fails its on-loop and
snapshot equality check. A second test keeps a link with no peer in the
output with zero counters on both render paths.

Fixes #158
2026-09-13 16:49:40 +00:00
..