Skip to content

Support validated website WebSockets and owned TCP shutdown - #42

Merged
cppla merged 3 commits into
mainfrom
codex/websocket-cover-safe-lifecycle
Oct 2, 2026
Merged

cppla merged 3 commits into
mainfrom
codex/websocket-cover-safe-lifecycle

Conversation

@cppla

@cppla cppla commented Oct 2, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Add strictly validated, fixed-origin HTTP/1.1 website WebSocket passthrough without changing native/authenticated proxy protocols or H2/H3 extended CONNECT routing.
  • Validate request eligibility and 101 proof against trusted request-local metadata; reject malformed/unsolicited/non-duplex responses, preserve upstream body ownership and optional CloseWrite.
  • Own admitted raw TCP sockets and their BaseContext across Hijack so Close/Serve cancellation also releases upgraded connections, blocked writes and admission slots.
  • Preserve credential/hop-header scrubbing and ordinary informational-response/trailer/cancellation behavior; document source-build behavior and explicit limitations.
  • Address automated review with ASCII-valid deduplicated nomination collection followed by one destination-header pass, replacing H×T rescanning. Six semantic regression cases and four pure-helper benchmark cases are included.
  • Correct the delayed-Accept test's synchronization: physical peer closure remains proven before ungating; admission release is asserted only after the existing joined Close. No production change or enlarged test budgets for this correction.

Final source / local verification

Tested/pushed head: 870b57eea8bec01a63dd4b4cbb68ffb7e4261fe2; tree a9020b16c8d2c5ed6d1edf5323ef717963168212.
Full Go/docs/module/README manifest: 209 paths, SHA-256 652195884757ed340a14b84b8cc6c72707417ebd58f870c7fc916bb34e9a008a.

  • Final make check and make race: passed on cached Go1.25.13 Darwin/arm64, offline.
  • All new tests under race ×3:20 exact top names /60 top executions,180 terminal leaves /540 leaf executions,582 RUN/PASS entries.
  • Final lifecycle/owner focused race passed Go1.27.1 ×20 and Go1.25.13 ×3. A deterministic actual-TCP scheduling diagnostic confirms EOF can precede local admission release; its synthetic return gate is explicitly not a blocked-write proof.
  • Fresh final isolated Linux/arm64 component gate:143 exact top executions /814 RUN entries, including new cases ×3 and83 existing control tops. Offline CGO0 binaries; network-none/read-only/capability-dropped owned container; source/compiler/script/binary manifests unchanged; owned container removed. This is Linux component evidence, not Linux race or remote deployment.
  • Preserved causal negative overlays demonstrate old socket ownership, wrong101 proof, no-Hijacker body cleanup and invalid-Unicode Accept failures. The final old-production delayed-Accept negative still fails actual peer closure before ungating; it does not fail the corrected slot ordering.
  • Independent source/test reviews checked the final repairs. Bounded local helper benchmark supports removal of repeated scans; set memory/constant overhead remains and no network throughput/denial-of-service claim is made.

Actions / review

Prior head2107b93 passed CI/CodeQL/netem, then automated review found one actionable nomination-scan finding; repaired in c86066b. Its CI attempt1 passed10/11 jobs but exposed the delayed-Accept fixture synchronization issue in Go1.27. Full original failures/receipts are retained; no blind CI retry was requested. These earlier runs are not final-head gates.
Final-head CI37059387372 (all11 jobs), CodeQL37059387261 and netem37059387314 all completed successfully at exact head870b57e, pull_request/attempt1. Actual Docker integration, dual-platform OCI export, netem completion log/artifact and synthetic checkout tree/parents were checked. Final official review snapshot found zero unresolved/new actionable inline threads; the sole original COMMENTED review remains historical, not a new approval. Its source-backed nomination finding was repaired and the thread resolved/outdated.

Merge and main verification

Squash-merged to main commit 0d42cc2f825aae217c802650a65443f3ce2bda6f. Official/local tree a9020b16c8d2c5ed6d1edf5323ef717963168212 exactly equals the tested final head tree; parent is the unchanged base. Local main is fast-forwarded and clean; before/after209-source manifest matches. Postmerge all-new race ×3 passed again:20 tops /60 top executions,180 terminal leaves /540 leaf executions,582 RUN/PASS.
Separate exact-main push/attempt1 CI37060011602 (all11 jobs), CodeQL37060011645 and netem37060011711 completed successfully. Main OCI checkout is the actual merge commit; real Docker integration and amd64/arm64 manifest/tarball export completed. No release/tag or deployment is included.

Limits

This is fixed-website compatibility and lifecycle correctness, not browser identity or traffic-classification parity. No browser/PCAP campaign, remote SSH, release/tag or production deployment was performed. Close aborts sockets rather than negotiating WebSocket close frames. Origin/subprotocol/extensions/access policy remain the website/client's responsibility; raw hijacked101 is not promised the bound Alt-Svc override. The native Go ordinary-response Connection: close information-loss boundary is documented and unchanged. Existing impaired netem evidence covers native direct/quic/tls only, not web H2/H3.

Copilot AI balanced review requested due to automatic review settings October 2, 2026 19:52

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

🔵 Needs a closer look

Header-filtering CPU amplification remains unresolved, and protocol handoff and concurrent shutdown require final human validation.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Adds validated fixed-origin website WebSockets and preserves server ownership of upgraded TCP connections.

Changes:

  • Validates H1.1 WebSocket handshakes while retaining header filtering.
  • Closes upgraded sockets during shutdown without closing shared transports.
  • Adds regression tests and documents compatibility boundaries.
File Description
README.md Introduces source-build WebSocket support.
internal/​tunnel/​websocket_lifecycle_test.go Tests upgraded connection shutdown and capacity release.
internal/​tunnel/​websocket_combined_test.go Tests combined-server WebSockets across TLS versions.
internal/​tunnel/​web_tcp_owner.go Tracks and closes owned TCP sockets.
internal/​tunnel/​web_tcp_owner_test.go Tests ownership and late acceptance.
internal/​tunnel/​web_limits.go Adds ownership registration and once-only closure.
internal/​tunnel/​web_h2.go Integrates socket ownership into server shutdown.
internal/​cover/​websocket.go Implements handshake validation and body ownership.
internal/​cover/​websocket_test.go Tests validation and cleanup boundaries.
internal/​cover/​websocket_integration_test.go Tests wire exchanges and rejection paths.
internal/​cover/​handler.go Integrates validated upgrades and header filtering.
docs/​WEB_COVER.md Defines WebSocket support and limitations.
docs/​PROTOCOL.md Clarifies separation from tunnel protocols.
docs/​DEPLOYMENT.md Documents deployment compatibility.
docs/​ARCHITECTURE.md Explains upgrade ownership and response boundaries.

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

Comment thread internal/cover/handler.go Outdated
@cppla
cppla merged commit 0d42cc2 into main Oct 2, 2026
14 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