Commit Graph
708 Commits
Author SHA1 Message Date
Nils Andreas Svee 93491e7762 refactor(proto): preserve open parameter presence
`Params::decode` seeded `Params::default()` and overwrote only the tags it
saw, so an omitted tag and one explicitly encoded as zero were
indistinguishable afterwards. The protocol gives those the same value but not
the same meaning, and a server cannot apply its open admission rules without
telling them apart: an absent Duration or Interval is accepted as the wire
default zero, while one explicitly encoded as zero is invalid.

Add `Params::decode_with_presence`, returning the decoded values alongside a
`ParamPresence` recording which known tags appeared. `Params::decode` now
delegates to it, so there is still exactly one parser and the two cannot
diverge. Unknown tags stay ignored and untracked, and repeated known tags keep
last-value-wins.

Add `Clock::Unspecified = 0` as the default, which is the wire default for an
absent Clock tag and what an empty parameter payload decodes to. An explicit
Clock tag encoding zero remains an invalid enum value, so `Unspecified` is
only ever reached by omission; `encode` omits the tag for it rather than
emitting an explicit zero. It selects no clock, so `has_wall`/`has_mono` are
false and no timestamp field is laid out.

`ClientConfig::clock` is public and therefore now constructible as
`Unspecified`, which is a wire default rather than a client mode. Reject it
during config validation. The client default stays `Clock::Both`, so normal
client-generated params and wire vectors are unchanged.
2026-08-12 00:23:14 +07:00
Nils Andreas Svee 78e503ffcc Merge pull request #73 from Lochnair/refactor/proto-request-codecs
refactor(proto): unify request codecs
2026-08-11 23:22:41 +07:00
Nils Andreas Svee 5a4272e7fd refactor(proto): unify request codecs
Replace the three per-kind request encoders and decoders with one
directional pair, ahead of introducing irtt-server.

Sender side: encode_request(RequestToEncode, hmac_key) constructs OPEN,
CLOSE and ECHO requests from borrowed values. Params and the ECHO payload
are borrowed rather than owned, removing a Params clone and a payload Vec
from the client's hot paths. Wire output is byte-identical; all captured
vectors still pass unchanged.

Receiver side: decode_request(packet) structurally classifies an inbound
request with no HMAC key, no negotiated Params, no session state and no
allocation. A server must extract a token before it knows which key
applies, so authentication is a separate step. Classification follows the
verified server spec: reserved bits and FLAG_REPLY are rejected, OPEN
takes precedence over CLOSE and over an echo-shaped body, and only the
structural minimums (4/12/16, plus 16 with FLAG_HMAC) are enforced.
Trailing bytes are tolerated, no negotiated length ceiling is applied, and
a zero token is structurally valid. OPEN parameters stay encoded bytes so
an authenticating receiver can verify before decoding untrusted data, and
everything after an ECHO sequence number is exposed as an opaque tail.

Add verify_packet_hmac(key, packet), which locates the standard field
itself and rejects a packet lacking FLAG_HMAC. hmac_present reports packet
layout, never authentication. The offset-based verify_hmac stays public as
the low-level primitive for hand-built and captured wire vectors, matching
the existing compute_hmac pair.

Refactor the private envelope into structural header decoding, codec flag
rules, HMAC presence policy and verification as separate steps. The reply
codecs compose the same steps in the same order, so decode_open_reply and
decode_echo_reply keep their exact error ordering and the client's
fatal-versus-ignore classification is unchanged. Reply decoding stays
state-specific: the client already knows which reply to expect, and the
two need different semantic context.

Migrate the production client and every fake peer to the new API; the
fake peers now admit requests the way a server does, instead of parsing
packets by hand.
2026-08-11 23:22:20 +07:00
Nils Andreas Svee c91e7917f7 Merge remote-tracking branch 'origin/renovate/lock-file-maintenance' 2026-08-11 23:22:03 +07:00
Nils Andreas Svee e380924414 Merge remote-tracking branch 'origin/renovate/tokio-1.x' 2026-08-11 23:22:03 +07:00
Nils Andreas Svee 7ea71f0811 Merge remote-tracking branch 'origin/renovate/nix-0.x' 2026-08-11 23:22:03 +07:00
Nils Andreas Svee db0bc282f3 Merge pull request #72 from Lochnair/audit/recv-window-downstream-loss
docs(stats): clarify server receive-window semantics
2026-08-11 23:22:03 +07:00
Nils Andreas Svee 0977db1fe2 docs(stats): clarify server receive-window semantics
An audit of the server-reported receive window found no defect in the
statistics pipeline: the bitmap is decoded raw, stored raw, never
interpreted, and never feeds the directional loss estimates, which use
the cumulative server receive count.

The public rustdoc was silent on all of that, leaving consumers of
PacketCounts free to read a window of 0x1 as a 63-packet loss burst.
Document the field's contract, name the count as the only server input
to LossStats, and cover the window-only case with a regression test.
2026-08-11 23:21:58 +07:00
renovate[bot] e0332b4360 chore(deps): maintain cargo lockfile 2026-08-11 14:25:00 +00:00
renovate[bot] 86c6422f14 fix(deps): update rust crate tokio to 1.53.1 2026-08-11 14:24:43 +00:00
renovate[bot] 554d197f14 fix(deps): update rust crate nix to 0.31.3 2026-08-11 14:24:34 +00:00
Nils Andreas Svee d5c3e21a05 Merge pull request #68 from Lochnair/fix/dscp-wire-semantics
fix(client): align DSCP wire semantics
2026-08-11 21:09:26 +07:00
Nils Andreas Svee 3d5a8fae14 fix(client): align DSCP wire semantics 2026-08-11 20:29:57 +07:00
Nils Andreas Svee 347af39d74 Merge pull request #67 from Lochnair/docs/server-protocol-airlock
docs(protocol): add sanitized server compatibility research
2026-08-11 18:34:51 +07:00
Nils Andreas Svee e0e8d3870b docs(agents): add server protocol guidance 2026-08-11 18:34:22 +07:00
Nils Andreas Svee 454bbc2378 docs(protocol): add sanitized server compatibility research 2026-08-11 18:25:31 +07:00
Nils Andreas Svee 8a94bc7ca6 Merge pull request #66 from Lochnair/fix/upstream-midpoint-echo-compat
fix(client): accept upstream midpoint echo replies
2026-08-11 17:43:05 +07:00
Nils Andreas Svee 88dd4f2a62 fix(proto): accept upstream midpoint echo replies
Upstream irtt 0.9.1 always emits both midpoint timestamp fields (wall,
then monotonic) in an ECHO reply for single-clock StampAt::Midpoint
negotiations, even though only one clock was negotiated, so its header is
one timestamp longer than the negotiated header.

The resulting datagram length is not simply negotiated_len + 8. Both
forms are max(negotiated_length, header), so the extra field lengthens
the datagram only while the larger header still exceeds the negotiated
length, and displaces payload beyond that; the difference is 8, then
7..1, then 0.

decode_echo_reply now accepts the compatibility length wherever it is
strictly longer than the negotiated length, parsing both wire fields and
exposing only the negotiated clock's value. Where the two lengths
coincide the forms are indistinguishable from the packet alone, so the
reply is accepted with normal negotiated parsing rather than a heuristic
- a monotonic-only midpoint negotiation therefore cannot always be
corrected, which is documented and tested. Every other length stays
strictly rejected.

Echo request decoding and encode_echo_reply are unchanged: the encoder
must keep emitting the sane negotiated layout.
2026-08-11 16:26:29 +07:00
Nils Andreas Svee 3d197c2353 ci: expand test matrix to include musl and aarch64 targets
Consolidate check and test jobs into a matrix strategy to verify compatibility across x86_64 and aarch64 architectures for both glibc and musl toolchains.
2026-08-11 14:23:06 +07:00
Nils Andreas Svee 8472745b42 Merge pull request #65 from Lochnair/fix/ancillary-safe
refactor(client): replace unsafe libc calls with nix for Linux ancillary data
2026-08-11 13:58:22 +07:00
Nils Andreas Svee 373bf32d0f refactor(client): replace unsafe libc calls with nix for Linux ancillary data
Eliminate unsafe code blocks and manual pointer arithmetic in Linux-specific receive paths by utilizing nix for socket options and control message parsing. This improves safety and maintainability while preserving the existing kernel RX timestamp and traffic class functionality.
2026-08-11 13:38:56 +07:00
Nils Andreas Svee 3c6c0e396f Merge pull request #64 from Lochnair/fix/tui-bound-input-drain
fix(tui): bound input event draining
2026-08-11 00:25:03 +07:00
Nils Andreas Svee 8651e93351 fix(tui): bound input event draining
handle_input() previously drained terminal events in an unbounded
while-poll loop, so a continuously-ready input stream could keep the
frontend inside handle_input() indefinitely, starving managed-event
processing, completion checks, peer-close stop policy, and rendering
in the outer run_tui() loop.

Bound each call to at most INPUT_EVENT_WORK_BUDGET (128) polled
terminal events, mirroring the MANAGED_EVENT_WORK_BUDGET pattern
already used for managed event draining. All polled events count
against the budget, including ignored/unknown/release events, so a
stream of non-actionable input can't bypass the bound. Remaining
events are left queued for the next outer-loop iteration rather than
dropped. Quit/Ctrl-C now also breaks out of the drain immediately
after being handled, since there is no benefit to consuming further
buffered input before the outer loop can request managed shutdown.
2026-08-11 00:12:37 +07:00
Nils Andreas Svee 17bbf72c6c Merge pull request #63 from Lochnair/fix/tui-lazy-graph-history
fix(tui): allocate graph history lazily
2026-08-10 23:59:11 +07:00
Nils Andreas Svee 17aeaf0b9b fix(tui): allocate graph history lazily 2026-08-10 23:57:27 +07:00
Nils Andreas Svee 3df71e0b69 fix(cli): account for targets in stats memory warning 2026-08-10 23:35:16 +07:00
Nils Andreas Svee b555451448 test(cli): make integration synchronization deterministic (#61) 2026-08-10 23:21:00 +07:00
Nils Andreas Svee 8924cc531c test(client): use protocol encoders in fake peers 2026-08-10 22:53:36 +07:00
Nils Andreas Svee e5c08997ed test(cli): use protocol encoders in fake peers 2026-08-10 21:55:54 +07:00
Nils Andreas Svee f0f9277469 test: trim redundant coverage 2026-08-10 21:06:49 +07:00
Nils Andreas Svee 186c6eba97 docs: add clean-room docs/specs and agent guidance 2026-08-10 18:54:22 +07:00
renovate[bot] 49826a5b3d fix(deps): update rust crate thiserror to 2.0.20 2026-08-10 11:15:42 +07:00
renovate[bot] d4cef6c2e7 fix(deps): update rust crate clap to 4.6.6 2026-08-10 11:15:26 +07:00
Nils Andreas Svee 8c31f14419 Merge pull request #55 from Lochnair/fix/managed-timeout-budget
fix(managed): bound timeout work per poll
2026-08-10 11:14:52 +07:00
Nils Andreas Svee 301542186a test(cli): bound peer-close synchronization waits 2026-08-10 11:09:00 +07:00
Nils Andreas Svee 04ea4af079 test(cli): synchronize multi-target peer close 2026-08-10 11:00:12 +07:00
Nils Andreas Svee 1f69c04274 test(managed): verify sparse timeout backlog progress 2026-08-10 10:30:36 +07:00
Nils Andreas Svee edb634146c fix(managed): retain timeout backlog fairness 2026-08-10 10:25:10 +07:00
Nils Andreas Svee ab9912b3d5 test(managed): cover timeout backlog scheduling 2026-08-10 02:06:41 +07:00
Nils Andreas Svee ec7baebe3a fix(managed): bound timeout discovery 2026-08-10 01:59:13 +07:00
Nils Andreas Svee f65998ff70 refactor(client): make deadline indexing allocation-free 2026-08-10 01:56:49 +07:00
Nils Andreas Svee 4632e310d7 test(managed): verify timeout budget fairness 2026-08-10 01:18:38 +07:00
Nils Andreas Svee a67331a297 fix(managed): bound timeout work per poll 2026-08-10 01:05:41 +07:00
Nils Andreas Svee 9769a1b49e refactor(client): index pending probe deadlines 2026-08-10 01:00:50 +07:00
Nils Andreas Svee fe3a4dc8e5 Merge pull request #54 from Lochnair/renovate/github-actions
chore(deps): update github actions
2026-08-10 00:45:41 +07:00
renovate[bot] 0bb75b04ef chore(deps): update github actions 2026-08-09 17:39:20 +00:00
Nils Andreas Svee 24d36d41d8 Merge pull request #53 from Lochnair/fix/managed-liveness-control
fix(managed): harden liveness and control bounds
2026-08-10 00:38:45 +07:00
Nils Andreas Svee 8d47dc9c6e test(managed): cover stopping admission overlap 2026-08-10 00:27:18 +07:00
Nils Andreas Svee dd396a8b5a test(managed): verify bounded control progress 2026-08-10 00:06:31 +07:00
Nils Andreas Svee dd1182d24d fix(managed): harden control admission 2026-08-10 00:05:48 +07:00