Skip to content

fix: cancel SOCKS TCP setup on forced close - #35

Merged
cppla merged 1 commit into
mainfrom
codex/socks-tcp-setup-cancellation
Oct 2, 2026
Merged

cppla merged 1 commit into
mainfrom
codex/socks-tcp-setup-cancellation

Conversation

@cppla

@cppla cppla commented Oct 2, 2026 •

Copy link
Copy Markdown
Owner

Summary

Cancel pending SOCKS5 TCP CONNECT setup when its tracked downstream connection is fully closed, instead of leaving that caller active until the existing dial budget expires.

  • Reuse the existing tracked-connection full-close context; skip dialing when already closed.
  • Keep the shared native client's physical dial client-owned, with no added downstream TCP reader.
  • Preserve early application payload, TCP write-half-close and established relays beyond their original setup deadline.
  • Document the source-build boundary and context-aware dialer limitation.

Validation completed on 33e6add22ce91b28b4b710a95ce534426d513020

  • make check and make race: exit 0, full repository.
  • Formal forced-close/closed-before-dial/shared-native-dial regressions: race ×3, pass.
  • Healthy real TCP early-byte/half-close/reverse-response and reply-after-original-setup-deadline controls: race ×3, pass.
  • Formal negative control: removing only the full-close binding through a one-file overlay makes both unchanged forced-close subcases fail at their original one-second completion assertion. Actual caller context, DialContext and production handler remain pending; independent failure cleanup joins all workers.
  • Preserved old reproduction fails before the fix and passes race ×3 after it.
  • Linux/arm64, existing isolated Docker image: four new top-level tests ×3 plus 19 existing HTTP/context/SOCKS UDP/relay controls, 31 top-level passes. Source/module inventories match before compilation, after compilation and after execution; test binary SHA-256 e3777fb53d9bed8e5c6d8ead4db34b3c137f9f0858a404f27f9edc5dcd1eac90.
  • Real native QUIC Initial and same-source/same-destination-CID retransmission demonstrate the physical handshake survives frontend cancellation. Native default 5s budget and proxy default 15s budget are unchanged.
  • Independent production/documentation review: no blocker.

Exact-head GitHub verification completed, all on attempt 1:

  • CI run 37029611743: all 11 jobs passed, including Go 1.25.13/1.27, macOS, Windows UDP continuity, full race, reachable-vulnerability scan, four platform builds, container integration and multi-platform OCI export. Actual container logs contain the integration success and OCI export markers.
  • CodeQL run 37029611718: passed.
  • Linux netem run 37029611875: passed; actual namespace/netem log contains its success marker.
  • Automated review reported no findings; there are no inline review threads.

Post-merge verification completed on ae60c176fcac70301dcd593d05f5225dcd66efbb:

  • Local main and origin/main are clean, synchronized and tree-identical to the tested PR head (dca06fd185bcda9e61c66694c504357e105e4e18). Main targeted race ×3 passed.
  • Main CI 37030030527: current aggregate success, all 11 jobs successful. Attempt 1 had one macOS failure in existing TestProxyComposition/quic, waiting for a SOCKS reply at the unchanged 5s operation deadline; new proxy regressions passed in that same job. The full initial log is preserved.
  • Before retrying, present code and binding-removal overlay each passed actual QUIC composition race ×10 at the failed shuffle seed, full integration shuffled race ×3 passed, and full repository tests at the failed CI shuffle seed passed. These are non-reproduction evidence, not proof of the remote root cause.
  • Exactly one failed-jobs-only rerun was requested. macOS attempt 2 passed, including integration and proxy packages; the other ten successful jobs retain their original execution timestamps. No source, assertion, timeout or workflow was changed to obtain this result.
  • Main CodeQL 37030030661 and main Linux netem 37030030476: success on attempt 1. Actual main container integration/OCI-export/netem success logs were verified.

The initial macOS timeout remains unexplained and is not described as a fixed infrastructure cause or a first-attempt main pass.

Boundaries

Custom dialers ignoring context cannot be forcibly interrupted. This does not add immediate peer-disconnect detection during pending TCP setup, does not change protocol framing or dependencies, and does not modify v1.0.1 or create a release/tag. No remote host or large capture campaign was used. These lifecycle tests do not establish traffic equivalence or comparative performance.

Copilot AI balanced review requested due to automatic review settings October 2, 2026 15:48

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

The lifecycle change is narrowly scoped, correct, and covered by comprehensive regression tests.

Review effort: Balanced
Findings: None

What changed in this PR

Cancels pending SOCKS5 TCP setup when the downstream connection is forcibly closed while preserving established relay behavior.

Changes:

  • Binds TCP dialing to the tracked connection lifecycle.
  • Adds cancellation, half-close, payload, and shared-QUIC regression tests.
  • Documents lifecycle and dialer limitations.
File Description
internal/​proxy/​socks5.go Cancels pending CONNECT setup on full close.
internal/​proxy/​lifecycle.go Generalizes connection-context documentation.
internal/​proxy/​socks5_tcp_setup_cancel_test.go Tests forced-close cancellation and shared dialing.
internal/​proxy/​socks5_tcp_setup_preserve_test.go Tests payload, half-close, and deadline preservation.
docs/​DEPLOYMENT.md Documents behavior and limitations.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@cppla
cppla merged commit ae60c17 into main Oct 2, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants