You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Aug 28, 2026. It is now read-only.
After #59, when the local TCP peer closes its read side and the client hits EPIPE on write, the QUIC receiver should signal STOP_SENDING to halt inbound traffic. Currently we send both STOP_SENDING and RESET_STREAM, which aborts the send direction as well. That is consistent with a "full abort on local error" policy but is not strictly correct for half-close semantics.
We should decide on desired behavior and implement it explicitly.
Why this matters
EPIPE means we cannot deliver inbound QUIC data to the local TCP peer.
It does not necessarily mean we must abort our outbound (send) direction.
Full resets prevent half-close behavior and may terminate valid upstream data.
Current behavior
On local TCP read/write errors, we call:
picoquic_stop_sending(...)
picoquic_reset_stream(...)
This aborts both directions and removes stream state.
Proposed behavior (if we choose half-close correctness)
On write error (EPIPE):
Send STOP_SENDING only (receiver-side abort).
Keep stream state so local->remote traffic can continue.
On read error / local close:
Send RESET_STREAM (sender-side abort).
Optionally also STOP_SENDING if we intend full abort.
Scope / likely changes
In crates/slipstream-client/src/streams.rs:
Split handling for StreamWriteError vs StreamReadError.
Avoid removing the stream on write errors if we want half-close semantics.
Update tests:
Add or adjust an e2e test that verifies half-close behavior for EPIPE.
Ensure server observes STOP_SENDING in that case.
Notes
In picoquic, RESET_STREAM alone does not schedule output; STOP_SENDING does.
We recently added STOP_SENDING to fix missing on-wire resets; this issue is about policy correctness and half-close support.
True half‑close isn’t fully supported today. When the target sends FIN, we mark target_fin_pending + close_after_flush and remove the stream after flushing the FIN, which drops any queued client→target data. That’s consistent with our current full‑close policy, but a real half‑close would need to keep the stream alive for the opposite direction. If we ever add half‑close, we should revisit the close_after_flush removal in StreamClosed/prepare_to_send and avoid dropping pending client→target data.
After #59, when the local TCP peer closes its read side and the client hits EPIPE on write, the QUIC receiver should signal STOP_SENDING to halt inbound traffic. Currently we send both STOP_SENDING and RESET_STREAM, which aborts the send direction as well. That is consistent with a "full abort on local error" policy but is not strictly correct for half-close semantics.
We should decide on desired behavior and implement it explicitly.
Why this matters
Current behavior
Proposed behavior (if we choose half-close correctness)
Scope / likely changes
crates/slipstream-client/src/streams.rs:Notes