refactor(server): centralize receive drop policy #99

Merged
Lochnair merged 2 commits from refactor/server-receive-drop-policy into main 2026-08-15 04:33:43 +00:00
Lochnair commented 2026-08-15 04:25:08 +00:00 (Migrated from github.com)

Summary

  • socket_io::receive now fully owns whether a received datagram is safe for ServerCore;
  • full-buffer receives are conservatively rejected there;
  • Server::run no longer carries a second receive-validity rule.

Behavior

  • ordinary explicit listener:

    • short-of-buffer receive -> accepted;
    • full-buffer receive -> dropped;
    • truncated-to-buffer receive -> dropped.
  • wildcard ancillary listener:

    • existing MSG_TRUNC / MSG_CTRUNC and destination-metadata rules preserved;
    • ancillary.rs has no production changes.
  • no protocol behavior change. The rule that previously lived in Server::run
    (len == RECEIVE_BUFFER_LEN -> drop) is the same rule, now expressed against
    the caller-supplied buffer.len() so socket_io stays generic about receive
    capacity, and applied to both receive paths exactly as before.

Ownership

socket_io:
    transport validity and drop policy — a datagram reaches the caller only
    once the transport layer has accepted it

Server::run:
    orchestration of already-accepted datagrams — receive, hand to the core,
    mark and send the reply

ServerCore:
    protocol/session semantics only

RECEIVE_BUFFER_LEN (still 65,536) now documents receive-buffer allocation
capacity and nothing else.

Scope

  • no jumbogram support;
  • no buffer-size or dynamic/configurable-capacity changes;
  • no source-selection, pktinfo, or IPv4-mapped behavior changes;
  • no ServerCore / ServerSet changes;
  • no new transport trait, socket wrapper, raw syscalls, or unsafe code.

Tests

Three focused socket_io::receive tests over a real loopback UDP pair with a
deliberately tiny receive buffer (no 65,536-byte datagram needed):

  • payload shorter than the buffer -> Some, with correct length, peer,
    ReplySource::Bound, and intact payload bytes;
  • payload exactly filling the buffer -> None;
  • payload larger than the buffer -> None.

ServerCore is not called for Ok(None): Server::run continues before
handle_datagram, which existing runtime/integration tests already cover.

Verification

All run locally on macOS (aarch64-apple-darwin), all passing:

  • cargo test -p irtt-server --all-features --locked
  • cargo fmt --all -- --check
  • cargo check --workspace --all-targets --all-features --locked
  • cargo test --workspace --all-targets --all-features --locked
  • cargo clippy --workspace --all-targets --all-features --locked -- -D warnings
  • RUSTDOCFLAGS="-D warnings" cargo doc --workspace --all-features --no-deps --locked
  • cargo check -p irtt-cli --no-default-features --features {server,client,tui} --all-targets --locked
  • git diff --check
  • cross-target cargo check -p irtt-server --all-targets --locked --target T for
    x86_64-unknown-linux-gnu, x86_64-unknown-freebsd, x86_64-pc-windows-gnu,
    aarch64-unknown-linux-musl.
## Summary - `socket_io::receive` now fully owns whether a received datagram is safe for `ServerCore`; - full-buffer receives are conservatively rejected there; - `Server::run` no longer carries a second receive-validity rule. ## Behavior - ordinary explicit listener: - short-of-buffer receive -> accepted; - full-buffer receive -> dropped; - truncated-to-buffer receive -> dropped. - wildcard ancillary listener: - existing `MSG_TRUNC` / `MSG_CTRUNC` and destination-metadata rules preserved; - `ancillary.rs` has no production changes. - no protocol behavior change. The rule that previously lived in `Server::run` (`len == RECEIVE_BUFFER_LEN` -> drop) is the same rule, now expressed against the caller-supplied `buffer.len()` so `socket_io` stays generic about receive capacity, and applied to both receive paths exactly as before. ## Ownership socket_io: transport validity and drop policy — a datagram reaches the caller only once the transport layer has accepted it Server::run: orchestration of already-accepted datagrams — receive, hand to the core, mark and send the reply ServerCore: protocol/session semantics only `RECEIVE_BUFFER_LEN` (still 65,536) now documents receive-buffer allocation capacity and nothing else. ## Scope - no jumbogram support; - no buffer-size or dynamic/configurable-capacity changes; - no source-selection, pktinfo, or IPv4-mapped behavior changes; - no `ServerCore` / `ServerSet` changes; - no new transport trait, socket wrapper, raw syscalls, or unsafe code. ## Tests Three focused `socket_io::receive` tests over a real loopback UDP pair with a deliberately tiny receive buffer (no 65,536-byte datagram needed): - payload shorter than the buffer -> `Some`, with correct length, peer, `ReplySource::Bound`, and intact payload bytes; - payload exactly filling the buffer -> `None`; - payload larger than the buffer -> `None`. `ServerCore` is not called for `Ok(None)`: `Server::run` continues before `handle_datagram`, which existing runtime/integration tests already cover. ## Verification All run locally on macOS (aarch64-apple-darwin), all passing: - `cargo test -p irtt-server --all-features --locked` - `cargo fmt --all -- --check` - `cargo check --workspace --all-targets --all-features --locked` - `cargo test --workspace --all-targets --all-features --locked` - `cargo clippy --workspace --all-targets --all-features --locked -- -D warnings` - `RUSTDOCFLAGS="-D warnings" cargo doc --workspace --all-features --no-deps --locked` - `cargo check -p irtt-cli --no-default-features --features {server,client,tui} --all-targets --locked` - `git diff --check` - cross-target `cargo check -p irtt-server --all-targets --locked --target T` for `x86_64-unknown-linux-gnu`, `x86_64-unknown-freebsd`, `x86_64-pc-windows-gnu`, `aarch64-unknown-linux-musl`.
chatgpt-codex-connector[bot] (Migrated from github.com) reviewed 2026-08-15 04:28:23 +00:00
chatgpt-codex-connector[bot] (Migrated from github.com) left a comment

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7df85767ad

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

### 💡 Codex Review Here are some automated review suggestions for this pull request. **Reviewed commit:** `7df85767ad` <details> <summary>ℹ️ About Codex in GitHub</summary> <br/> [Your team has set up Codex to review pull requests in this repo](https://chatgpt.com/codex/cloud/settings/general). Reviews are triggered when you - Open a pull request for review - Mark a draft as ready - Comment "@codex review". If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". </details>
chatgpt-codex-connector[bot] (Migrated from github.com) commented 2026-08-15 04:28:24 +00:00

P2 Badge Make the oversized-datagram test portable to Windows

When this test runs on Windows, Tokio/Mio's recv_from reports WSAEMSGSIZE for a datagram larger than the supplied buffer instead of returning a length equal to the buffer capacity. Consequently, receive_one unwraps an error and this newly added test fails on the repository's Windows release target; handle the platform-specific truncation result or condition the assertion appropriately.

Useful? React with 👍 / 👎.

**<sub><sub>![P2 Badge](https://img.shields.io/badge/P2-yellow?style=flat)</sub></sub> Make the oversized-datagram test portable to Windows** When this test runs on Windows, Tokio/Mio's `recv_from` reports `WSAEMSGSIZE` for a datagram larger than the supplied buffer instead of returning a length equal to the buffer capacity. Consequently, `receive_one` unwraps an error and this newly added test fails on the repository's Windows release target; handle the platform-specific truncation result or condition the assertion appropriately. Useful? React with 👍 / 👎.
Lochnair (Migrated from github.com) reviewed 2026-08-15 04:31:02 +00:00
Lochnair (Migrated from github.com) commented 2026-08-15 04:31:02 +00:00

Fixed in 435315a: receive_one now returns the raw io::Result and the oversized test asserts !matches!(received, Ok(Some(_))), so it holds whether the platform truncates to the buffer (Unix) or fails the receive with WSAEMSGSIZE (Windows).

🤖 Addressed by Claude Code

Fixed in 435315a: `receive_one` now returns the raw `io::Result` and the oversized test asserts `!matches!(received, Ok(Some(_)))`, so it holds whether the platform truncates to the buffer (Unix) or fails the receive with `WSAEMSGSIZE` (Windows). _🤖 Addressed by [Claude Code](https://claude.com/claude-code)_
Sign in to join this conversation.