mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-08-31 15:37:14 +00:00
feat(inbounds): add Port-with-Fallback inbound type
Adds a new "portfallback" protocol that emits as a VLESS-TLS inbound under the hood but is paired with a sidecar table of child inbounds. Panel auto-builds settings.fallbacks at Xray-config-gen time from the sidecar — each child's listen+port becomes the fallback dest, with SNI/ALPN/path/xver match criteria pulled from the row. No more typing loopback ports by hand or keeping settings.fallbacks in sync. Backend: new FallbackService (Get/SetChildren, BuildFallbacksJSON); two new routes (GET/POST /panel/api/inbounds/:id/fallbackChildren); xray.GetXrayConfig injects fallbacks for PortFallback inbounds; the inbound model emits protocol="vless" so Xray accepts the config. Frontend: PORTFALLBACK joins the protocol dropdown; selecting it shows the standard VLESS controls plus a Fallback Children table (inbound picker + per-row SNI/ALPN/path/xver). Children are loaded on edit and replaced atomically on save. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+23
-1
@@ -6,6 +6,7 @@ import (
|
||||
"runtime"
|
||||
"sync"
|
||||
|
||||
"github.com/mhsanaei/3x-ui/v3/database/model"
|
||||
"github.com/mhsanaei/3x-ui/v3/logger"
|
||||
"github.com/mhsanaei/3x-ui/v3/xray"
|
||||
|
||||
@@ -166,8 +167,29 @@ func (s *XrayService) GetXrayConfig() (*xray.Config, error) {
|
||||
finalClients = append(finalClients, entry)
|
||||
}
|
||||
|
||||
if _, hadClients := settings["clients"]; hadClients || len(finalClients) > 0 {
|
||||
_, hadClients := settings["clients"]
|
||||
mutated := hadClients || len(finalClients) > 0
|
||||
if mutated {
|
||||
settings["clients"] = finalClients
|
||||
}
|
||||
|
||||
if inbound.Protocol == model.PortFallback {
|
||||
fallbacks, fbErr := s.inboundService.fallbackService.BuildFallbacksJSON(nil, inbound.Id)
|
||||
if fbErr != nil {
|
||||
return nil, fbErr
|
||||
}
|
||||
generic := make([]any, 0, len(fallbacks))
|
||||
for _, f := range fallbacks {
|
||||
generic = append(generic, f)
|
||||
}
|
||||
settings["fallbacks"] = generic
|
||||
if _, ok := settings["decryption"]; !ok {
|
||||
settings["decryption"] = "none"
|
||||
}
|
||||
mutated = true
|
||||
}
|
||||
|
||||
if mutated {
|
||||
modifiedSettings, err := json.MarshalIndent(settings, "", " ")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
Reference in New Issue
Block a user