mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-09-17 15:47:14 +00:00
fix(node): sweep a selected inbound the node reports without its prefix
In "selected" sync mode the reconcile sweep built its set of managed tags verbatim from node.InboundTags. A panel-created node inbound is stored with an n<id>- prefix (composeInboundTag) and pushed to the node with that prefix stripped (wireInbound), so the tag the node reports never matched the set and the sweep skipped it. The effect is the case the sweep exists for: an operator deletes a node inbound while the node is offline, and the node keeps serving it — and its clients — indefinitely. Only unprefixed tags were unaffected, which is why the existing selected-mode test did not catch it. nodeSelectedTagSet already builds both tag forms for exactly this reason and is used by the snapshot filter; the sweep now uses it too, so the two agree.
This commit is contained in:
@@ -3,6 +3,7 @@ package service
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
@@ -404,3 +405,29 @@ func TestEnsureInboundTagAllowed(t *testing.T) {
|
||||
t.Fatalf("all-mode node must stay without tags, got %#v", gotAll.InboundTags)
|
||||
}
|
||||
}
|
||||
|
||||
// A panel-created node inbound is stored as "n<id>-tag" and pushed to the node
|
||||
// with the prefix stripped, so the sweep's selected set must match both forms.
|
||||
func TestReconcileNode_SelectedModeSweepsPrefixedSelectedTag(t *testing.T) {
|
||||
setupConflictDB(t)
|
||||
|
||||
ts, deletedIDs := fakeNodePanel(t, map[string]int{
|
||||
"keep": 1,
|
||||
"selected-gone": 2,
|
||||
"unmanaged": 3,
|
||||
})
|
||||
node := reconcileTestNode(t, ts, "sel-prefix-node", "selected", nil)
|
||||
prefix := fmt.Sprintf("n%d-", node.Id)
|
||||
node.InboundTags = []string{prefix + "keep", prefix + "selected-gone"}
|
||||
seedInboundConflictNode(t, prefix+"keep", "", 443, model.VLESS, `{"network":"tcp"}`, `{"clients":[]}`, &node.Id)
|
||||
|
||||
svc := InboundService{}
|
||||
if err := svc.ReconcileNode(context.Background(), runtime.NewRemote(node, nil), node); err != nil {
|
||||
t.Fatalf("ReconcileNode: %v", err)
|
||||
}
|
||||
|
||||
got := deletedIDs()
|
||||
if len(got) != 1 || got[0] != 2 {
|
||||
t.Fatalf("deleted remote ids = %v, want [2] (prefixed selected tag must be swept, unmanaged 3 must survive)", got)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user