Răsfoiți Sursa

Merge branch 'fw876:master' into master

FluffyTigerfear 2 ani în urmă
părinte
comite
aab0619c7d

+ 4 - 7
gn/Makefile

@@ -9,17 +9,14 @@ PKG_RELEASE:=1
 
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_URL:=https://gn.googlesource.com/gn.git
-PKG_SOURCE_DATE:=2023-04-05
-PKG_SOURCE_VERSION:=28b7b6c507eb808567e3aea446cd259f7691fddc
-PKG_MIRROR_HASH:=5b112442eabea4b906cc409237fac13b8efb4f5acb25989b1883d5ce96deebd2
+PKG_SOURCE_DATE:=2024-01-24
+PKG_SOURCE_VERSION:=a2e2717ea670249a34b0de4b3e54f268d320bdfa
+PKG_MIRROR_HASH:=13d4b2ac0ca78cedf25ca9919c2969eb37c36b6dd5e8e6e8cd114441500daa76
 
 PKG_LICENSE:=BSD 3-Clause
 PKG_LICENSE_FILES:=LICENSE
 PKG_MAINTAINER:=Tianling Shen <[email protected]>
 
-ifneq ($(wildcard $(TOPDIR)/feeds/packages/devel/ninja/ninja.mk),)
-PKG_BUILD_DEPENDS+= ninja/host
-endif
 PKG_HOST_ONLY:=1
 HOST_BUILD_PARALLEL:=1
 
@@ -45,7 +42,7 @@ define Host/Configure
 endef
 
 define Host/Compile
-	ninja -C $(HOST_BUILD_DIR)/out
+	+$(NINJA) -C $(HOST_BUILD_DIR)/out
 endef
 
 define Host/Install

+ 0 - 11
gn/patches/010-gcc.patch

@@ -1,11 +0,0 @@
---- a/build/gen.py
-+++ b/build/gen.py
-@@ -368,7 +368,7 @@ def WriteGNNinja(path, platform, host, o
-     cxx = os.environ.get('CXX', 'g++')
-     ld = os.environ.get('LD', 'g++')
-     ar = os.environ.get('AR', 'ar -X64')
--  elif platform.is_msys() or platform.is_mingw():
-+  elif platform.is_msys() or platform.is_mingw() or platform.is_linux():
-     cxx = os.environ.get('CXX', 'g++')
-     ld = os.environ.get('LD', 'g++')
-     ar = os.environ.get('AR', 'ar')

+ 2 - 2
gn/src/out/last_commit_position.h

@@ -3,7 +3,7 @@
 #ifndef OUT_LAST_COMMIT_POSITION_H_
 #define OUT_LAST_COMMIT_POSITION_H_
 
-#define LAST_COMMIT_POSITION_NUM 2085
-#define LAST_COMMIT_POSITION "2085 (28b7b6c507eb)"
+#define LAST_COMMIT_POSITION_NUM 2143
+#define LAST_COMMIT_POSITION "2143 (a2e2717ea670)"
 
 #endif  // OUT_LAST_COMMIT_POSITION_H_

+ 2 - 2
hysteria/Makefile

@@ -5,12 +5,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=hysteria
-PKG_VERSION:=2.2.3
+PKG_VERSION:=2.2.4
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://codeload.github.com/apernet/hysteria/tar.gz/app/v$(PKG_VERSION)?
-PKG_HASH:=123bc416b21bc7288a24504915d81b87651f4b1e1b93805a69864e9adccf1066
+PKG_HASH:=efd15d2ad1fc13a42d0e4a75f5c7396b1219e9923a10ccef2c6f45251266c9a5
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-app-v$(PKG_VERSION)
 
 PKG_LICENSE:=MIT

+ 5 - 0
luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/advanced.lua

@@ -1,5 +1,8 @@
 local uci = luci.model.uci.cursor()
 local server_table = {}
+local function is_finded(e)
+	return luci.sys.exec('type -t -p "%s"' % e) ~= "" and true or false
+end
 
 uci:foreach("shadowsocksr", "servers", function(s)
 	if s.alias then
@@ -69,7 +72,9 @@ o:depends("netflix_enable", "1")
 
 o = s:option(ListValue, "shunt_dns_mode", translate("DNS Query Mode For Shunt Mode"))
 o:value("1", translate("Use DNS2SOCKS query and cache"))
+if is_finded("mosdns") then
 o:value("2", translate("Use MOSDNS query"))
+end
 o:depends("netflix_enable", "1")
 o.default = 1
 

+ 165 - 11
luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua

@@ -117,7 +117,8 @@ local securitys = {
 local tls_flows = {
 	-- tls
 	"xtls-rprx-vision",
-	"xtls-rprx-vision-udp443"
+	"xtls-rprx-vision-udp443",
+	"none"
 }
 
 m = Map("shadowsocksr", translate("Edit ShadowSocksR Server"))
@@ -868,7 +869,7 @@ if is_finded("xray") then
 	o:depends({type = "v2ray", v2ray_protocol = "vless", reality = true})
 
 	-- [[ XTLS ]]--
-	o = s:option(Value, "tls_flow", translate("Flow"))
+	o = s:option(ListValue, "tls_flow", translate("Flow"))
 	for _, v in ipairs(tls_flows) do
 		o:value(v, translate(v))
 	end
@@ -878,7 +879,7 @@ if is_finded("xray") then
 
 	-- [[ uTLS ]]--
 	o = s:option(Value, "fingerprint", translate("Finger Print"))
-	o:value("", translate("disable"))
+	o.default = "chrome"
 	o:value("chrome", translate("chrome"))
 	o:value("firefox", translate("firefox"))
 	o:value("safari", translate("safari"))
@@ -889,6 +890,7 @@ if is_finded("xray") then
 	o:value("qq", translate("qq"))
 	o:value("random", translate("random"))
 	o:value("randomized", translate("randomized"))
+	o:value("", translate("disable"))
 	o:depends({type = "v2ray", tls = true})
 	o:depends({type = "v2ray", reality = true})
 end
@@ -917,9 +919,11 @@ o = s:option(Value, "pinsha256", translate("Certificate fingerprint"))
 o:depends({type = "hysteria", insecure = true })
 o.rmempty = true
 
+
 -- [[ Mux ]]--
 o = s:option(Flag, "mux", translate("Mux"))
 o.rmempty = false
+o.default = false
 o:depends({type = "v2ray", v2ray_protocol = "vless"})
 o:depends({type = "v2ray", v2ray_protocol = "vmess"})
 o:depends({type = "v2ray", v2ray_protocol = "trojan"})
@@ -927,29 +931,33 @@ o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"})
 o:depends({type = "v2ray", v2ray_protocol = "socks"})
 o:depends({type = "v2ray", v2ray_protocol = "http"})
 
-o = s:option(Value, "concurrency", translate("concurrency"))
-o.datatype = "integer"
+o = s:option(ListValue, "concurrency", translate("concurrency"))
 o.rmempty = true
 o.default = "-1"
-o:depends("mux", "1")
+o:value("-1", translate("disable"))
+o:value("8", translate("8"))
+o:depends("mux", true)
 
-o = s:option(Value, "xudpConcurrency", translate("xudpConcurrency"))
-o.datatype = "integer"
+o = s:option(ListValue, "xudpConcurrency", translate("xudpConcurrency"))
 o.rmempty = true
 o.default = "16"
-o:depends("mux", "1")
+o:value("16", translate("16"))
+o:value("-1", translate("disable"))
+o:depends("mux", true)
 
-o = s:option(Value, "xudpProxyUDP443", translate("xudpProxyUDP443"))
+o = s:option(ListValue, "xudpProxyUDP443", translate("xudpProxyUDP443"))
 o.rmempty = true
 o.default = "reject"
 o:value("reject", translate("reject"))
 o:value("allow", translate("allow"))
 o:value("skip", translate("skip"))
-o:depends("mux", "1")
+o:depends("mux", true)
+
 
 -- [[ MPTCP ]]--
 o = s:option(Flag, "mptcp", translate("MPTCP"))
 o.rmempty = false
+o.default = false
 o:depends({type = "v2ray", v2ray_protocol = "vless"})
 o:depends({type = "v2ray", v2ray_protocol = "vmess"})
 o:depends({type = "v2ray", v2ray_protocol = "trojan"})
@@ -957,6 +965,152 @@ o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"})
 o:depends({type = "v2ray", v2ray_protocol = "socks"})
 o:depends({type = "v2ray", v2ray_protocol = "http"})
 
+-- [[ custom_tcpcongestion 连接服务器节点的 TCP 拥塞控制算法 ]]--
+o = s:option(ListValue, "custom_tcpcongestion", translate("custom_tcpcongestion"))
+o.rmempty = true
+o.default = ""
+o:value("", translate("comment_tcpcongestion_disable"))
+o:value("bbr", translate("BBR"))
+o:value("cubic", translate("CUBIC"))
+o:value("reno", translate("Reno"))
+o:depends({type = "v2ray", v2ray_protocol = "vless"})
+o:depends({type = "v2ray", v2ray_protocol = "vmess"})
+o:depends({type = "v2ray", v2ray_protocol = "trojan"})
+o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"})
+o:depends({type = "v2ray", v2ray_protocol = "socks"})
+o:depends({type = "v2ray", v2ray_protocol = "http"})
+
+
+-- [[ custom_sniffing 流量嗅探 ]]--
+o = s:option(Flag, "custom_sniffing", translate("custom_sniffing"))
+o.rmempty = false
+o.default = true
+o:depends({type = "v2ray", v2ray_protocol = "vless"})
+o:depends({type = "v2ray", v2ray_protocol = "vmess"})
+o:depends({type = "v2ray", v2ray_protocol = "trojan"})
+o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"})
+o:depends({type = "v2ray", v2ray_protocol = "socks"})
+o:depends({type = "v2ray", v2ray_protocol = "http"})
+
+-- [[ custom_domainsExcluded 流量嗅探域名排除列表 ]]--
+o = s:option(Flag, "custom_domainsExcluded", translate("custom_domainsExcluded"))
+o.rmempty = false
+o.default = true
+o:depends("custom_sniffing", true)
+
+-- [[ custom_routeOnly 嗅探得到的域名仅用于 Xray 路由 ]]--
+o = s:option(Flag, "custom_routeOnly", translate("custom_routeOnly"))
+o.rmempty = false
+o.default = false
+o:depends("custom_sniffing", true)
+
+
+-- [[ custom_dns_enable Xray DNS 功能 ]]--
+o = s:option(Flag, "custom_dns_enable", translate("custom_dns_enable"))
+o.rmempty = false
+o.default = false
+o:depends({type = "v2ray", v2ray_protocol = "vless"})
+o:depends({type = "v2ray", v2ray_protocol = "vmess"})
+o:depends({type = "v2ray", v2ray_protocol = "trojan"})
+o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"})
+o:depends({type = "v2ray", v2ray_protocol = "socks"})
+o:depends({type = "v2ray", v2ray_protocol = "http"})
+o.description = translate("comment_dns_inbound_enable")
+
+-- [[ custom_dns_local 本地 DNS ]]--
+o = s:option(ListValue, "custom_dns_local", translate("custom_dns_local"))
+o.rmempty = true
+o.default = "https+local://223.5.5.5/dns-query"
+o:value("https+local://223.5.5.5/dns-query", translate("https+local://223.5.5.5/dns-query"))
+o:value("https+local://119.29.29.29/dns-query", translate("https+local://119.29.29.29/dns-query"))
+o:depends("custom_dns_enable", true)
+
+-- [[ custom_dns_remote 远端 DNS ]]--
+o = s:option(ListValue, "custom_dns_remote", translate("custom_dns_remote"))
+o.rmempty = true
+o.default = "https://1.1.1.1/dns-query"
+o:value("https://1.1.1.1/dns-query", translate("https://1.1.1.1/dns-query"))
+o:value("https://8.8.8.8/dns-query", translate("https://8.8.8.8/dns-query"))
+o:depends("custom_dns_enable", true)
+
+-- [[ custom_dns_remote_domains 远端 DNS 域名列表 ]]--
+o = s:option(ListValue, "custom_dns_remote_domains", translate("custom_dns_remote_domains"))
+o.rmempty = true
+o.default = "geosite:geolocation-!cn"
+o:value("geosite:geolocation-!cn", translate("geosite:geolocation-!cn"))
+o:depends("custom_dns_enable", true)
+
+-- [[ custom_nonIPQuery 非 A 和 AAAA 记录处理方式 ]]--
+o = s:option(ListValue, "custom_nonIPQuery", translate("custom_nonIPQuery"))
+o.rmempty = true
+o.default = "skip"
+o:value("skip", translate("skip"))
+o:value("drop", translate("drop"))
+o:depends("custom_dns_enable", true)
+
+-- [[ custom_nonIPQuery_outbound_tag 非 A 和 AAAA 记录查询方式 ]]--
+o = s:option(ListValue, "custom_nonIPQuery_outbound_tag", translate("custom_nonIPQuery_outbound_tag"))
+o.rmempty = true
+o.default = "direct"
+o:value("direct", translate("direct"))
+o:value("proxy", translate("proxy"))
+o:depends({custom_nonIPQuery = "skip"})
+
+-- [[ custom_dokodemo_door_dns_address 查询非 A 和 AAAA 记录 DNS ]]--
+o = s:option(ListValue, "custom_dokodemo_door_dns_address", translate("custom_dokodemo_door_dns_address"))
+o.rmempty = true
+o.default = "223.5.5.5"
+o:value("223.5.5.5", translate("223.5.5.5"))
+o:value("119.29.29.29", translate("119.29.29.29"))
+o:value("1.1.1.1", translate("1.1.1.1"))
+o:value("8.8.8.8", translate("8.8.8.8"))
+o:depends({custom_nonIPQuery = "skip"})
+
+
+-- [[ custom_log Xray 日志功能 ]]--
+o = s:option(Flag, "custom_log", translate("custom_log"))
+o.rmempty = false
+o.default = false
+o:depends({type = "v2ray", v2ray_protocol = "vless"})
+o:depends({type = "v2ray", v2ray_protocol = "vmess"})
+o:depends({type = "v2ray", v2ray_protocol = "trojan"})
+o:depends({type = "v2ray", v2ray_protocol = "shadowsocks"})
+o:depends({type = "v2ray", v2ray_protocol = "socks"})
+o:depends({type = "v2ray", v2ray_protocol = "http"})
+
+-- [[ custom_loglevel 日志级别 ]]--
+o = s:option(ListValue, "custom_loglevel", translate("custom_loglevel"))
+o.rmempty = true
+o.default = "warning"
+o:value("error", translate("error"))
+o:value("warning", translate("warning"))
+o:value("info", translate("info"))
+o:value("debug", translate("debug"))
+o:depends("custom_log", true)
+
+-- [[ custom_dnsLog DNS 查询记录 ]]--
+o = s:option(Flag, "custom_dnsLog", translate("custom_dnsLog"))
+o.rmempty = true
+o.default = true
+o:depends("custom_log", true)
+
+-- [[ custom_access 访问记录 ]]--
+o = s:option(ListValue, "custom_access", translate("custom_access"))
+o.rmempty = true
+o.default = "/tmp/access.log"
+o:value("/tmp/access.log", translate("/tmp/access.log"))
+o:value("none", translate("none"))
+o:depends("custom_log", true)
+
+-- [[ custom_error 错误记录 ]]--
+o = s:option(ListValue, "custom_error", translate("custom_error"))
+o.rmempty = true
+o.default = "/tmp/error.log"
+o:value("/tmp/error.log", translate("/tmp/error.log"))
+o:value("none", translate("none"))
+o:depends("custom_log", true)
+
+
 -- [[ Cert ]]--
 o = s:option(Flag, "certificate", translate("Self-signed Certificate"))
 o.rmempty = true

+ 60 - 0
luci-app-ssr-plus/po/zh-cn/ssr-plus.po

@@ -88,6 +88,7 @@ msgstr "TLS 主机名"
 msgid "allowInsecure"
 msgstr "允许不安全连接"
 
+
 msgid "concurrency"
 msgstr "TCP 最大并发连接数"
 
@@ -97,6 +98,65 @@ msgstr "UDP 最大并发连接数"
 msgid "xudpProxyUDP443"
 msgstr "对被代理的 UDP/443 流量处理方式"
 
+
+msgid "custom_tcpcongestion"
+msgstr "连接服务器节点的 TCP 拥塞控制算法"
+
+msgid "comment_tcpcongestion_disable"
+msgstr "使用系统默认值"
+
+
+msgid "custom_sniffing"
+msgstr "流量嗅探"
+
+msgid "custom_domainsExcluded"
+msgstr "流量嗅探域名排除列表"
+
+msgid "custom_routeOnly"
+msgstr "嗅探得到的域名仅用于 Xray 路由"
+
+
+msgid "custom_dns_enable"
+msgstr "Xray DNS 功能"
+
+msgid "comment_dns_inbound_enable"
+msgstr "监听 5335 端口,需要上传 geosite.dat 到 /usr/share/xray,更新固件后要重新上传"
+
+msgid "custom_dns_local"
+msgstr "本地 DNS"
+
+msgid "custom_dns_remote"
+msgstr "远端 DNS"
+
+msgid "custom_dns_remote_domains"
+msgstr "远端 DNS 域名列表"
+
+msgid "custom_dokodemo_door_dns_address"
+msgstr "查询非 A 和 AAAA 记录 DNS"
+
+msgid "custom_nonIPQuery"
+msgstr "非 A 和 AAAA 记录处理方式"
+
+msgid "custom_nonIPQuery_outbound_tag"
+msgstr "非 A 和 AAAA 记录查询方式"
+
+
+msgid "custom_log"
+msgstr "Xray 日志功能"
+
+msgid "custom_loglevel"
+msgstr "日志级别"
+
+msgid "custom_dnsLog"
+msgstr "DNS 查询记录"
+
+msgid "custom_access"
+msgstr "访问记录"
+
+msgid "custom_error"
+msgstr "错误记录"
+
+
 msgid "If true, allowss insecure connection at TLS client, e.g., TLS server uses unverifiable certificates."
 msgstr "是否允许不安全连接。当选择时,将不会检查远端主机所提供的 TLS 证书的有效性。"
 

+ 31 - 31
luci-app-ssr-plus/root/etc/init.d/shadowsocksr

@@ -380,13 +380,13 @@ gen_config_file() { #server1 type2 code3 local_port4 socks_port5 chain6 threads5
 		;;
 	shadowtls)
 		case "$3" in
-			1|2|4)
-        [ -z "$6" ] && lua /usr/share/shadowsocksr/gen_config.lua $1 $type $4 >$chain_config_file || lua /usr/share/shadowsocksr/gen_config.lua $1 $mode $4 $5 $6 >$config_file
-        ;;
-			3)
-				lua /usr/share/shadowsocksr/gen_config.lua $1 $type $4 >$chain_config_file
-				lua /usr/share/shadowsocksr/gen_config.lua $1 $mode $4 $5 $6 >$config_file
-				;;
+		1|2|4)
+			[ -z "$6" ] && lua /usr/share/shadowsocksr/gen_config.lua $1 $type $4 >$chain_config_file || lua /usr/share/shadowsocksr/gen_config.lua $1 $mode $4 $5 $6 >$config_file
+			;;
+		3)
+			lua /usr/share/shadowsocksr/gen_config.lua $1 $type $4 >$chain_config_file
+			lua /usr/share/shadowsocksr/gen_config.lua $1 $mode $4 $5 $6 >$config_file
+			;;
 		esac
 		;;
 	socks5)
@@ -452,14 +452,14 @@ start_udp() {
 		ln_start_bin $(first_type shadow-tls) shadow-tls config --config $chain_config_file
 		local chain_type=$(uci_get_by_name $UDP_RELAY_SERVER chain_type)
 		case ${chain_type} in
-			vmess)
-				ln_start_bin $(first_type xray v2ray) v2ray run -c $udp_config_file
-				echolog "UDP TPROXY Relay:shadow-tls chain-to $($(first_type xray) --version) Started!"
-				;;
-			sslocal)
-				ln_start_bin $(first_type sslocal) sslocal -c $udp_config_file
-				echolog "UDP TPROXY Relay:shadow-tls chain-to $($(first_type sslocal) --version) Started!"
-				;;
+		vmess)
+			ln_start_bin $(first_type xray v2ray) v2ray run -c $udp_config_file
+			echolog "UDP TPROXY Relay:shadow-tls chain-to $($(first_type xray) --version) Started!"
+			;;
+		sslocal)
+			ln_start_bin $(first_type sslocal) sslocal -c $udp_config_file
+			echolog "UDP TPROXY Relay:shadow-tls chain-to $($(first_type sslocal) --version) Started!"
+			;;
 		esac
 		;;
 	socks5)
@@ -588,14 +588,14 @@ start_shunt() {
 		shunt_dns_command
 		local chain_type=$(uci_get_by_name $SHUNT_SERVER chain_type)
 		case ${chain_type} in
-			vmess)
-				ln_start_bin $(first_type xray v2ray) v2ray run -c $shunt_config_file
-				echolog "Netflix Separated Shunt Server:shadow-tls chain-to$($(first_type xray) --version) Started!"
-				;;
-			 sslocal)
-				ln_start_bin $(first_type sslocal) sslocal -c $shunt_config_file
-				echolog "Netflix Separated Shunt Server:shadow-tls chain-to$($(first_type sslocal) --version) Started!"
-				;;
+		vmess)
+			ln_start_bin $(first_type xray v2ray) v2ray run -c $shunt_config_file
+			echolog "Netflix Separated Shunt Server:shadow-tls chain-to$($(first_type xray) --version) Started!"
+			;;
+		sslocal)
+			ln_start_bin $(first_type sslocal) sslocal -c $shunt_config_file
+			echolog "Netflix Separated Shunt Server:shadow-tls chain-to$($(first_type sslocal) --version) Started!"
+			;;
 		esac
 		;;
 	# socks5)
@@ -681,14 +681,14 @@ start_local() {
 			ln_start_bin $(first_type shadow-tls) shadow-tls config --config $chain_local_config_file
 			local chain_type=$(uci_get_by_name $LOCAL_SERVER chain_type)
 			case ${chain_type} in
-				vmess)
-					ln_start_bin $(first_type xray v2ray) v2ray run -c $local_config_file
-					echolog "Global Socks5 Proxy:shadow-tls chain-to$($(first_type xray) --version) Started!"
-					;;
-				sslocal)
-					ln_start_bin $(first_type sslocal) sslocal -c $local_config_file
-					echolog "Global Socks5 Proxy:shadow-tls chain-to$($(first_type sslocal) --version) Started!"
-					;;
+			vmess)
+				ln_start_bin $(first_type xray v2ray) v2ray run -c $local_config_file
+				echolog "Global Socks5 Proxy:shadow-tls chain-to$($(first_type xray) --version) Started!"
+				;;
+			sslocal)
+				ln_start_bin $(first_type sslocal) sslocal -c $local_config_file
+				echolog "Global Socks5 Proxy:shadow-tls chain-to$($(first_type sslocal) --version) Started!"
+				;;
 			esac
 		fi
 		;;

+ 126 - 20
luci-app-ssr-plus/root/usr/share/shadowsocksr/gen_config.lua

@@ -116,18 +116,96 @@ end
 local settings = outbound:new()
 settings:handleIndex(server.v2ray_protocol)
 local Xray = {
-	log = {
-		-- error = "/var/ssrplus.log",
-		loglevel = "warning"
+	-- 日志
+	log = (server.custom_log == "1") and {
+		loglevel = server.custom_loglevel, -- 日志级别
+		dnsLog = (server.custom_dnsLog == "1") and true or false, -- DNS 查询记录
+		access = server.custom_access, -- 访问记录
+		error = server.custom_error -- 错误记录
+	} or nil,
+	-- DNS
+	dns = {
+		hosts = {
+			["dns.alidns.com"] = "223.5.5.5",
+			["doh.pub"] = "119.29.29.29"
+		},
+		servers = (server.custom_dns_enable == "1") and { -- Xray 内置 DNS
+			server.custom_dns_local, -- 本地 DNS
+			{
+				address = server.custom_dns_remote, -- 远端 DNS
+				domains = {
+					server.custom_dns_remote_domains -- 远端 DNS 域名列表
+				},
+				skipFallback = true,
+				queryStrategy = "UseIP"
+			}
+		} or nil,
+		queryStrategy = "UseIP"
+	},
+	-- 路由
+	routing = {
+		domainStrategy = "AsIs",
+		rules = {
+			{
+				type = "field",
+				inboundTag = {
+					"dns-in"
+				},
+				outboundTag = "dns-out"
+			}
+		}
 	},
 	-- 传入连接
-	inbound = (local_port ~= "0") and {
+	inbounds = {
+	(local_port ~= "0") and {
 		-- listening
 		port = tonumber(local_port),
 		protocol = "dokodemo-door",
 		settings = {network = proto, followRedirect = true},
-		sniffing = {enabled = true, destOverride = {"http", "tls", "quic"}}
+		sniffing = {
+			enabled = (server.custom_sniffing == "1") and true or false, -- 流量嗅探
+			routeOnly = (server.custom_routeOnly == "1") and true or false, -- 嗅探得到的域名仅用于 Xray 内部路由
+			destOverride = {"http", "tls", "quic"},
+			domainsExcluded = (server.custom_domainsExcluded == "1") and { -- 流量嗅探域名排除列表
+				"courier.push.apple.com",
+				"rbsxbxp-mim.vivox.com",
+				"rbsxbxp.www.vivox.com",
+				"rbsxbxp-ws.vivox.com",
+				"rbspsxp.www.vivox.com",
+				"rbspsxp-mim.vivox.com",
+				"rbspsxp-ws.vivox.com",
+				"rbswxp.www.vivox.com",
+				"rbswxp-mim.vivox.com",
+				"disp-rbspsp-5-1.vivox.com",
+				"disp-rbsxbp-5-1.vivox.com",
+				"proxy.rbsxbp.vivox.com",
+				"proxy.rbspsp.vivox.com",
+				"proxy.rbswp.vivox.com",
+				"rbswp.vivox.com",
+				"rbsxbp.vivox.com",
+				"rbspsp.vivox.com",
+				"rbspsp.www.vivox.com",
+				"rbswp.www.vivox.com",
+				"rbsxbp.www.vivox.com",
+				"rbsxbxp.vivox.com",
+				"rbspsxp.vivox.com",
+				"rbswxp.vivox.com",
+				"Mijia Cloud",
+				"dlg.io.mi.com"
+			} or nil,
+		}
+	} or nil,
+	(server.custom_dns_enable == "1") and { -- Xray 内置 DNS
+		port = 5335,
+		protocol = "dokodemo-door",
+		settings = {
+			address = server.custom_dokodemo_door_dns_address, -- 查询非 A 和 AAAA 记录DNS
+			port = 53,
+			network = "udp"
+		},
+		tag = "dns-in"
 	} or nil,
+	},
 	-- 开启 socks 代理
 	inboundDetour = (proto:find("tcp") and socks_port ~= "0") and {
 		{
@@ -138,7 +216,9 @@ local Xray = {
 		}
 	} or nil,
 	-- 传出连接
-	outbound = {
+	outbounds = {
+	{
+		tag = "proxy",
 		protocol = server.v2ray_protocol,
 		settings = outbound_settings,
 		-- 底层传输配置
@@ -154,7 +234,7 @@ local Xray = {
 				certificates = server.certificate and {
 					usage = "verify",
 					certificateFile = server.certpath
-				} or nil
+				} or nil,
 			} or nil,
 			realitySettings = (server.reality == '1') and {
 				publicKey = server.reality_publickey,
@@ -218,20 +298,46 @@ local Xray = {
 				permit_without_stream = (server.permit_without_stream == "1") and true or nil,
 				initial_windows_size = tonumber(server.initial_windows_size) or nil
 			} or nil,
-			sockopt = (server.mptcp == "1") and {
-				tcpcongestion = "bbr",
-				tcpMptcp = true,
-				tcpNoDelay = true
-			} or nil
+			sockopt = {
+				tcpMptcp = (server.mptcp == "1") and true or false, -- MPTCP
+				tcpNoDelay = (server.mptcp == "1") and true or false, -- MPTCP
+				tcpcongestion = server.custom_tcpcongestion -- 连接服务器节点的 TCP 拥塞控制算法
+			}
 		},
-		mux = (server.mux == "1") and {
-			-- mux
-			enabled = true,
-			concurrency = tonumber(server.concurrency),
-			xudpConcurrency = tonumber(server.xudpConcurrency),
-			xudpProxyUDP443 = server.xudpProxyUDP443
-		} or nil
-	} or nil
+		mux = {
+			enabled = (server.mux == "1") and true or false, -- Mux
+			concurrency = tonumber(server.concurrency), -- TCP 最大并发连接数
+			xudpConcurrency = tonumber(server.xudpConcurrency), -- UDP 最大并发连接数
+			xudpProxyUDP443 = server.xudpProxyUDP443 -- 对被代理的 UDP/443 流量处理方式
+		}
+	},
+	{
+		protocol = "freedom",
+		settings = {
+			domainStrategy = "ForceIPv6v4"
+		},
+		streamSettings = {
+			sockopt = {
+				tcpFastOpen = true
+			}
+		},
+		tag = "direct"
+	},
+	{
+		protocol = "blackhole",
+		tag = "block"
+	},
+	(server.custom_dns_enable == "1") and { -- Xray 内置 DNS
+		protocol = "dns",
+		settings = {
+			nonIPQuery = server.custom_nonIPQuery -- 非 A 和 AAAA 记录处理方式
+		},
+		proxySettings = (server.custom_nonIPQuery == "skip") and {
+			tag = server.custom_nonIPQuery_outbound_tag -- 非 A 和 AAAA 记录查询方式
+		} or nil,
+		tag = "dns-out"
+	} or nil,
+	}
 }
 local cipher = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:AES128-SHA:AES256-SHA:DES-CBC3-SHA"
 local cipher13 = "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384"

+ 7 - 11
naiveproxy/Makefile

@@ -5,23 +5,19 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=naiveproxy
-PKG_VERSION:=113.0.5672.62-2
+PKG_VERSION:=121.0.6167.71-1
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://codeload.github.com/klzgrad/naiveproxy/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=75db685789d550094343a76fdcbb6ea2bfcb708c3330af621ca532842251fb26
+PKG_HASH:=8e6d3029a0249140595fab3d668103881689f6c7ef7c65230191f674a370b309
 
 PKG_LICENSE:=BSD 3-Clause
 PKG_LICENSE_FILES:=LICENSE
 PKG_MAINTAINER:=Tianling Shen <[email protected]>
 
 PKG_BUILD_DEPENDS:=gn/host
-ifneq ($(wildcard $(TOPDIR)/feeds/packages/devel/ninja/ninja.mk),)
-PKG_BUILD_DEPENDS+= ninja/host
-endif
 PKG_BUILD_PARALLEL:=1
-PKG_USE_MIPS16:=0
 PKG_BUILD_FLAGS:=no-mips16
 
 ifneq ($(CONFIG_CPU_TYPE)," ")
@@ -59,22 +55,22 @@ ifneq ($(CONFIG_CCACHE),)
   export naive_ccache_flags=cc_wrapper="$(CCACHE)"
 endif
 
-CLANG_VER:=17-init-4759-g547e3456-1
+CLANG_VER:=18-init-12938-geb1d5065-1
 CLANG_FILE:=clang-llvmorg-$(CLANG_VER).tgz
 define Download/CLANG
 	URL:=https://commondatastorage.googleapis.com/chromium-browser-clang/Linux_x64
 	URL_FILE:=$(CLANG_FILE)
 	FILE:=$(CLANG_FILE)
-	HASH:=1949427e0030523dc86bdf4b63dac88228cfe05c57318be2d0b0b290297925f6
+	HASH:=fd1628fdb22157a7328c25802a745f17f92f5210a8b62591202deb92413f52e5
 endef
 
-PGO_VER:=5672-1682419203-4df9c2f8b97b0e23303fa2b15279906232abc306
+PGO_VER:=6167-1705427108-cb39f8a22759d3159f79efc273ac8b13a0f3882a
 PGO_FILE:=chrome-linux-$(PGO_VER).profdata
 define Download/PGO_PROF
 	URL:=https://storage.googleapis.com/chromium-optimization-profiles/pgo_profiles
 	URL_FILE:=$(PGO_FILE)
 	FILE:=$(PGO_FILE)
-	HASH:=5fae812f617d882222cd5aa5620fb355583391127f608759b030c231b71d4c90
+	HASH:=7632c875db539cb1d4a0df6eb3acc9e155d2d477376dec1f815081bbae7cdd4f
 endef
 
 define Build/Prepare
@@ -103,7 +99,7 @@ define Build/Configure
 endef
 
 define Build/Compile
-	ninja -C "$(PKG_BUILD_DIR)/src/out/Release" naive
+	+$(NINJA) -C "$(PKG_BUILD_DIR)/src/out/Release" naive
 endef
 
 define Package/naiveproxy/install

+ 0 - 38
naiveproxy/patches/100-macros.patch

@@ -1,38 +0,0 @@
---- a/src/base/allocator/partition_allocator/tagging.cc
-+++ b/src/base/allocator/partition_allocator/tagging.cc
-@@ -18,22 +18,25 @@
- #define PR_GET_TAGGED_ADDR_CTRL 56
- #define PR_TAGGED_ADDR_ENABLE (1UL << 0)
- 
--#if BUILDFLAG(IS_LINUX)
--#include <linux/version.h>
--
--// Linux headers already provide these since v5.10.
--#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)
--#define HAS_PR_MTE_MACROS
--#endif
--#endif
--
--#ifndef HAS_PR_MTE_MACROS
-+#ifndef PR_MTE_TCF_SHIFT
- #define PR_MTE_TCF_SHIFT 1
-+#endif
-+#ifndef PR_MTE_TCF_NONE
- #define PR_MTE_TCF_NONE (0UL << PR_MTE_TCF_SHIFT)
-+#endif
-+#ifndef PR_MTE_TCF_SYNC
- #define PR_MTE_TCF_SYNC (1UL << PR_MTE_TCF_SHIFT)
-+#endif
-+#ifndef PR_MTE_TCF_ASYNC
- #define PR_MTE_TCF_ASYNC (2UL << PR_MTE_TCF_SHIFT)
-+#endif
-+#ifndef PR_MTE_TCF_MASK
- #define PR_MTE_TCF_MASK (3UL << PR_MTE_TCF_SHIFT)
-+#endif
-+#ifndef PR_MTE_TAG_SHIFT
- #define PR_MTE_TAG_SHIFT 3
-+#endif
-+#ifndef PR_MTE_TAG_MASK
- #define PR_MTE_TAG_MASK (0xffffUL << PR_MTE_TAG_SHIFT)
- #endif
- #endif

+ 10 - 2
naiveproxy/src/init_env.sh

@@ -40,7 +40,7 @@ export naive_flags="
 is_official_build=true
 exclude_unwind_tables=true
 enable_resource_allowlist_generation=false
-symbol_level=1
+symbol_level=0
 is_clang=true
 use_sysroot=false
 
@@ -64,6 +64,9 @@ enable_reporting=false
 include_transport_security_state_preload_list=false
 use_nss_certs=false
 
+enable_backup_ref_ptr_support=false
+enable_dangling_raw_ptr_checks=false
+
 target_os=\"openwrt\"
 target_cpu=\"${naive_arch}\"
 target_sysroot=\"${toolchain_dir}\""
@@ -87,7 +90,12 @@ case "${target_arch}" in
 	[ -n "${cpu_type}" ] && naive_flags+=" arm_cpu=\"${cpu_type}\""
 	;;
 "mipsel"|"mips64el")
-	naive_flags+=" use_thin_lto=false chrome_pgo_phase=0 mips_arch_variant=\"r2\""
+	naive_flags+=" use_thin_lto=false chrome_pgo_phase=0"
+	if [ -z "${cpu_type}" ]; then
+		naive_flags+=" mips_arch_variant=\"r1\""
+	else
+		naive_flags+=" mips_arch_variant=\"r2\""
+	fi
 	if [ "${target_arch}" == "mipsel" ]; then
 		if [ "${cpu_subtype}" == "24kf" ]; then
 			naive_flags+=" mips_float_abi=\"hard\""

+ 12 - 43
shadowsocks-rust/Makefile

@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 #
 # Copyright (C) 2017-2020 Yousong Zhou <[email protected]>
-# Copyright (C) 2021 ImmortalWrt.org
+# Copyright (C) 2021-2023 ImmortalWrt.org
 
 include $(TOPDIR)/rules.mk
 
@@ -9,49 +9,21 @@ PKG_NAME:=shadowsocks-rust
 PKG_VERSION:=1.17.1
 PKG_RELEASE:=1
 
-PKG_SOURCE_HEADER:=shadowsocks-v$(PKG_VERSION)
-PKG_SOURCE_BODY:=unknown-linux-musl
-PKG_SOURCE_FOOTER:=tar.xz
-PKG_SOURCE_URL:=https://github.com/shadowsocks/shadowsocks-rust/releases/download/v$(PKG_VERSION)/
-
-ifeq ($(ARCH),aarch64)
-  PKG_SOURCE:=$(PKG_SOURCE_HEADER).aarch64-$(PKG_SOURCE_BODY).$(PKG_SOURCE_FOOTER)
-  PKG_HASH:=ac172822b579ac0fe59e4cc519e9f4ffee32ed069b10ffdc7421fb1bfdb8c03e
-else ifeq ($(ARCH),arm)
-  # Referred to golang/golang-values.mk
-  ARM_CPU_FEATURES:=$(word 2,$(subst +,$(space),$(call qstrip,$(CONFIG_CPU_TYPE))))
-  ifeq ($(ARM_CPU_FEATURES),)
-    PKG_SOURCE:=$(PKG_SOURCE_HEADER).arm-$(PKG_SOURCE_BODY)eabi.$(PKG_SOURCE_FOOTER)
-    PKG_HASH:=2468a4a3077326661b696e2603850db06667c60c107842ce054e3f70d772952d
-  else
-    PKG_SOURCE:=$(PKG_SOURCE_HEADER).arm-$(PKG_SOURCE_BODY)eabihf.$(PKG_SOURCE_FOOTER)
-    PKG_HASH:=155e62782afcdf46ea88319253853c573e9542a7a8e91769e4a6dedbef1f1c35
-  endif
-else ifeq ($(ARCH),i386)
-  PKG_SOURCE:=$(PKG_SOURCE_HEADER).i686-$(PKG_SOURCE_BODY).$(PKG_SOURCE_FOOTER)
-  PKG_HASH:=d71024f5f79ebe209173124ed6c733c546214f091f2552eb13217ea65aa54940
-else ifeq ($(ARCH),mips)
-  PKG_SOURCE:=$(PKG_SOURCE_HEADER).mips-$(PKG_SOURCE_BODY).$(PKG_SOURCE_FOOTER)
-  PKG_HASH:=1a8ab79ef3904290c564933b3cff60f0b80211c769b25103adb910e1adb0a4d8
-else ifeq ($(ARCH),mipsel)
-  PKG_SOURCE:=$(PKG_SOURCE_HEADER).mipsel-$(PKG_SOURCE_BODY).$(PKG_SOURCE_FOOTER)
-  PKG_HASH:=e3909ba7e07c89adf7818f8c4c07a980650e9a0fa05f522d41e9fcba636f2cb8
-else ifeq ($(ARCH),x86_64)
-  PKG_SOURCE:=$(PKG_SOURCE_HEADER).x86_64-$(PKG_SOURCE_BODY).$(PKG_SOURCE_FOOTER)
-  PKG_HASH:=8ee466b7919480f33db45c3995d4b0baa0c310470f88f7d65b7bb4a89e256624
-# Set the default value to make OpenWrt Package Checker happy
-else
-  PKG_SOURCE:=dummy
-  PKG_HASH:=dummy
-endif
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://codeload.github.com/shadowsocks/shadowsocks-rust/tar.gz/v$(PKG_VERSION)?
+PKG_HASH:=97a1c8ebf7fd19de94cd6d0dfee398667e1f4e131ec8a37ecb7c3191af7cc75e
 
 PKG_MAINTAINER:=Tianling Shen <[email protected]>
 PKG_LICENSE:=MIT
 PKG_LICENSE_FILES:=LICENSE
 
-include $(INCLUDE_DIR)/package.mk
+PKG_BUILD_DEPENDS:=rust/host
+PKG_BUILD_PARALLEL:=1
+
+RUST_PKG_FEATURES:=local-redir
 
-TAR_CMD:=$(HOST_TAR) -C $(PKG_BUILD_DIR) $(TAR_OPTIONS)
+include $(INCLUDE_DIR)/package.mk
+include $(TOPDIR)/feeds/packages/lang/rust/rust-package.mk
 
 define Package/shadowsocks-rust/Default
   define Package/shadowsocks-rust-$(1)
@@ -60,12 +32,12 @@ define Package/shadowsocks-rust/Default
     SUBMENU:=Web Servers/Proxies
     TITLE:=shadowsocks-rust $(1)
     URL:=https://github.com/shadowsocks/shadowsocks-rust
-    DEPENDS:=@USE_MUSL @(aarch64||arm||i386||mips||mipsel||x86_64) @!(TARGET_x86_geode||TARGET_x86_legacy)
+    DEPENDS:=$$(RUST_ARCH_DEPENDS)
   endef
 
   define Package/shadowsocks-rust-$(1)/install
 	$$(INSTALL_DIR) $$(1)/usr/bin
-	$$(INSTALL_BIN) $$(PKG_BUILD_DIR)/$(1) $$(1)/usr/bin
+	$$(INSTALL_BIN) $$(PKG_INSTALL_DIR)/bin/$(1) $$(1)/usr/bin/
   endef
 endef
 
@@ -77,9 +49,6 @@ define shadowsocks-rust/templates
 endef
 $(eval $(call shadowsocks-rust/templates))
 
-define Build/Compile
-endef
-
 $(foreach component,$(SHADOWSOCKS_COMPONENTS), \
   $(eval $(call BuildPackage,shadowsocks-rust-$(component))) \
 )

+ 10 - 2
shadowsocksr-libev/Makefile

@@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=shadowsocksr-libev
 PKG_VERSION:=2.5.6
-PKG_RELEASE:=9
+PKG_RELEASE:=10
 
 PKG_SOURCE_PROTO:=git
 PKG_SOURCE_URL:=https://github.com/shadowsocksrr/shadowsocksr-libev
@@ -34,7 +34,7 @@ define Package/shadowsocksr-libev/Default
     SUBMENU:=Web Servers/Proxies
     TITLE:=shadowsocksr-libev ssr-$(1)
     URL:=https://github.com/shadowsocksrr/shadowsocksr-libev
-    DEPENDS:=+libev +libsodium +libopenssl +libpthread +libpcre +libudns +zlib
+    DEPENDS:=+libev +libsodium +libopenssl +libpthread +libpcre +libudns +zlib +libopenssl-legacy
   endef
 
   define Package/shadowsocksr-libev-ssr-$(1)/install
@@ -60,6 +60,14 @@ CONFIGURE_ARGS += \
 TARGET_CFLAGS += -flto
 TARGET_LDFLAGS += -Wl,--gc-sections,--as-needed
 
+ifeq ($(CONFIG_GCC_VERSION_12),y)
+	TARGET_CFLAGS += -Wno-error=use-after-free
+endif
+
+ifeq ($(CONFIG_GCC_VERSION_13),y)
+	TARGET_CFLAGS += -Wno-error=use-after-free
+endif
+
 $(foreach component,$(SHADOWSOCKSR_COMPONENTS), \
   $(eval $(call BuildPackage,shadowsocksr-libev-ssr-$(component))) \
 )

+ 0 - 79
v2ray-geodata/Makefile

@@ -1,79 +0,0 @@
-# SPDX-License-Identifier: GPL-3.0-only
-#
-# Copyright (C) 2021-2022 ImmortalWrt.org
-
-include $(TOPDIR)/rules.mk
-
-PKG_NAME:=v2ray-geodata
-PKG_RELEASE:=1
-
-PKG_LICENSE_FILES:=LICENSE
-PKG_MAINTAINER:=Tianling Shen <[email protected]>
-
-include $(INCLUDE_DIR)/package.mk
-
-GEOIP_VER:=202210200105
-GEOIP_FILE:=geoip.dat.$(GEOIP_VER)
-define Download/geoip
-  URL:=https://github.com/v2fly/geoip/releases/download/$(GEOIP_VER)/
-  URL_FILE:=geoip.dat
-  FILE:=$(GEOIP_FILE)
-  HASH:=08b8039a1a3f6fca59864b658bd0b0698588a950dc08ff76e83d3e204fc10679
-endef
-
-GEOSITE_VER:=20221023064040
-GEOSITE_FILE:=dlc.dat.$(GEOSITE_VER)
-define Download/geosite
-  URL:=https://github.com/v2fly/domain-list-community/releases/download/$(GEOSITE_VER)/
-  URL_FILE:=dlc.dat
-  FILE:=$(GEOSITE_FILE)
-  HASH:=d1706f66a29795fa29093f85a6cd620854c53911c0b437ba80d81953280d7bf7
-endef
-
-define Package/v2ray-geodata/template
-  SECTION:=net
-  CATEGORY:=Network
-  SUBMENU:=IP Addresses and Names
-  URL:=https://www.v2fly.org
-  PKGARCH:=all
-endef
-
-define Package/v2ray-geoip
-  $(call Package/v2ray-geodata/template)
-  TITLE:=GeoIP List for V2Ray
-  VERSION:=$(GEOIP_VER)-$(PKG_RELEASE)
-  LICENSE:=CC-BY-SA-4.0
-endef
-
-define Package/v2ray-geosite
-  $(call Package/v2ray-geodata/template)
-  TITLE:=Geosite List for V2Ray
-  VERSION:=$(GEOSITE_VER)-$(PKG_RELEASE)
-  LICENSE:=MIT
-endef
-
-define Build/Prepare
-	$(call Build/Prepare/Default)
-ifneq ($(CONFIG_PACKAGE_v2ray-geoip),)
-	$(call Download,geoip)
-endif
-ifneq ($(CONFIG_PACKAGE_v2ray-geosite),)
-	$(call Download,geosite)
-endif
-endef
-
-define Build/Compile
-endef
-
-define Package/v2ray-geoip/install
-	$(INSTALL_DIR) $(1)/usr/share/v2ray
-	$(INSTALL_DATA) $(DL_DIR)/$(GEOIP_FILE) $(1)/usr/share/v2ray/geoip.dat
-endef
-
-define Package/v2ray-geosite/install
-	$(INSTALL_DIR) $(1)/usr/share/v2ray
-	$(INSTALL_DATA) $(DL_DIR)/$(GEOSITE_FILE) $(1)/usr/share/v2ray/geosite.dat
-endef
-
-$(eval $(call BuildPackage,v2ray-geoip))
-$(eval $(call BuildPackage,v2ray-geosite))

+ 9 - 11
v2raya/Makefile

@@ -5,12 +5,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=v2rayA
-PKG_VERSION:=1.5.9.1698.1
+PKG_VERSION:=2.2.4.6
 PKG_RELEASE:=2
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://codeload.github.com/v2rayA/v2rayA/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=247a357230c616bf48309c61d119686e4ad56939c05afef584c45051e9dc6220
+PKG_HASH:=22285b2fdf321d68993b38ad738f4af210920757d7944691a78e151abd99cb3a
 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)/service
 
 PKG_LICENSE:=AGPL-3.0-only
@@ -23,7 +23,9 @@ PKG_USE_MIPS16:=0
 PKG_BUILD_FLAGS:=no-mips16
 
 GO_PKG:=github.com/v2rayA/v2rayA
-GO_PKG_LDFLAGS_X:=$(GO_PKG)/conf.Version=$(PKG_VERSION)
+GO_PKG_LDFLAGS_X:= \
+	$(GO_PKG)/conf.Version=$(PKG_VERSION) \
+	$(GO_PKG)/core/iptables.TproxyNotSkipBr=true
 
 include $(INCLUDE_DIR)/package.mk
 include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk
@@ -38,11 +40,7 @@ define Package/v2raya
   SUBMENU:=Web Servers/Proxies
   DEPENDS:=$(GO_ARCH_DEPENDS) \
     +ca-bundle \
-    +iptables-mod-conntrack-extra \
-    +iptables-mod-extra \
-    +iptables-mod-filter \
-    +iptables-mod-tproxy \
-    +kmod-ipt-nat6 \
+    +kmod-nft-tproxy \
     +xray-core
   URL:=https://v2raya.org
 endef
@@ -59,10 +57,10 @@ endef
 
 WEB_FILE:=$(PKG_NAME)-web-$(PKG_VERSION).tar.gz
 define Download/v2raya-web
-	URL:=https://codeload.github.com/v2rayA/v2raya-web/tar.gz/v$(PKG_VERSION)?
-	URL_FILE:=$(WEB_FILE)
+	URL:=https://github.com/v2rayA/v2rayA/releases/download/v$(PKG_VERSION)/
+	URL_FILE:=web.tar.gz
 	FILE:=$(WEB_FILE)
-	HASH:=149097a42c3e5fa6f5c3cd46d1bf7ec4546e79ad37c1446b759539e700bd75e2
+	HASH:=09109442abac13801b7b82433fccbb769657b1d292ac4820af179c297e845135
 endef
 
 define Build/Prepare

+ 4 - 10
v2raya/files/v2raya.config

@@ -5,19 +5,17 @@ config v2raya 'config'
 	# Listening address
 	option address '0.0.0.0:2017'
 
-	# v2rayA configuration directory
-	option config '/etc/v2raya'
-
 	# Make sure your IPv6 network works fine before you turn it on.
 	# Optional values: auto, on, off.
 	option ipv6_support 'auto'
 
+	# Experimental feature. Make sure you have installed nftables.
+	# Optional values: auto, on, off.
+	option nftables_support 'auto'
+
 	# Optional values: trace, debug, info, warn or error
 	option log_level 'info'
 
-	# The path of log file
-	option log_file '/var/log/v2raya/v2raya.log'
-
 	# Maximum number of days to keep log files
 	option log_max_days '3'
 
@@ -44,7 +42,3 @@ config v2raya 'config'
 	# v2rayA will pass in the --stage (pre-start, post-start, pre-stop, post-stop) argument.
 	option plugin_manager ''
 
-	# Specify the certification path instead of automatically generating a self-signed certificate.
-	# Example: /etc/v2raya/grpc_certificate.crt,/etc/v2raya/grpc_private.key
-	option vless_grpc_inbound_cert_key ''
-

+ 4 - 3
v2raya/files/v2raya.init

@@ -40,18 +40,19 @@ start_service() {
 	procd_set_param command "$PROG"
 	procd_set_param env XDG_DATA_HOME="/usr/share"
 
+	append_env "config" "/etc/v2raya"
+	append_env "log_file" "/var/log/v2raya/v2raya.log"
+
 	append_env_arg "config" "address" "0.0.0.0:2017"
-	append_env_arg "config" "config" "/etc/v2raya"
 	append_env_arg "config" "ipv6_support" "auto"
+	append_env_arg "config" "nftables_support" "auto"
 	append_env_arg "config" "log_level" "info"
-	append_env_arg "config" "log_file" "/var/log/v2raya/v2raya.log"
 	append_env_arg "config" "log_max_days" "3"
 	append_env_arg "config" "v2ray_bin"
 	append_env_arg "config" "v2ray_confdir"
 	append_env_arg "config" "transparent_hook"
 	append_env_arg "config" "core_hook"
 	append_env_arg "config" "plugin_manager"
-	append_env_arg "config" "vless_grpc_inbound_cert_key"
 	append_env_bool "config" "log_disable_color"
 	append_env_bool "config" "log_disable_timestamp"
 

+ 0 - 38
v2raya/patches/013-fix-we-should-skip-interface-ppp-to-avoid-to-break-net.patch

@@ -1,38 +0,0 @@
-From ca6a05273284daa04856a840e64f3936f700b7c3 Mon Sep 17 00:00:00 2001
-From: mzz2017 <[email protected]>
-Date: Fri, 16 Sep 2022 15:13:11 +0800
-Subject: [PATCH] fix: we should skip interface ppp+ to avoid to break net
-
----
- service/core/iptables/tproxy.go | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
---- a/core/iptables/tproxy.go
-+++ b/core/iptables/tproxy.go
-@@ -16,7 +16,7 @@ var Tproxy tproxy
- func (t *tproxy) AddIPWhitelist(cidr string) {
- 	// avoid duplication
- 	t.RemoveIPWhitelist(cidr)
--	pos := 5
-+	pos := 7
- 	if configure.GetSettingNotNil().AntiPollution != configure.AntipollutionClosed {
- 		pos += 3
- 	}
-@@ -68,6 +68,8 @@ iptables -w 2 -t mangle -A TP_RULE -m ma
- iptables -w 2 -t mangle -A TP_RULE -i br-+ -j RETURN
- iptables -w 2 -t mangle -A TP_RULE -i docker+ -j RETURN
- iptables -w 2 -t mangle -A TP_RULE -i veth+ -j RETURN
-+iptables -w 2 -t mangle -A TP_RULE -i ppp+ -j RETURN
-+iptables -w 2 -t mangle -A TP_RULE -i dn42-+ -j RETURN
- `
- 	if configure.GetSettingNotNil().AntiPollution != configure.AntipollutionClosed {
- 		commands += `
-@@ -127,6 +129,8 @@ ip6tables -w 2 -t mangle -A TP_RULE -m m
- ip6tables -w 2 -t mangle -A TP_RULE -i br-+ -j RETURN
- ip6tables -w 2 -t mangle -A TP_RULE -i docker+ -j RETURN
- ip6tables -w 2 -t mangle -A TP_RULE -i veth+ -j RETURN
-+ip6tables -w 2 -t mangle -A TP_RULE -i ppp+ -j RETURN
-+ip6tables -w 2 -t mangle -A TP_RULE -i dn42-+ -j RETURN
- `
- 		if configure.GetSettingNotNil().AntiPollution != configure.AntipollutionClosed {
- 			commands += `

+ 0 - 105
v2raya/patches/014-fix-seed-cannot-be-read-from-vless-sharing-link-and-add-m.patch

@@ -1,105 +0,0 @@
-From 5db722b22b39642280572a62b149d4e1efa21ce3 Mon Sep 17 00:00:00 2001
-From: mzz2017 <[email protected]>
-Date: Mon, 8 Aug 2022 22:30:36 +0800
-Subject: [PATCH] fix: seed cannot be read from vless sharing-link and add
- missing sni field. #616
-
----
- service/core/serverObj/v2ray.go | 24 +++++++++++-------------
- 1 file changed, 11 insertions(+), 13 deletions(-)
-
---- a/core/serverObj/v2ray.go
-+++ b/core/serverObj/v2ray.go
-@@ -12,7 +12,6 @@ import (
- 	"time"
- 
- 	jsoniter "github.com/json-iterator/go"
--	"github.com/tidwall/gjson"
- 	"github.com/v2rayA/v2rayA/common"
- 	"github.com/v2rayA/v2rayA/core/coreObj"
- 	"github.com/v2rayA/v2rayA/core/v2ray/service"
-@@ -39,6 +38,7 @@ type V2Ray struct {
- 	Net           string `json:"net"`
- 	Type          string `json:"type"`
- 	Host          string `json:"host"`
-+	SNI           string `json:"sni"`
- 	Path          string `json:"path"`
- 	TLS           string `json:"tls"`
- 	Flow          string `json:"flow,omitempty"`
-@@ -69,7 +69,8 @@ func ParseVlessURL(vless string) (data *
- 		ID:            u.User.String(),
- 		Net:           u.Query().Get("type"),
- 		Type:          u.Query().Get("headerType"),
--		Host:          u.Query().Get("sni"),
-+		Host:          u.Query().Get("host"),
-+		SNI:           u.Query().Get("sni"),
- 		Path:          u.Query().Get("path"),
- 		TLS:           u.Query().Get("security"),
- 		Flow:          u.Query().Get("flow"),
-@@ -86,16 +87,13 @@ func ParseVlessURL(vless string) (data *
- 	if data.Type == "" {
- 		data.Type = "none"
- 	}
--	if data.Host == "" {
--		data.Host = u.Query().Get("host")
--	}
- 	if data.TLS == "" {
- 		data.TLS = "none"
- 	}
- 	if data.Flow == "" {
- 		data.Flow = "xtls-rprx-direct"
- 	}
--	if data.Type == "mkcp" || data.Type == "kcp" {
-+	if data.Net == "mkcp" || data.Net == "kcp" {
- 		data.Path = u.Query().Get("seed")
- 	}
- 	return data, nil
-@@ -145,6 +143,7 @@ func ParseVmessURL(vmess string) (data *
- 		if aid == "" {
- 			aid = q.Get("aid")
- 		}
-+		sni := q.Get("sni")
- 		info = V2Ray{
- 			ID:            subMatch[1],
- 			Add:           subMatch[2],
-@@ -152,6 +151,7 @@ func ParseVmessURL(vmess string) (data *
- 			Ps:            ps,
- 			Host:          obfsParam,
- 			Path:          path,
-+			SNI:           sni,
- 			Net:           obfs,
- 			Aid:           aid,
- 			TLS:           map[string]string{"1": "tls"}[q.Get("tls")],
-@@ -165,12 +165,6 @@ func ParseVmessURL(vmess string) (data *
- 		if err != nil {
- 			return
- 		}
--		if info.Host == "" {
--			sni := gjson.Get(raw, "sni")
--			if sni.Exists() {
--				info.Host = sni.String()
--			}
--		}
- 	}
- 	// correct the wrong vmess as much as possible
- 	if strings.HasPrefix(info.Host, "/") && info.Path == "" {
-@@ -328,7 +322,9 @@ func (v *V2Ray) Configuration(info Prior
- 				core.StreamSettings.TLSSettings.AllowInsecure = true
- 			}
- 			// SNI
--			if v.Host != "" {
-+			if v.SNI != "" {
-+				core.StreamSettings.TLSSettings.ServerName = v.SNI
-+			} else if v.Host != "" {
- 				core.StreamSettings.TLSSettings.ServerName = v.Host
- 			}
- 			// Alpn
-@@ -345,6 +341,8 @@ func (v *V2Ray) Configuration(info Prior
- 			// SNI
- 			if v.Host != "" {
- 				core.StreamSettings.XTLSSettings.ServerName = v.Host
-+			} else if v.Host != "" {
-+				core.StreamSettings.TLSSettings.ServerName = v.Host
- 			}
- 			if v.AllowInsecure {
- 				core.StreamSettings.XTLSSettings.AllowInsecure = true

+ 0 - 100
v2raya/patches/015-fix-a-problem-that-supervisor-cannot-exit-normally.patch

@@ -1,100 +0,0 @@
-From 3f78422f81f3abc2668fc3938b31d213bfe4dfff Mon Sep 17 00:00:00 2001
-From: mzz2017 <[email protected]>
-Date: Sun, 28 Aug 2022 17:54:36 +0800
-Subject: [PATCH] fix: a problem that supervisor cannot exit normally
-
----
- service/core/specialMode/infra/handle.go     | 11 ++++++----
- service/core/specialMode/infra/supervisor.go | 22 ++++++++------------
- 2 files changed, 16 insertions(+), 17 deletions(-)
-
---- a/core/specialMode/infra/handle.go
-+++ b/core/specialMode/infra/handle.go
-@@ -127,10 +127,13 @@ func (interfaceHandle *handle) handleRec
- 	return results, msg
- }
- 
--func packetFilter(portCache *portCache, pPacket *gopacket.Packet, whitelistDnsServers *v2router.GeoIPMatcher) (m *dnsmessage.Message, pSAddr, pSPort, pDAddr, pDPort *gopacket.Endpoint) {
--	packet := *pPacket
--	trans := packet.TransportLayer()
-+func packetFilter(portCache *portCache, packet gopacket.Packet, whitelistDnsServers *v2router.GeoIPMatcher) (m *dnsmessage.Message, pSAddr, pSPort, pDAddr, pDPort *gopacket.Endpoint) {
-+	//跳过非网络层的包
-+	if packet.NetworkLayer() == nil {
-+		return
-+	}
- 	//跳过非传输层的包
-+	trans := packet.TransportLayer()
- 	if trans == nil {
- 		return
- 	}
-@@ -180,7 +183,7 @@ func packetFilter(portCache *portCache,
- }
- 
- func (interfaceHandle *handle) handlePacket(packet gopacket.Packet, ifname string, whitelistDnsServers *v2router.GeoIPMatcher, whitelistDomains *strmatcher.MatcherGroup) {
--	m, sAddr, sPort, dAddr, dPort := packetFilter(interfaceHandle.portCache, &packet, whitelistDnsServers)
-+	m, sAddr, sPort, dAddr, dPort := packetFilter(interfaceHandle.portCache, packet, whitelistDnsServers)
- 	if m == nil {
- 		return
- 	}
---- a/core/specialMode/infra/supervisor.go
-+++ b/core/specialMode/infra/supervisor.go
-@@ -9,7 +9,6 @@ import (
- 	v2router "github.com/v2rayA/v2ray-lib/router"
- 	"github.com/v2rayA/v2rayA/pkg/util/log"
- 	"sync"
--	"time"
- )
- 
- type DnsSupervisor struct {
-@@ -70,7 +69,7 @@ func (d *DnsSupervisor) DeleteHandles(if
- 	}
- 	close(d.handles[ifname].done)
- 	delete(d.handles, ifname)
--	log.Trace("DnsSupervisor:%v closed", ifname)
-+	log.Trace("DnsSupervisor:%v deleted", ifname)
- 	return
- }
- 
-@@ -81,28 +80,24 @@ func (d *DnsSupervisor) Run(ifname strin
- 	d.inner.Lock()
- 	handle, ok := d.handles[ifname]
- 	if !ok {
-+		d.inner.Unlock()
- 		return fmt.Errorf("Run: %v not exsits", ifname)
- 	}
- 	if handle.running {
-+		d.inner.Unlock()
- 		return fmt.Errorf("Run: %v is running", ifname)
- 	}
- 	handle.running = true
- 	log.Trace("[DnsSupervisor] " + ifname + ": running")
--	pkgsrc := gopacket.NewPacketSource(handle, layers.LayerTypeEthernet)
-+	// we only decode UDP packets
-+	pkgsrc := gopacket.NewPacketSource(handle, layers.LayerTypeDNS)
- 	pkgsrc.NoCopy = true
-+	//pkgsrc.Lazy = true
- 	d.inner.Unlock()
- 	packets := pkgsrc.Packets()
- 	go func() {
--		for {
--			//心跳包,防止内存泄漏
--			packets <- gopacket.NewPacket(nil, layers.LinkTypeEthernet, gopacket.DecodeOptions{})
--			select {
--			case <-handle.done:
--				return
--			default:
--				time.Sleep(2 * time.Second)
--			}
--		}
-+		<-handle.done
-+		packets <- gopacket.NewPacket(nil, layers.LinkTypeEthernet, pkgsrc.DecodeOptions)
- 	}()
- out:
- 	for packet := range packets {
-@@ -113,5 +108,6 @@ out:
- 		}
- 		go handle.handlePacket(packet, ifname, whitelistDnsServers, whitelistDomains)
- 	}
-+	log.Trace("DnsSupervisor:%v closed", ifname)
- 	return
- }

+ 0 - 52
v2raya/patches/016-fix-unexpected-exit-does-not-apply-stop-steps.patch

@@ -1,52 +0,0 @@
-From 153b72ed623876ad73b731c2ec2344e9057d3c35 Mon Sep 17 00:00:00 2001
-From: mzz2017 <[email protected]>
-Date: Wed, 21 Sep 2022 16:50:24 +0800
-Subject: [PATCH] fix: unexpected exit does not apply stop steps
-
----
- service/core/v2ray/process.go        | 4 ++--
- service/core/v2ray/processManager.go | 8 +++-----
- 2 files changed, 5 insertions(+), 7 deletions(-)
-
---- a/core/v2ray/process.go
-+++ b/core/v2ray/process.go
-@@ -35,7 +35,7 @@ type Process struct {
- 	tag2WhichIndex map[string]int
- }
- 
--func NewProcess(tmpl *Template, prestart func() error, poststart func() error) (process *Process, err error) {
-+func NewProcess(tmpl *Template, prestart func() error, poststart func() error, stopfunc func(p *Process)) (process *Process, err error) {
- 	process = &Process{
- 		template: tmpl,
- 	}
-@@ -111,7 +111,7 @@ func NewProcess(tmpl *Template, prestart
- 			// canceled by v2rayA
- 			return
- 		}
--		defer ProcessManager.Stop(false)
-+		defer stopfunc(process)
- 		var t []string
- 		if p != nil {
- 			if p.Success() {
---- a/core/v2ray/processManager.go
-+++ b/core/v2ray/processManager.go
-@@ -245,16 +245,14 @@ func (m *CoreProcessManager) Start(t *Te
- 		return m.beforeStart(t)
- 	}, func() error {
- 		return m.afterStart(t)
-+	}, func(p *Process) {
-+		m.p = p
-+		ProcessManager.Stop(false)
- 	})
- 	if err != nil {
- 		return err
- 	}
- 	m.p = process
--	defer func() {
--		if err != nil {
--			m.stop(true)
--		}
--	}()
- 
- 	configure.SetRunning(true)
- 	return nil

+ 0 - 336
v2raya/patches/017-optimize-reduce-disk-writes.patch

@@ -1,336 +0,0 @@
-From 00366b224b2e28861b80f677e8aa604c5d08dae3 Mon Sep 17 00:00:00 2001
-From: Kelo <[email protected]>
-Date: Sat, 29 Oct 2022 16:27:26 +0800
-Subject: [PATCH] optimize: reduce disk writes
-
----
- service/db/boltdb.go  | 43 +++++++++++++++++++++++++++++++----
- service/db/listOp.go  | 48 +++++++++++++++++++++------------------
- service/db/plainOp.go | 52 ++++++++++++++++++++++++-------------------
- service/db/setOp.go   | 20 +++++++++--------
- 4 files changed, 105 insertions(+), 58 deletions(-)
-
---- a/db/boltdb.go
-+++ b/db/boltdb.go
-@@ -1,13 +1,14 @@
- package db
- 
- import (
--	"go.etcd.io/bbolt"
--	"github.com/v2rayA/v2rayA/conf"
--	"github.com/v2rayA/v2rayA/pkg/util/copyfile"
--	"github.com/v2rayA/v2rayA/pkg/util/log"
- 	"os"
- 	"path/filepath"
- 	"sync"
-+
-+	"github.com/v2rayA/v2rayA/conf"
-+	"github.com/v2rayA/v2rayA/pkg/util/copyfile"
-+	"github.com/v2rayA/v2rayA/pkg/util/log"
-+	"go.etcd.io/bbolt"
- )
- 
- var once sync.Once
-@@ -46,3 +47,37 @@ func DB() *bbolt.DB {
- 	once.Do(initDB)
- 	return db
- }
-+
-+// The function should return a dirty flag.
-+// If the dirty flag is true and there is no error then the transaction is commited.
-+// Otherwise, the transaction is rolled back.
-+func Transaction(db *bbolt.DB, fn func(*bbolt.Tx) (bool, error)) error {
-+	tx, err := db.Begin(true)
-+	if err != nil {
-+		return err
-+	}
-+	defer tx.Rollback()
-+	dirty, err := fn(tx)
-+	if err != nil {
-+		_ = tx.Rollback()
-+		return err
-+	}
-+	if !dirty {
-+		return nil
-+	}
-+	return tx.Commit()
-+}
-+
-+// If the bucket does not exist, the dirty flag is setted
-+func CreateBucketIfNotExists(tx *bbolt.Tx, name []byte, dirty *bool) (*bbolt.Bucket, error) {
-+	bkt := tx.Bucket(name)
-+	if bkt != nil {
-+		return bkt, nil
-+	}
-+	bkt, err := tx.CreateBucket(name)
-+	if err != nil {
-+		return nil, err
-+	}
-+	*dirty = true
-+	return bkt, nil
-+}
---- a/db/listOp.go
-+++ b/db/listOp.go
-@@ -2,13 +2,14 @@ package db
- 
- import (
- 	"fmt"
--	"go.etcd.io/bbolt"
--	jsoniter "github.com/json-iterator/go"
--	"github.com/tidwall/gjson"
--	"github.com/tidwall/sjson"
- 	"reflect"
- 	"sort"
- 	"strconv"
-+
-+	jsoniter "github.com/json-iterator/go"
-+	"github.com/tidwall/gjson"
-+	"github.com/tidwall/sjson"
-+	"go.etcd.io/bbolt"
- )
- 
- func ListSet(bucket string, key string, index int, val interface{}) (err error) {
-@@ -31,20 +32,21 @@ func ListSet(bucket string, key string,
- }
- 
- func ListGet(bucket string, key string, index int) (b []byte, err error) {
--	err = DB().Update(func(tx *bbolt.Tx) error {
--		if bkt, err := tx.CreateBucketIfNotExists([]byte(bucket)); err != nil {
--			return err
-+	err = Transaction(DB(), func(tx *bbolt.Tx) (bool, error) {
-+		dirty := false
-+		if bkt, err := CreateBucketIfNotExists(tx, []byte(bucket), &dirty); err != nil {
-+			return dirty, err
- 		} else {
- 			v := bkt.Get([]byte(key))
- 			if v == nil {
--				return fmt.Errorf("ListGet: can't get element from an empty list")
-+				return dirty, fmt.Errorf("ListGet: can't get element from an empty list")
- 			}
- 			r := gjson.GetBytes(v, strconv.Itoa(index))
- 			if r.Exists() {
- 				b = []byte(r.Raw)
--				return nil
-+				return dirty, nil
- 			} else {
--				return fmt.Errorf("ListGet: no such element")
-+				return dirty, fmt.Errorf("ListGet: no such element")
- 			}
- 		}
- 	})
-@@ -79,24 +81,25 @@ func ListAppend(bucket string, key strin
- }
- 
- func ListGetAll(bucket string, key string) (list [][]byte, err error) {
--	err = DB().Update(func(tx *bbolt.Tx) error {
--		if bkt, err := tx.CreateBucketIfNotExists([]byte(bucket)); err != nil {
--			return err
-+	err = Transaction(DB(), func(tx *bbolt.Tx) (bool, error) {
-+		dirty := false
-+		if bkt, err := CreateBucketIfNotExists(tx, []byte(bucket), &dirty); err != nil {
-+			return dirty, err
- 		} else {
- 			b := bkt.Get([]byte(key))
- 			if b == nil {
--				return nil
-+				return dirty, nil
- 			}
- 			parsed := gjson.ParseBytes(b)
- 			if !parsed.IsArray() {
--				return fmt.Errorf("ListGetAll: is not array")
-+				return dirty, fmt.Errorf("ListGetAll: is not array")
- 			}
- 			results := parsed.Array()
- 			for _, r := range results {
- 				list = append(list, []byte(r.Raw))
- 			}
- 		}
--		return nil
-+		return dirty, nil
- 	})
- 	return list, err
- }
-@@ -143,21 +146,22 @@ func ListRemove(bucket, key string, inde
- }
- 
- func ListLen(bucket string, key string) (length int, err error) {
--	err = DB().Update(func(tx *bbolt.Tx) error {
--		if bkt, err := tx.CreateBucketIfNotExists([]byte(bucket)); err != nil {
--			return err
-+	err = Transaction(DB(), func(tx *bbolt.Tx) (bool, error) {
-+		dirty := false
-+		if bkt, err := CreateBucketIfNotExists(tx, []byte(bucket), &dirty); err != nil {
-+			return dirty, err
- 		} else {
- 			b := bkt.Get([]byte(key))
- 			if b == nil {
--				return nil
-+				return dirty, nil
- 			}
- 			parsed := gjson.ParseBytes(b)
- 			if !parsed.IsArray() {
--				return fmt.Errorf("ListLen: is not array")
-+				return dirty, fmt.Errorf("ListLen: is not array")
- 			}
- 			length = len(parsed.Array())
- 		}
--		return nil
-+		return dirty, nil
- 	})
- 	return length, err
- }
---- a/db/plainOp.go
-+++ b/db/plainOp.go
-@@ -2,50 +2,54 @@ package db
- 
- import (
- 	"fmt"
--	"go.etcd.io/bbolt"
-+
- 	jsoniter "github.com/json-iterator/go"
- 	"github.com/v2rayA/v2rayA/common"
- 	"github.com/v2rayA/v2rayA/pkg/util/log"
-+	"go.etcd.io/bbolt"
- )
- 
- func Get(bucket string, key string, val interface{}) (err error) {
--	return DB().Update(func(tx *bbolt.Tx) error {
--		if bkt, err := tx.CreateBucketIfNotExists([]byte(bucket)); err != nil {
--			return err
-+	return Transaction(DB(), func(tx *bbolt.Tx) (bool, error) {
-+		dirty := false
-+		if bkt, err := CreateBucketIfNotExists(tx, []byte(bucket), &dirty); err != nil {
-+			return dirty, err
- 		} else {
- 			if v := bkt.Get([]byte(key)); v == nil {
--				return fmt.Errorf("Get: key is not found")
-+				return dirty, fmt.Errorf("Get: key is not found")
- 			} else {
--				return jsoniter.Unmarshal(v, val)
-+				return dirty, jsoniter.Unmarshal(v, val)
- 			}
- 		}
- 	})
- }
- 
- func GetRaw(bucket string, key string) (b []byte, err error) {
--	err = DB().Update(func(tx *bbolt.Tx) error {
--		if bkt, err := tx.CreateBucketIfNotExists([]byte(bucket)); err != nil {
--			return err
-+	err = Transaction(DB(), func(tx *bbolt.Tx) (bool, error) {
-+		dirty := false
-+		if bkt, err := CreateBucketIfNotExists(tx, []byte(bucket), &dirty); err != nil {
-+			return dirty, err
- 		} else {
- 			v := bkt.Get([]byte(key))
- 			if v == nil {
--				return fmt.Errorf("GetRaw: key is not found")
-+				return dirty, fmt.Errorf("GetRaw: key is not found")
- 			}
- 			b = common.BytesCopy(v)
--			return nil
-+			return dirty, nil
- 		}
- 	})
- 	return b, err
- }
- 
- func Exists(bucket string, key string) (exists bool) {
--	if err := DB().Update(func(tx *bbolt.Tx) error {
--		if bkt, err := tx.CreateBucketIfNotExists([]byte(bucket)); err != nil {
--			return err
-+	if err := Transaction(DB(), func(tx *bbolt.Tx) (bool, error) {
-+		dirty := false
-+		if bkt, err := CreateBucketIfNotExists(tx, []byte(bucket), &dirty); err != nil {
-+			return dirty, err
- 		} else {
- 			v := bkt.Get([]byte(key))
- 			exists = v != nil
--			return nil
-+			return dirty, nil
- 		}
- 	}); err != nil {
- 		log.Warn("%v", err)
-@@ -55,23 +59,25 @@ func Exists(bucket string, key string) (
- }
- 
- func GetBucketLen(bucket string) (length int, err error) {
--	err = DB().Update(func(tx *bbolt.Tx) error {
--		if bkt, err := tx.CreateBucketIfNotExists([]byte(bucket)); err != nil {
--			return err
-+	err = Transaction(DB(), func(tx *bbolt.Tx) (bool, error) {
-+		dirty := false
-+		if bkt, err := CreateBucketIfNotExists(tx, []byte(bucket), &dirty); err != nil {
-+			return dirty, err
- 		} else {
- 			length = bkt.Stats().KeyN
- 		}
--		return nil
-+		return dirty, nil
- 	})
- 	return length, err
- }
- 
- func GetBucketKeys(bucket string) (keys []string, err error) {
--	err = DB().Update(func(tx *bbolt.Tx) error {
--		if bkt, err := tx.CreateBucketIfNotExists([]byte(bucket)); err != nil {
--			return err
-+	err = Transaction(DB(), func(tx *bbolt.Tx) (bool, error) {
-+		dirty := false
-+		if bkt, err := CreateBucketIfNotExists(tx, []byte(bucket), &dirty); err != nil {
-+			return dirty, err
- 		} else {
--			return bkt.ForEach(func(k, v []byte) error {
-+			return dirty, bkt.ForEach(func(k, v []byte) error {
- 				keys = append(keys, string(k))
- 				return nil
- 			})
---- a/db/setOp.go
-+++ b/db/setOp.go
-@@ -4,8 +4,9 @@ import (
- 	"bytes"
- 	"crypto/sha256"
- 	"encoding/gob"
--	"go.etcd.io/bbolt"
-+
- 	"github.com/v2rayA/v2rayA/common"
-+	"go.etcd.io/bbolt"
- )
- 
- type set map[[32]byte]interface{}
-@@ -28,26 +29,27 @@ func toSha256(val interface{}) (hash [32
- }
- 
- func setOp(bucket string, key string, f func(m set) (readonly bool, err error)) (err error) {
--	return DB().Update(func(tx *bbolt.Tx) error {
--		if bkt, err := tx.CreateBucketIfNotExists([]byte(bucket)); err != nil {
--			return err
-+	return Transaction(DB(), func(tx *bbolt.Tx) (bool, error) {
-+		dirty := false
-+		if bkt, err := CreateBucketIfNotExists(tx, []byte(bucket), &dirty); err != nil {
-+			return dirty, err
- 		} else {
- 			var m set
- 			v := bkt.Get([]byte(key))
- 			if v == nil {
- 				m = make(set)
- 			} else if err := gob.NewDecoder(bytes.NewReader(v)).Decode(&m); err != nil {
--				return err
-+				return dirty, err
- 			}
- 			if readonly, err := f(m); err != nil {
--				return err
-+				return dirty, err
- 			} else if readonly {
--				return nil
-+				return dirty, nil
- 			}
- 			if b, err := common.ToBytes(m); err != nil {
--				return err
-+				return dirty, err
- 			} else {
--				return bkt.Put([]byte(key), b)
-+				return true, bkt.Put([]byte(key), b)
- 			}
- 		}
- 	})

+ 0 - 27
v2raya/patches/018-fix-do-not-rollback-closed-transaction.patch

@@ -1,27 +0,0 @@
-From 451912074ba1ba4000c66874876bc0a6b64cb5da Mon Sep 17 00:00:00 2001
-From: Kelo <[email protected]>
-Date: Sun, 30 Oct 2022 16:49:22 +0800
-Subject: [PATCH] fix: do not rollback closed transaction
-
----
- service/db/boltdb.go | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
---- a/db/boltdb.go
-+++ b/db/boltdb.go
-@@ -56,14 +56,13 @@ func Transaction(db *bbolt.DB, fn func(*
- 	if err != nil {
- 		return err
- 	}
--	defer tx.Rollback()
- 	dirty, err := fn(tx)
- 	if err != nil {
- 		_ = tx.Rollback()
- 		return err
- 	}
- 	if !dirty {
--		return nil
-+		return tx.Rollback()
- 	}
- 	return tx.Commit()
- }

+ 0 - 21
v2raya/patches/100-compat-v5.patch

@@ -1,21 +0,0 @@
---- a/core/v2ray/process.go
-+++ b/core/v2ray/process.go
-@@ -226,6 +226,7 @@ func StartCoreProcess(ctx context.Contex
- 	dir := path.Dir(v2rayBinPath)
- 	var arguments = []string{
- 		v2rayBinPath,
-+		"run",
- 		"--config=" + asset.GetV2rayConfigPath(),
- 	}
- 	if confdir := asset.GetV2rayConfigDirPath(); confdir != "" {
---- a/core/v2ray/where/where.go
-+++ b/core/v2ray/where/where.go
-@@ -41,7 +41,7 @@ func GetV2rayServiceVersion() (variant V
- 	if err != nil || len(v2rayPath) <= 0 {
- 		return Unknown, "", fmt.Errorf("cannot find v2ray executable binary")
- 	}
--	out, err := exec.Command(v2rayPath, "-version").Output()
-+	out, err := exec.Command(v2rayPath, "version").Output()
- 	var fields []string
- 	if fields = strings.Fields(strings.TrimSpace(string(out))); len(fields) < 2 {
- 		return Unknown, "", fmt.Errorf("cannot parse version of v2ray")

+ 2 - 2
xray-core/Makefile

@@ -1,12 +1,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=xray-core
-PKG_VERSION:=1.8.6
+PKG_VERSION:=1.8.7
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://codeload.github.com/XTLS/Xray-core/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=d828296c9f29f9e59a61ab73d44f072ab2a30fe979679e39aea43b33ddb7d6bf
+PKG_HASH:=e8f46177d792b89700f164ca28fbf1a3c7d95a3ecf98871cb0dd5e474b46a859
 
 PKG_MAINTAINER:=Tianling Shen <[email protected]>
 PKG_LICENSE:=MPL-2.0

+ 2 - 2
xray-plugin/Makefile

@@ -5,12 +5,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=xray-plugin
-PKG_VERSION:=1.8.6
+PKG_VERSION:=1.8.7
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://codeload.github.com/teddysun/xray-plugin/tar.gz/v$(PKG_VERSION)?
-PKG_HASH:=9df7e65fe1ae6a001240d304db3aeaa3d4b1e3a2f4db00aa498bbe1e2bb18729
+PKG_HASH:=6ee5ed3a6bbecc41dba99a107849de00e2e72d99fdea4f9af8ea95783cb38528
 
 PKG_LICENSE:=MIT
 PKG_LICENSE_FILES:=LICENSE