Commit Graph
44 Commits
Author SHA1 Message Date
Nils Andreas Svee 56a2a653d0 docs(crates): give each published crate its own crates.io README and examples
Each published crate (irtt-rs, irtt-client, irtt-server, irtt-stats,
irtt-proto) now points crates.io at its own README instead of
inheriting the root project README via the workspace-wide readme
default, which is removed. Each crate README is a short landing page:
what the crate is, who should use it, which sibling crate to use
instead if this isn't the right abstraction level, and links to
docs.rs and the main repository.

Add real Cargo example targets teaching irtt-client's blocking/Tokio/
managed API tiers, a basic and a multi-listener irtt-server example,
and an irtt-stats example contrasting finite vs continuous retention.
irtt-proto intentionally has none. Update each crate's top-level
rustdoc to explain its API-tier choices and point at the examples, and
enable docs.rs rustdoc example scraping for irtt-client and
irtt-server (via doc-scrape-examples on each example target, needed
because the crate has dev-dependencies).

The client examples are caller-paced against next_send_deadline()
rather than sending on every loop iteration, bound their receive wait
by the next send/timeout deadline instead of awaiting indefinitely,
poll timeouts on a short fixed cadence, and surface send/receive/close
errors instead of discarding them via unwrap_or_default()/if-let-Ok --
so they demonstrate correct pacing and terminate/report cleanly rather
than racing the server, hanging on a lost reply, or silently dropping a
failed final close.
2026-08-20 22:17:53 +07:00
Nils Andreas Svee 2634649852 test(proto): add codec property tests
Add proptest-based property tests for irtt-proto's varint and Params
codecs, covering the full u64/i64 domains for varint/zigzag round trips
and generated valid Params for semantic round trips, presence
omission rules, repeated-tag last-wins behavior, and unknown-tag
tolerance.
2026-08-20 00:45:16 +07:00
Nils Andreas Svee d66b5ed8de chore(release): move to independent per-crate versioning at 0.5.0
Each workspace crate now owns its own version instead of the previous
lockstep scheme; irtt-proto, irtt-client, irtt-server, irtt-stats, and
irtt-cli all become 0.5.0 as the first independently-versioned release.
Workspace dependency requirements are bumped to match.

Add a root CHANGELOG.md with a real per-crate 0.5.0 section drawn from
archaeology of every merge since v0.4.0, not just path-filtered commits.

Move cargo-dist to a crate-qualified `irtt-cli/vX.Y.Z` tag namespace so
only irtt-cli (the one dist-able application) triggers a GitHub Release;
library crate tags (irtt-proto/irtt-client/irtt-server/irtt-stats) exist
purely to pin the source for a crates.io release and no longer risk
tripping the release workflow. Regenerate the renamed
irtt-cli-release.yml via `dist generate` and update the few other files
that referenced the old release.yml path by name. Also fix a stale
`features = ["full"]` in dist-workspace.toml left over from a feature-flag
refactor that dropped the "full" feature entirely, which was silently
breaking every dist build.

Rescope semver.yml's tag trigger to the same five crate-qualified tags
so semver checks keep running under the new convention.
2026-08-17 09:29:25 +07:00
Nils Andreas Svee 3845142d30 fix(proto): reject packet lengths usize cannot represent 2026-08-12 20:05:01 +07:00
Nils Andreas Svee c833b0663d docs(proto): correct the echo length saturation note 2026-08-12 19:40:17 +07:00
Nils Andreas Svee 68ed5c6e2e fix(proto): floor negative echo lengths 2026-08-12 17:16:03 +07:00
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 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 3d5a8fae14 fix(client): align DSCP wire semantics 2026-08-11 20:29:57 +07:00
Nils Andreas Svee e0e8d3870b docs(agents): add server protocol guidance 2026-08-11 18:34:22 +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 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
Nils Andreas Svee cabe0f6c24 feat(proto): add directional echo codecs 2026-08-04 00:34:12 +07:00
Nils Andreas Svee cc7f7fc9b2 feat(proto): add directional open and close codecs 2026-08-04 00:30:08 +07:00
Nils Andreas Svee e908c4ce4f refactor(proto): centralize packet envelope handling 2026-08-04 00:27:45 +07:00
renovate[bot] bbb8a6a458 fix(deps): update rust crate thiserror to 2.0.19 2026-07-23 12:30:30 +07:00
Nils Andreas Svee 68c7f92cb4 chore: bump version to 0.4.0 across all workspace packages
Update the version of irtt-proto, irtt-client, irtt-stats, and irtt-cli to 0.4.0 in preparation for a new release.
2026-07-05 00:30:19 +07:00
Nils Andreas Svee 5efb8a1870 build: bump workspace and crate versions to 0.3.0 2026-06-10 00:44:10 +07:00
Nils Andreas Svee 8fd0b803e9 docs: add public crate landing docs 2026-05-18 01:22:08 +07:00
Nils Andreas Svee 2fcef0adc5 docs: clarify params validation boundaries 2026-05-18 00:36:18 +07:00
Nils Andreas Svee e117813578 test: consolidate and prune redundant unit tests
Simplify the test suite by merging similar test cases and removing redundant assertions that verify trivial initialization and basic container logic.
2026-05-18 00:16:51 +07:00
Nils Andreas Svee 64da60d480 feat(proto): enforce maximum length for server fill parameter
Move MAX_SERVER_FILL_BYTES to irtt-proto and validate it during decoding to prevent processing oversized parameters.
2026-05-17 22:59:57 +07:00
Nils Andreas Svee 20a1d9dc8e refactor(proto): make echo_packet_len return Result to handle negative lengths 2026-05-12 13:05:45 +07:00
Nils Andreas Svee b508a94198 build: bump version to 0.2.0 2026-05-11 15:11:58 +07:00
Nils Andreas Svee 2258509021 chore: bump version to 0.1.1 across all crates
Update workspace members and dependencies to version 0.1.1 to prepare for a new release.
2026-05-10 21:17:22 +07:00
renovate[bot] f474632f4c fix(deps): update rust crate thiserror to 2.0.18 2026-05-10 20:56:43 +07:00
renovate[bot] ababa9d6b6 fix(deps): update rust crate subtle to 2.6.1 2026-05-10 20:56:43 +07:00
Nils Andreas Svee 47a8143bce refactor(irtt-proto): update HMAC implementation for Digest 0.11 2026-05-10 20:56:43 +07:00
Nils Andreas Svee 831fd0cc45 build(deps): update hmac and md-5 dependencies 2026-05-10 20:56:43 +07:00
Nils Andreas Svee 416e5b43ba build: add package metadata to member crates for publishing
Include descriptions, keywords, categories, and workspace-inherited fields (repository, homepage, readme) to prepare crates for distribution on crates.io.
2026-05-10 20:56:43 +07:00
Nils Andreas Svee fa06177c60 docs(proto): document HMAC-MD5 compatibility 2026-05-10 20:56:43 +07:00
Nils Andreas Svee 48f6cb80ed fix(proto): require exact echo reply packet length 2026-05-10 20:56:43 +07:00
Nils Andreas Svee 8374a51054 fix(client): reject runtime-invalid negotiated dscp 2026-05-10 20:56:43 +07:00
Nils Andreas Svee dfdc43292a fix(proto): reject invalid echo packet lengths 2026-05-10 20:56:43 +07:00
Nils Andreas Svee d53dd7f406 fix(proto): reject oversized echo payloads 2026-05-10 20:56:43 +07:00
Nils Andreas Svee f5cdaf4b67 perf(proto): compute HMAC without packet allocation 2026-05-10 20:56:43 +07:00
Nils Andreas Svee f0823fa90b fix(proto): avoid mutating flags in HMAC helper 2026-05-10 20:56:43 +07:00
Nils Andreas Svee ab855338af test(proto): verify HMAC field placement in protocol packets 2026-05-10 20:56:43 +07:00
Nils Andreas Svee 5831f4a3b5 test(proto): add unit tests for parameter encoding and decoding 2026-05-10 20:56:43 +07:00
Nils Andreas Svee 04ebaf829a refactor(proto): Remove unused protocol flags and helper functions 2026-05-10 20:56:43 +07:00
Nils Andreas Svee a5e8c80ecb build(deps): Upgrade thiserror to version 2 2026-05-10 20:56:43 +07:00
Nils Andreas Svee 34dd2ee5d2 refactor(proto): Remove Clock::None and default to Clock::Both
Simplify clock parameter negotiation by rejecting the ambiguous 'None' value.
2026-05-10 20:56:43 +07:00
Nils Andreas Svee cf74887bdf feat(project): Establish initial IRTT workspace and protocol definitions 2026-05-10 20:56:28 +07:00