Skip to content

test: Prove CONNECT-IP works over HTTP/3 and HTTP/2 - #1136

Merged
privateip merged 3 commits into
mainfrom
fix/issue-973
Oct 27, 2026
Merged

privateip merged 3 commits into
mainfrom
fix/issue-973

Conversation

@privateip

@privateip privateip commented Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Production MASQUE work needs proof that CONNECT-IP works with an independent client over HTTP/3 and over HTTP/2 with UDP/443 blocked, and until now the server had only been tested with clients built on its own library.

This adds a root-only suite, run with one task command, that drives the released Xray-core client through both transports into a VPC namespace and checks 1280-byte inner packets both ways, certificate rejection, blocked UDP, and that malformed input or cancellation on one request leaves its sibling working.

HTTP/3 uses the existing server unchanged. HTTP/2 uses a test-only prototype, since the production listener belongs to #981, and the report lists what that listener still needs, along with the quiche client's packet-sizing defect.

Test plan

  • Both transports pass the suite in five runs in a row, the last on this head
  • With UDP/443 dropped, HTTP/3 fails with no session while HTTP/2 completes every round trip
  • quiche fails as released and passes with its sizing corrected
  • Lint, build, unit and end-to-end tests pass

Fixes #973

The CONNECT-IP server had only been exercised with clients built on its own library, and nothing showed that a tunnel works over HTTP/2 with UDP/443 blocked. Production protocol work depends on both transports carrying 1280-byte inner IPv6 packets with an independent client.

tests/connectipinterop builds a client, server and VPC network namespace with a TUN backend and echo servers, then drives Xray-core's MASQUE client over each transport. connectip.Server serves HTTP/3. An HTTP/2 prototype on net/http's Extended CONNECT and a bounded capsule codec serves HTTP/2 through the same Admission and PacketBackend interfaces; the production listener remains separate work.

The suite checks negotiated ALPN, exact 1280-byte packets both ways, certificate rejection, HTTP/2 with UDP/443 dropped by nftables, and that malformed capsules or a cancelled request leave a sibling request on the same connection forwarding. Raw HTTP/3 and HTTP/2 clients drive the negative cases.

task test:connectip-interop downloads the pinned Xray release, checks its SHA-256 and runs the suite as root. tests/connectipinterop/quiche builds google/quiche's masque_client as released and with its CONNECT-IP packet sizing corrected, for the existing opt-in quiche test.
Dependent MASQUE work needs to know which server stacks and independent clients carry CONNECT-IP over both transports, what failed, and what an HTTP/2 listener still lacks.

The report covers how to run the suite, the selected stacks and the quiche candidate that failed and why, what each check proves, a recorded run, the shared Admission/Lease/PacketBackend boundary, the work left for the production HTTP/2 listener, and the disposition of each earlier CONNECT-IP server finding. The MASQUE contract and the Edge index link to it.

Resolves: #973
@privateip privateip self-assigned this Oct 27, 2026
The recorded run predated the last change to the suite's teardown. Record the run made on the published code, which also passed all 33 tests.
@privateip
privateip marked this pull request as ready for review October 27, 2026 15:20
@privateip
privateip requested a review from a team as a code owner October 27, 2026 15:20
@privateip
privateip enabled auto-merge October 27, 2026 15:20
@privateip

Copy link
Copy Markdown
Collaborator Author

The first review pass split, and the repository owner reviewed both reports and approved moving to ready.

The adversarial reviewer returned VERDICT merge with no defects. Its one decision point was that CI cannot exercise the root-only suite, because the fixture tests skip without root and Xray. The author closed that by running task test:connectip-interop as root, which passed 33 of 33 in five consecutive runs, the last on this head. Its nit about run counts was fixed in 29afbdd.

The conventions reviewer returned VERDICT hold on two warnings: the commit subjects are 64 and 56 characters, over the 50-character target. Its nits were the mix of Fixes and Resolves keywords and the summary naming #981. The owner approved proceeding without rewriting the subjects. They sit under the 72-character hard limit and match recent main history, and rewriting them would need a force-push of a published branch. The nits were not applied.

CI on 29afbdd passed every required check: Build, Lint, Unit Tests, Unit Tests (root), E2E Tests, Manifests, Documentation, Service API bundle, and the image and bundle publish jobs. The publish-service-api job was skipped. No reviewer was requested beyond the code owners, because the repository configures no human reviewer. Auto-merge is enabled with the merge method, the only method the main ruleset allows. The ruleset requires one code-owner approval and dismisses approvals on push, so the merge waits for a human approval on this head.

@privateip
privateip disabled auto-merge October 27, 2026 15:23
@privateip
privateip merged commit 509c9c9 into main Oct 27, 2026
23 checks passed
@privateip
privateip deleted the fix/issue-973 branch October 27, 2026 15:23
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.

Prove CONNECT-IP interoperability over HTTP/3 and HTTP/2

2 participants