Repository navigation
Count compound responses the server split across frames #19
Description
Context
A compound request (CREATE + READ + CLOSE in one frame, for example) normally gets one compound response. MS-SMB2
§ 3.3.4.1.3 lets a server answer it in several frames instead, and Samba (plus the QNAP firmware built on it) and
Windows Server both do in some cases. The client handles that transparently: the receiver task routes each sub-response
by its MessageId, and Connection::execute_compound reassembles the results in submission order.
SmbClient::diagnostics() / Connection::diagnostics() expose per-connection counters (MetricsSnapshot), including
the four-way routing partition, status_pending_loops, and the frame-error counters. A response_splits_observed
counter was designed alongside them and deferred.
Problem
Nothing counts or logs a split today, so there's no way to see from a snapshot or a log whether a server splits
compounds, how often, or whether a performance difference between two servers lines up with it. It's a diagnostic gap,
not a correctness one: splits are handled either way.
The reason it was deferred is the shape of the actor. Each sub-op's oneshot::Receiver resolves on its own as its
MessageId arrives, so the receiver task doesn't know "N sub-responses are expected for this caller", and
execute_compound doesn't see which transport frame each sub-response came from.
Solution
Tag each routed sub-response with the transport frame it arrived in, and have execute_compound count a split when its
sub-responses carry more than one tag.
For the implementer
crates/smb2/src/client/connection.rs: inreceiver_loop, give each received transport frame a sequence number (a
per-connection counter is enough) and carry it on the routedFrameor next to it through the waiter's
oneshot::Sender. Keep it crate-private;Frameis public, so don't add a public field for this.execute_compound: after collecting its results, tickmetrics.response_splits_observedonce if the sub-responses
came from more than one frame. Count per compound call, not per extra frame, to matchcompound_requests_sent.crates/smb2/src/client/diagnostics.rs: add the field toMetricsSnapshot(it's#[non_exhaustive], so this is a
minor change), document it, and add it to theDisplayoutput.- A
debug!line naming the command chain and frame count when a split is seen would help live diagnosis too; keep it
atdebug, since a split is protocol-normal. - Tests: a mock-transport test that answers a three-op compound in two frames and asserts the counter reads 1, and one
that answers it in one frame and asserts 0 (the existingexecute_compound_partial_failure_routes_correctlyshows how
to script compound answers on the mock).AGENTS.mdpitfall 13 andclient/CLAUDE.md§ Gotchas both say "nothing
counts or logs a split"; update them.
Impact: Makes server-side compound splitting visible in diagnostics · Size: S (one tag through the demux, one
counter, two tests)
Origin: Diagnostics plan § response_splits_observed is deferred
Activity