fix(sequence)!: require an arrival time on input PDUs - #1757
Draft
Benoît Cortier (CBenoit) wants to merge 3 commits into
Draft
fix(sequence)!: require an arrival time on input PDUs#1757Benoît Cortier (CBenoit) wants to merge 3 commits into
Benoît Cortier (CBenoit) wants to merge 3 commits into
Conversation
`Sequence::step` took `Option<MonotonicInstant>`, so a caller could hand over a PDU without saying when it arrived. The .NET bindings did exactly that: the FFI read its own clock on entry to `step`, timing how long the managed caller took to get around to the call rather than when the bytes came off the socket. `Sequence` now has a single required transition, `step_input`, taking a `StepInput` that is either a PDU with the instant its read completed or no PDU at all. `step` and `step_no_input` are provided methods on top of it, so a clockless input frame is unrepresentable while each state machine keeps one implementation and the trait stays object safe. `Framed` records the instant of the read that filled its buffer, so PDUs drained out of a single read all report that read even when the caller gets to them later. `into_inner` hands back a `Leftover` pairing the buffered bytes with their arrival time rather than a bare buffer, so rebuilding a `Framed` across a TLS upgrade, a websocket handover, or an RDCleanPath response keeps both. `Connection.SecurityUpgrade` in .NET now reports leftover plaintext instead of silently dropping it. The FFI exposes `MonotonicInstant.Now()`, backed by one process-wide clock and with no way to build a reading from a caller-supplied number. The managed `Framed` calls it immediately after `Stream.ReadAsync` returns and passes the result down to `Sequence.Step`. BREAKING CHANGE: `Sequence` implementors write `step_input` instead of `step`, and `Sequence::step` requires a `MonotonicInstant`. `Framed::into_inner` and `Framed::read_by_hint` return the arrival time alongside the bytes, `Framed::get_inner_mut` no longer hands out the buffer, and `Framed::last_read_at` is gone. In .NET, `ISequence.Step`, `Framed.GetInner`, `Framed.ReadExact`, and `Framed.ReadByHint` change the same way. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Benoît Cortier (CBenoit)
marked this pull request as draft
August 21, 2026 15:42
Contributor
|
This pull request is Please split it into focused pull requests that can each be reviewed on their own. When the parts build on each other, stacked pull requests let you open each one on top of the last without waiting for the one below to merge. Stacks require every branch to live in this repository, so from a fork, please open separate pull requests instead. Automated review resumes once the change is below the |
Represent managed frame timestamps as readonly values and pass their millisecond reading over the generated ABI. This removes one Rust allocation and one finalizable managed wrapper from every socket read while preserving the original read timestamp at each Step boundary. Expose leftover bytes read-only and reject zero-size hints before I/O in both Rust drivers and managed framing. Regenerate bindings, drop the unsupported test asset, and restore unrelated CredSSP generated output. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keep Diplomat-generated Step methods on their raw ulong ABI and bridge the typed managed ISequence contract from handwritten partial classes. Restore all generator-owned output so regeneration remains clean. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Sequence::steptookOption<MonotonicInstant>, so a caller could hand over a PDU without saying when it arrived. The .NET bindings did exactly that: the FFI read its own clock on entry tostep, timing how long the managed caller took to get around to the call rather than when the bytes came off the socket.Sequencenow has a single required transition,step_input, taking aStepInputthat is either a PDU with the instant its read completed or no PDU at all.stepandstep_no_inputare provided methods on top of it, so a clockless input frame is unrepresentable while each state machine keeps one implementation and the trait stays object safe.Framedrecords the instant of the read that filled its buffer, so PDUs drained out of a single read all report that read even when the caller gets to them later.into_innerhands back aLeftoverpairing the buffered bytes with their arrival time rather than a bare buffer, so rebuilding aFramedacross a TLS upgrade, a websocket handover, or an RDCleanPath response keeps both.Connection.SecurityUpgradein .NET now reports leftover plaintext instead of silently dropping it.The FFI exposes
MonotonicInstant.Now(), backed by one process-wide clock and with no way to build a reading from a caller-supplied number. The managedFramedcalls it immediately afterStream.ReadAsyncreturns and passes the result down toSequence.Step.BREAKING CHANGE:
Sequenceimplementors writestep_inputinstead ofstep, andSequence::steprequires aMonotonicInstant.Framed::into_innerandFramed::read_by_hintreturn the arrival time alongside the bytes,Framed::get_inner_mutno longer hands out the buffer, andFramed::last_read_atis gone. In .NET,ISequence.Step,Framed.GetInner,Framed.ReadExact, andFramed.ReadByHintchange the same way.