diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua
index ffb01c33..cb8e92ec 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua
@@ -808,6 +808,9 @@ o:value("UseIPv6v4", translate("Prefer IPv6"))
o:value("UseIPv4", translate("IPv4 Only"))
o:value("UseIPv6", translate("IPv6 Only"))
+o = s:option(Flag, _n("happy_eyeballs"), translate("Enable Happy Eyeballs"), translate("Attempts IPv4 and IPv6 simultaneously; automatically uses the faster connection."))
+o.default = 0
+
local protocols = s.fields[_n("protocol")].keylist
if #protocols > 0 then
for i, v in ipairs(protocols) do
@@ -819,7 +822,11 @@ if #protocols > 0 then
s.fields[_n("address")]:depends(depends_condition)
s.fields[_n("port")]:depends(depends_condition)
s.fields[_n("domain_resolver")]:depends(depends_condition)
- s.fields[_n("domain_strategy")]:depends(depends_condition)
+ s.fields[_n("happy_eyeballs")]:depends(depends_condition)
+
+ local strategy_depends = api.clone(depends_condition)
+ strategy_depends[_n("happy_eyeballs")] = false
+ s.fields[_n("domain_strategy")]:depends(strategy_depends)
if v ~= "hysteria2" then
s.fields[_n("tcp_fast_open")]:depends({ [_n("protocol")] = v })
diff --git a/luci-app-passwall/luasrc/passwall/util_xray.lua b/luci-app-passwall/luasrc/passwall/util_xray.lua
index a6454928..438bde06 100644
--- a/luci-app-passwall/luasrc/passwall/util_xray.lua
+++ b/luci-app-passwall/luasrc/passwall/util_xray.lua
@@ -146,7 +146,13 @@ function gen_outbound(flag, node, tag, proxy_table)
mark = 255,
domainStrategy = node.domain_strategy or "UseIP",
tcpFastOpen = (node.tcp_fast_open == "1") and true or nil,
- tcpMptcp = (node.tcpMptcp == "1") and true or nil
+ tcpMptcp = (node.tcpMptcp == "1") and true or nil,
+ happyEyeballs = (node.happy_eyeballs == "1") and {
+ TryDelayMs = 250,
+ PrioritizeIPv6 = false,
+ Interleave = 1,
+ MaxConcurrentTry = 4
+ } or nil
},
network = node.transport,
security = node.stream_security,
diff --git a/luci-app-passwall/po/zh-cn/passwall.po b/luci-app-passwall/po/zh-cn/passwall.po
index 726e5952..9ea4fc6e 100644
--- a/luci-app-passwall/po/zh-cn/passwall.po
+++ b/luci-app-passwall/po/zh-cn/passwall.po
@@ -1922,6 +1922,12 @@ msgstr "如果节点地址是域名,则将使用此 DNS 进行解析。"
msgid "Note: For node-specific DNS only. Keep Auto to avoid extra overhead."
msgstr "注意:仅用于节点专用 DNS,通常请保持自动,以免增加开销。"
+msgid "Enable Happy Eyeballs"
+msgstr "启用 Happy Eyeballs"
+
+msgid "Attempts IPv4 and IPv6 simultaneously; automatically uses the faster connection."
+msgstr "同时尝试 IPv4 和 IPv6 连接,自动使用更快的连接。"
+
msgid "Supports only Xray or Sing-box node types."
msgstr "仅支持 Xray 或 Sing-box 类型节点。"
diff --git a/luci-app-ssr-plus/luasrc/view/shadowsocksr/advanced_switch_compact.htm b/luci-app-ssr-plus/luasrc/view/shadowsocksr/advanced_switch_compact.htm
index c85245e8..ed750db3 100644
--- a/luci-app-ssr-plus/luasrc/view/shadowsocksr/advanced_switch_compact.htm
+++ b/luci-app-ssr-plus/luasrc/view/shadowsocksr/advanced_switch_compact.htm
@@ -1,31 +1,59 @@