Remove the intermediate b37ee660 dev-dependency and its duplicate
compatibility cases. Keep the pre-negotiation d7427c22 endpoint as
the maintained legacy baseline.
Flatten the single-use test macro into ordinary test functions and
retain negotiation, bidirectional data, half-close, and duplicate SYN
assertions. Protocol implementation files are unchanged.
Validation: all 31 tests and strict Clippy pass.
Use nonblocking output for reliable stateless responses when the queue
is full. Preserve legacy behavior and keep stateful controls pending.
Add a regression that saturates output and verifies an unknown FIN
cannot prevent the next connection from entering the handshake.
Negotiate reliable control packets in the reserved header byte while
preserving legacy handshake and output behavior for older endpoints.
Retry SYN, SYN-ACK and FIN with bounded deadlines, acknowledge FIN
independently, and handle duplicate handshakes and early empty closes.
Retain graceful close records for late FIN acknowledgements. Serialize
control sends with cleanup, cancel abandoned connects, and keep resets
and transport failures distinct from EOF.
Cover deterministic loss, reordering, queue saturation, close retention
and real d7427c2/b37ee660 interoperability. All 33 tests pass.
Both examples, formatting and strict all-targets clippy also pass.
Exclude handshake states from periodic keepalives. A startup ping can
overtake SYN, causing the peer to reset the unknown connection before
the handshake response arrives. Keep Established, LocalClosed and
PeerClosed connections eligible for their existing keepalive behavior.
Windows packet traces reproduce the premature PING, RST, then SYN on
both the original d7427c2 dependency and the close-fix branch. Add a
deterministic state-boundary regression that fails on the old behavior.
All 10 tests and both example targets pass on Linux, macOS and Windows;
Linux and macOS formatting and strict all-targets clippy checks pass.
Use a shared test helper with try_join so a failed connect immediately
cancels the pending accept instead of hanging before data timeouts are
installed. Keep the one-second connect timeout and bound the complete
handshake to report stalled accepts with useful failure context.
This exposed a Windows startup failure as a peer reset rather than an
apparent deadlock. Existing production behavior and older tests remain
unchanged.
Read receive-close state before peeking at buffered KCP data so a FIN
arriving after an empty peek cannot turn that stale result into EOF.
Evaluate expiration and remove state under the same state-map lock so
a concurrent pong cannot revive an entry selected for later deletion.
Remove corresponding connections after releasing state-map locks.
Run buffered half-close and simultaneous-close tests on a two-worker
runtime. All 9 tests and example targets pass, with 100 additional
multithreaded FIN drain repetitions, formatting and strict clippy.
Accept established connections whose peer has already closed its write
direction. Initialize their receive task with the saved FIN so empty
requests produce EOF and can still receive a response. Apply the same
handling when an empty response arrives before connect resumes.
Add deterministic tests for FIN preceding accept and for SYN-ACK plus
FIN arriving before the connecting future resumes. The delayed accept
case times out before this fix and returns EOF plus its response after.
Validation: all 9 tests and both example targets pass, with formatting
and strict all-targets clippy checks passing.
Keep acknowledged KCP data flowing to the application after peer FIN.
Delay connection cleanup until the receive task finishes, including
when both write directions close before the application reads.
Track graceful receive completion separately from resets so AsyncRead
reports EOF for FIN and keeps errors for RST or endpoint destruction.
Answer keepalive pings while the local write direction is closed.
Cover a 200 KiB request followed by a response after EOF, simultaneous
buffered shutdown across a cleanup interval, half-close keepalives,
and pending reads interrupted by reset or endpoint destruction.
Validation: all 7 library tests and both example targets pass;
cargo fmt --check and clippy --all-targets -- -D warnings pass.
Record pending server accepts in connection state so a full bounded
notification channel cannot strand an established connection. Drain
queued IDs first and claim pending state when notifications run out.
Only server handshakes enter the accept path, and claims are serialized
to prevent duplicate delivery.
Add a regression that completes 32 handshakes before accepting any of
them. It times out on the fifth accept before the fix and delivers every
connection exactly once after the fix.
Rework build.rs to auto-detect cargo-zigbuild via `CC/CC_{target}` env
vars, forward zig system include paths to bindgen for cross-compilation,
and use `llvm-ar` on macOS to avoid `ar -D` warning.