Files
shater/constant/proxy.go
T
omarandClaude Fable 5 026bba904f feat: real random strategy over the live pool; sweep becomes an honest knob; multi-WAN egress gateway
- random is a REAL urltest mode (lx SPEC 019 v2): uniform draw over LIVE
  slots only, pool sized to every member; dead slots keep their place
  (never-shrink) but are never picked, for random AND round_robin AND
  sticky (degrade-to-live). All-dead pools fall back to Select.
- Globals.SweepInterval + Globals.GroupHealth master switch, resolved by
  one pure function (model.SweepSchedule) shared by validator and apply;
  unparseable is warned-and-ON, never silently off. ConfigureSweep no
  longer resets the cursor on every cron reconcile (release blocker:
  a ~6-min cycle was restarted every 60s and never completed).
- multi-WAN egress gateway: ubus netifd status -> uci static -> main
  table; a gatewayless non-P2P egress warns CRITICAL instead of silently
  blackholing the second uplink.
- endpoint resolver (route.default_domain_resolver): bootstrap-direct
  clone of a named resolver, profile override beats globals.
- chains are composable: chain: hops flatten recursively, cycle-guarded,
  entry egress lifts only at position 0 (fail-closed mid-path).
- group test publishes its scope so "measuring" lights only the cards a
  run covers; health run is explicitly global (all_nodes).
- panel: biased-sample honesty (no ratio until a failure CAN be on
  record), profiles auto-pin plate, sweep/GroupHealth settings UI.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-22 18:20:26 +03:00

141 lines
3.8 KiB
Go

package constant
const (
TypeTun = "tun"
TypeRedirect = "redirect"
TypeTProxy = "tproxy"
TypeDirect = "direct"
TypeBridge = "bridge"
TypeBlock = "block"
TypeDNS = "dns"
TypeSOCKS = "socks"
TypeHTTP = "http"
TypeMixed = "mixed"
TypeShadowsocks = "shadowsocks"
TypeSnell = "snell"
TypeVMess = "vmess"
TypeTrojan = "trojan"
TypeNaive = "naive"
TypeWireGuard = "wireguard"
TypeHysteria = "hysteria"
TypeTor = "tor"
TypeSSH = "ssh"
TypeShadowTLS = "shadowtls"
TypeAnyTLS = "anytls"
TypeShadowsocksR = "shadowsocksr"
TypeVLESS = "vless"
TypeTUIC = "tuic"
TypeHysteria2 = "hysteria2"
TypeMASQUE = "masque"
TypeTailscale = "tailscale"
TypeCloudflared = "cloudflared"
TypeDERP = "derp"
TypeResolved = "resolved"
TypeSSMAPI = "ssm-api"
TypeAPI = "api"
TypeCCM = "ccm"
TypeOCM = "ocm"
TypeOOMKiller = "oom-killer"
TypeUSBIPServer = "usbip-server"
TypeUSBIPClient = "usbip-client"
TypeHysteriaRealm = "hysteria-realm"
TypeACME = "acme"
TypeCloudflareOriginCA = "cloudflare-origin-ca"
)
const (
TypeSelector = "selector"
TypeURLTest = "urltest"
)
// lx: SPEC 019 — URLTest balancing mode (urltest "mode" option).
const (
URLTestModeLeastTest = "least_test" // default — pick lowest-delay node (legacy urltest behaviour)
URLTestModeRoundRobin = "round_robin" // rotate over a fixed-size pool of live nodes
URLTestModeRandom = "random" // pick a uniformly-random LIVE node from the pool per connection
)
// lx: SPEC 019 — balancer.sticky_hash key components.
const (
URLTestStickyProcess = "process"
URLTestStickyDomain = "domain"
URLTestStickySourceIP = "source_ip"
URLTestStickyDestIP = "dest_ip"
URLTestStickyDestPort = "dest_port"
// URLTestStickyNone explicitly disables stickiness: sticky_hash: ["none"]. A bare [] cannot
// be used because the config decoder (badjson.UnmarshallExcludedContext) re-marshals the
// struct and collapses an empty array to nil, which is indistinguishable from "omitted" —
// so an explicit sentinel is required. Omitted → default [process, domain].
URLTestStickyNone = "none"
)
// lx: SPEC 019 — default rotation pool size when balancer.pool is unset.
const DefaultURLTestPool = 3
func ProxyDisplayName(proxyType string) string {
switch proxyType {
case TypeTun:
return "TUN"
case TypeRedirect:
return "Redirect"
case TypeTProxy:
return "TProxy"
case TypeDirect:
return "Direct"
case TypeBridge:
return "Bridge"
case TypeBlock:
return "Block"
case TypeDNS:
return "DNS"
case TypeSOCKS:
return "SOCKS"
case TypeHTTP:
return "HTTP"
case TypeMixed:
return "Mixed"
case TypeShadowsocks:
return "Shadowsocks"
case TypeSnell:
return "Snell"
case TypeVMess:
return "VMess"
case TypeTrojan:
return "Trojan"
case TypeNaive:
return "Naive"
case TypeWireGuard:
return "WireGuard"
case TypeHysteria:
return "Hysteria"
case TypeTor:
return "Tor"
case TypeSSH:
return "SSH"
case TypeShadowTLS:
return "ShadowTLS"
case TypeShadowsocksR:
return "ShadowsocksR"
case TypeVLESS:
return "VLESS"
case TypeTUIC:
return "TUIC"
case TypeHysteria2:
return "Hysteria2"
case TypeMASQUE:
return "MASQUE"
case TypeAnyTLS:
return "AnyTLS"
case TypeTailscale:
return "Tailscale"
case TypeCloudflared:
return "Cloudflared"
case TypeSelector:
return "Selector"
case TypeURLTest:
return "URLTest"
default:
return "Unknown"
}
}