Skip to content

fix(outbound): test VLESS vnext endpoints - #6358

Merged
MHSanaei merged 1 commit into
MHSanaei:mainfrom
sanmaxdev:fix/vless-vnext-tcp-probe
Sep 2, 2026
Merged

fix(outbound): test VLESS vnext endpoints#6358
MHSanaei merged 1 commit into
MHSanaei:mainfrom
sanmaxdev:fix/vless-vnext-tcp-probe

Conversation

@sanmaxdev

Copy link
Copy Markdown
Contributor

Summary

  • Read VLESS TCP probe endpoints from the vnext form.
  • Keep the existing flat address and port form as a fallback.
  • Add regression coverage for both forms and invalid vnext entries.

Why

VLESS outbounds stored in the vnext form currently produce no TCP probe endpoints even though the panel accepts that form.

Closes #6312

Type of change

  • Bug fix
  • New feature
  • Refactoring (no behavior change)
  • Documentation
  • Tests only
  • Build / CI / tooling
  • Other

Areas affected

  • Frontend (UI / panel pages)
  • Backend (API endpoints, login, settings)
  • Xray config generation
  • Subscription (share links / Clash / JSON)
  • Statistics / traffic counters
  • Database / migrations
  • Install / upgrade script
  • Docker image
  • Multi-node (sub-nodes)

How was this tested?

  • go test ./internal/web/service/outbound -run '^TestExtractOutboundEndpointsVLESS$' -count=1
  • make gen-check lint format-check typecheck msw-worker-check test-go build build-storybook
  • npm test -- --maxWorkers=1 --fileParallelism=false

Breaking changes

None.

Checklist

  • I tested the change locally and confirmed the described behavior.
  • I added or updated tests for the new behavior.
  • go build ./... and the test suite pass locally.
  • My commits follow the project's existing message style.
  • I have no unrelated changes mixed into this PR.

@github-actions

Copy link
Copy Markdown
Contributor

Code review

No blocking issues0 🔴 / 0 🟡 / 0 🟣

The vless arm of extractOutboundEndpoints now mirrors the vmess arm directly above it, then falls back to the flat address/port pair only when vnext yielded nothing. out is empty on entry to the switch, so len(out) == 0 reads exactly as "vnext produced no usable endpoint" and cannot pick up state from another arm. addServer already rejects an empty host or a non-positive port, so a partial vnext entry is skipped rather than emitting ":0". Reachability checks out: the panel’s own form reader parses stored VLESS outbounds in vnext form (outbound-form-adapter.ts L121-L131), and the TCP lane probes the stored outbound object verbatim (probe_http.go L207-L216), so a raw-JSON vnext outbound really did reach the old flat-only lookup and get dropped.

The "vnext endpoints" subtest goes red on the base branch (base returns nil against a two-element want), so the fix carries a test that fails without it. The other two subtests pass on both sides — fine as regression fencing around the preserved flat path, since one subtest does discriminate.

Coverage

  • Diff read in full: 2 files, +64/−1, head edda9e6162870e829e51bc34c4fc4fe23f6bf4f3.
  • Callers: the only non-test caller is testOutboundTCP (outbound.go L162-L168), which already fans out over N endpoints and reduces to best-delay — multi-endpoint VLESS is the shape vmess/trojan/wireguard already return, so nothing downstream changes.
  • Compile surface: TestExtractOutboundEndpointsVLESS collides with no symbol in egress_trace_test.go, probe_http_test.go or outbound_commit_postgres_test.go; no existing test pinned the old flat-only VLESS behaviour.
  • Wire format: probe-only change. internal/util/link/outbound.go, internal/sub/clash_external.go and the sub JSON service are untouched, and clashProxyFromExternal only ever sees link-parser output (always flat for VLESS), so the three link implementations do not diverge.
  • CLAUDE.md: no new route, model, migration or i18n key; no comment blocks added; stdlib table-driven test asserting the exact slice; fix is the minimum that removes the bug.
  • CI on this head: go-test, golangci, frontend, codegen, govulncheck, fuzz-smoke, postgres-durable-first, CodeQL and all 8 build-matrix jobs passed; race was still in progress when this review ran.
  • Unverified here: upstream xray-core’s VLESS outbound conf schema (whether the core itself still accepts vnext) — the Go module cache is unavailable in this sandbox. The conclusion does not rest on it: reachability is established panel-side, and the flat path is preserved either way.

@MHSanaei
MHSanaei merged commit c62ee0b into MHSanaei:main Sep 2, 2026
25 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.

[Bug]: TCP Test fails for VLESS outbounds with standard vnext configuration format ("No testable endpoint")

2 participants