fix(outbounds): preserve stable subscription tags - #6345
Open
dawNotPoi wants to merge 1 commit into
Open
Conversation
An inserted link could claim a previous positional tag before the existing identity that owned it was processed. The owner was then suffixed and the swapped mapping persisted across refreshes. Reserve tags for identities still present in the batch so positional fallback, fresh allocation, and collision suffixes cannot take them.
dawNotPoi
marked this pull request as ready for review
August 28, 2026 05:38
Contributor
Code reviewNo blocking issues — 0 🔴 / 0 🟡 / 0 🟣 The fix is proportionate to the bug: a reservation pre-pass plus two guard conditions inside I traced the algorithm rather than taking the tests' word for it, and it holds up:
One thing worth carrying into the release note, already acknowledged in the PR description: an install whose Coverage — head
Reviewed head: c309cd3 |
4 tasks
kuzzrus
added a commit
to kuzzrus/3x-ui-awg
that referenced
this pull request
Sep 1, 2026
A newly inserted subscription link could reuse the positional tag of an existing server before that server's own entry was processed later in the same refresh loop. The existing server was then bumped to a suffixed tag instead, silently repointing any routing or balancer rule that referenced the original stable tag at a different physical server. Ported from upstream MHSanaei#6345. Reserves historical tags for identities still present in the current fetch before assigning tags to new/renamed links, so neither the positional-fallback path nor a fresh-tag collision suffix can steal a tag that rightfully belongs to another identity still in the batch. Verified: all 8 TestAssignStableTags subtests pass with the fix; the 3 new ones confirmed to fail without it (reproduces the exact wrong-tag assignment). Reviewed by the repo's automated Claude Bot (verdict: Approve); one doc-comment suggestion applied, one pre-existing orthogonal bug (duplicate identities within a subscription) tracked separately per the bot's own recommendation not to bolt it onto this PR, one upgrade caveat noted in the PR description instead of a code change. Upgrade note: this fix prevents the mis-assignment from recurring, it does not repair a subscription that already hit it -- see PR discussion for the recovery steps if a routing/balancer rule seems to be pointing at the wrong server on a subscription that predates this fix. Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Why
A newly inserted subscription link could reuse the positional tag of an existing server before that server was processed. The existing server was then assigned a suffixed tag, and the swapped identity-to-tag mapping was persisted across refreshes.
This could silently make an exact routing or balancer tag point to a different physical server.
Closes #6341
Existing subscriptions whose mapping was already corrupted cannot be repaired unambiguously and may still need to be removed and added again once.
Type of change
Areas affected
How was this tested?
Regression coverage confirms:
Commands run:
go test -count=100 -run '^TestAssignStableTags$' ./internal/web/servicego test -race -shuffle=on -count=1 ./internal/web/servicego test ./internal/web/service -count=1make lintmake verifygit diff --checkThe inserted-link regression test was also confirmed to fail against the parent commit and pass with this change.
Screenshots / recordings
N/A — backend-only behavior change.
Breaking changes
None.
Checklist
go build ./...and the test suite pass locally.npm run lint,npm run typecheck, andnpm run buildpass.