mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-09-26 19:56:37 +08:00
feat(settings): allow a balancer as the panel traffic outbound
The panel egress is injected as a routing rule, so a routing balancer is a valid target for it (unlike the geodata download, which dials a forced outbound tag and bypasses the router). Surface routing balancers in the panel outbound picker as a separate group, and emit balancerTag instead of outboundTag in the injected egress rule when the configured tag names a balancer, so the panel's own traffic load-balances across its members.
This commit is contained in:
@@ -317,9 +317,17 @@ func injectPanelEgress(cfg *xray.Config, outboundTag string) {
|
||||
}
|
||||
rules, _ := routing["rules"].([]any)
|
||||
rule := map[string]any{
|
||||
"type": "field",
|
||||
"inboundTag": []any{PanelEgressInboundTag},
|
||||
"outboundTag": outboundTag,
|
||||
"type": "field",
|
||||
"inboundTag": []any{PanelEgressInboundTag},
|
||||
}
|
||||
// The configured tag may name a routing balancer instead of a concrete
|
||||
// outbound. A field rule can target either, so emit the matching key —
|
||||
// balancerTag load-balances the panel's own traffic across the balancer's
|
||||
// outbounds, while a plain outbound tag keeps the original behavior.
|
||||
if routingTagIsBalancer(routing, outboundTag) {
|
||||
rule["balancerTag"] = outboundTag
|
||||
} else {
|
||||
rule["outboundTag"] = outboundTag
|
||||
}
|
||||
routing["rules"] = append([]any{rule}, rules...)
|
||||
newRouting, err := json.Marshal(routing)
|
||||
@@ -350,6 +358,29 @@ func injectPanelEgress(cfg *xray.Config, outboundTag string) {
|
||||
})
|
||||
}
|
||||
|
||||
// routingTagIsBalancer reports whether tag names a balancer in the parsed
|
||||
// routing section. The panel-egress rule targets a balancer via balancerTag and
|
||||
// a concrete outbound via outboundTag, so the caller picks the key from this.
|
||||
func routingTagIsBalancer(routing map[string]any, tag string) bool {
|
||||
if tag == "" {
|
||||
return false
|
||||
}
|
||||
balancers, ok := routing["balancers"].([]any)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
for _, b := range balancers {
|
||||
bm, ok := b.(map[string]any)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if t, ok := bm["tag"].(string); ok && t == tag {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// mergeSubscriptionOutbounds appends the subscription outbounds to the
|
||||
// OutboundConfigs array of the xray config. It works on the already-unmarshaled
|
||||
// template so that manually configured outbounds are never overwritten.
|
||||
|
||||
Reference in New Issue
Block a user