fix(routing): sync xray rules when panel inbound tags change or are deleted (#5367)

* fix(routing): sync xray rules when panel inbound tags change or are deleted

When an auto-generated inbound tag changes (e.g. port edit), propagate the
rename into xrayTemplateConfig routing rules and loopback outbounds. On
inbound delete, drop rules that only matched that tag and strip the tag from
rules that also match on domain, IP, or other fields.

Run the template update after the inbound DB transaction commits so SQLite
WAL reads see the stored xray settings reliably.

* fix(inbounds): return needRestart after deferred routing tag sync

Use a named needRestart return in UpdateInbound so the post-commit PropagateInboundTagRename defer can signal callers to restart Xray.

---------

Co-authored-by: Sanaei <ho3ein.sanaei@gmail.com>
This commit is contained in:
nima1024m
2026-06-20 01:18:31 +02:00
committed by GitHub
parent f5e50038f0
commit af3f460065
3 changed files with 634 additions and 0 deletions
+21
View File
@@ -785,6 +785,16 @@ func (s *InboundService) DelInbound(id int) (bool, error) {
return false, err
}
// Drop the deleted inbound's tag from any routing rules / loopback outbounds
// in xrayTemplateConfig so they don't point at a tag that no longer exists.
if loadErr == nil && ib.Tag != "" {
if routingChanged, syncErr := (&XraySettingService{}).RemoveInboundTagReferences(ib.Tag); syncErr != nil {
logger.Warning("DelInbound: sync routing on inbound delete failed:", syncErr)
} else if routingChanged {
needRestart = true
}
}
if err := db.Delete(model.Inbound{}, id).Error; err != nil {
return needRestart, err
}
@@ -1158,6 +1168,17 @@ func (s *InboundService) UpdateInbound(inbound *model.Inbound) (*model.Inbound,
if txErr != nil {
return inbound, false, txErr
}
// After the rename is committed, point any routing rules / loopback outbounds
// in xrayTemplateConfig at the new tag (oldInbound.Tag now holds the resolved
// new tag; tag holds the pre-edit one). Done post-commit so a sync failure
// can't roll back the inbound edit.
if tag != oldInbound.Tag {
if routingChanged, syncErr := (&XraySettingService{}).PropagateInboundTagRename(tag, oldInbound.Tag); syncErr != nil {
logger.Warning("UpdateInbound: sync routing on tag rename failed:", syncErr)
} else if routingChanged {
needRestart = true
}
}
if markDirty && oldInbound.NodeID != nil {
if dErr := (&NodeService{}).MarkNodeDirty(*oldInbound.NodeID); dErr != nil {
logger.Warning("mark node dirty failed:", dErr)