Просмотр исходного кода

Merge pull request #1865 from zxlhhyccc/tuic

luci-app-ssr-plus: Optimize the startup speed.
zxl hhyccc 1 месяц назад
Родитель
Сommit
cb8f7d7f30

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

@@ -211,7 +211,7 @@ start_dns() {
 	local run_mode="$(uci_get_by_type global run_mode)"
 
 	if [ "$ssrplus_dns" != "0" ]; then
-		if command -v iptables-legacy >/dev/null 2>&1; then
+		if command -v ipset >/dev/null 2>&1; then
 			if [ -n "$dnsserver" ]; then
 				add_dns_into_ipset $run_mode $dnsserver
 			fi
@@ -238,7 +238,7 @@ start_dns() {
 			output=$(for i in $(echo $mosdns_dnsserver | sed "s/,/ /g"); do
 				dnsserver=${i%:*}
 				dnsserver=${i##*/}
-				if command -v iptables-legacy >/dev/null 2>&1; then
+				if command -v ipset >/dev/null 2>&1; then
 					add_dns_into_ipset $run_mode $dnsserver
 				fi
 				echo "            - addr: $i"
@@ -1326,7 +1326,13 @@ start_server() {
 			;;
 		socks5)
 			[ -e /proc/sys/net/ipv6 ] && local listenip='-i ::'
-			ln_start_bin $(first_type microsocks) microsocks $listenip -p $(uci_get_by_name $1 server_port) -1 -u $(uci_get_by_name $1 username) -P $(uci_get_by_name $1 password) ssr-server$server_count
+			local username=$(uci_get_by_name $1 username)
+			local password=$(uci_get_by_name $1 password)
+			local auth_opts=""
+			if [ -n "$username" ] && [ -n "$password" ]; then
+				auth_opts="-u $username -P $password"
+			fi
+			ln_start_bin $(first_type microsocks) microsocks $listenip -p $(uci_get_by_name $1 server_port) -1 $auth_opts ssr-server$server_count
 			echolog "Server:Socks5 Server$server_count Started!"
 			;;
 		esac
@@ -1511,7 +1517,7 @@ start_rules() {
 		-M "$(uci_get_by_type global netflix_proxy 0)" \
 		-I "/etc/ssrplus/netflixip.list" \
 		$(get_arg_out) $(gfwmode) $ARG_UDP $ARG_A
-		
+
 	return $?
 }
 
@@ -1524,6 +1530,14 @@ start() {
 		Start_Run
 		start_xhttp_addr
 		start_rules
+		# Restore ipsets after rules creation
+		if command -v ipset >/dev/null 2>&1; then
+			for setname in gfwlist china blacklist whitelist netflix; do
+				if [ -f "/tmp/ssrplus_save/${setname}.save" ]; then
+					ipset restore -! < "/tmp/ssrplus_save/${setname}.save" 2>/dev/null
+				fi
+			done
+		fi
 		start_dns
 		add_cron
 		start_switch
@@ -1535,16 +1549,25 @@ start() {
 			echolog "未启动主节点,广告过滤正在加载。"
 			cp -f /etc/ssrplus/ad.conf $TMP_DNSMASQ_PATH/
 			if [ -f "$TMP_DNSMASQ_PATH/ad.conf" ]; then
-				for line in $(cat /etc/ssrplus/black.list); do sed -i "/$line/d" $TMP_DNSMASQ_PATH/ad.conf; done
-				for line in $(cat /etc/ssrplus/white.list); do sed -i "/$line/d" $TMP_DNSMASQ_PATH/ad.conf; done
-				for line in $(cat /etc/ssrplus/deny.list); do sed -i "/$line/d" $TMP_DNSMASQ_PATH/ad.conf; done
+				# Optimize: Batch filter using grep instead of looping sed
+				for list_file in /etc/ssrplus/black.list /etc/ssrplus/white.list /etc/ssrplus/deny.list; do
+					if [ -s "$list_file" ]; then
+						# Clean list file (remove comments and empty lines)
+						grep -vE '^\s*#|^\s*$' "$list_file" > "${list_file}.clean"
+						if [ -s "${list_file}.clean" ]; then
+							grep -v -F -f "${list_file}.clean" "$TMP_DNSMASQ_PATH/ad.conf" > "$TMP_DNSMASQ_PATH/ad.conf.tmp"
+							mv "$TMP_DNSMASQ_PATH/ad.conf.tmp" "$TMP_DNSMASQ_PATH/ad.conf"
+						fi
+						rm -f "${list_file}.clean"
+					fi
+				done
 			fi
 			echolog "广告过滤加载完毕。"
 		fi
 	fi
 	/etc/init.d/dnsmasq restart >/dev/null 2>&1
 	check_server
-    if command -v nft >/dev/null 2>&1; then
+	if command -v nft >/dev/null 2>&1; then
 		local CURRENT_SERVER="$(uci_get_by_type global global_server nil)"
 		if [ "$CURRENT_SERVER" != "nil" ]; then
 			uci set shadowsocksr.@global[0].old_global_server="$CURRENT_SERVER"
@@ -1565,18 +1588,27 @@ boot() {
 }
 
 stop() {
+	# Save ipsets before stopping to persist transparent proxy state
+	if command -v ipset >/dev/null 2>&1; then
+		mkdir -p /tmp/ssrplus_save
+		ipset save gfwlist > /tmp/ssrplus_save/gfwlist.save 2>/dev/null
+		ipset save china > /tmp/ssrplus_save/china.save 2>/dev/null
+		ipset save blacklist > /tmp/ssrplus_save/blacklist.save 2>/dev/null
+		ipset save whitelist > /tmp/ssrplus_save/whitelist.save 2>/dev/null
+		ipset save netflix > /tmp/ssrplus_save/netflix.save 2>/dev/null
+	fi
 	unlock
 	set_lock
-    if command -v nft >/dev/null 2>&1; then
-        /usr/bin/ssr-rules -K
-        local OLD_SERVER="$(uci_get_by_type global old_global_server nil)"
-        local NEW_SERVER="$(uci_get_by_type global global_server nil)"
-        if [ "$OLD_SERVER" != "nil" ] && [ "$NEW_SERVER" != "nil" ] && [ "$OLD_SERVER" != "$NEW_SERVER" ]; then
+	if command -v nft >/dev/null 2>&1; then
+		/usr/bin/ssr-rules -K
+		local OLD_SERVER="$(uci_get_by_type global old_global_server nil)"
+		local NEW_SERVER="$(uci_get_by_type global global_server nil)"
+		if [ "$OLD_SERVER" != "nil" ] && [ "$NEW_SERVER" != "nil" ] && [ "$OLD_SERVER" != "$NEW_SERVER" ]; then
 			/usr/bin/ssr-rules -X
-        fi
-        uci delete shadowsocksr.@global[0].old_global_server 2>/dev/null
-        uci commit shadowsocksr
-    fi
+		fi
+		uci delete shadowsocksr.@global[0].old_global_server 2>/dev/null
+		uci commit shadowsocksr
+	fi
 	/usr/bin/ssr-rules -f
 	local srulecount=0
 	if command -v nft >/dev/null 2>&1; then

+ 45 - 22
luci-app-ssr-plus/root/usr/share/shadowsocksr/gfw2ipset.sh

@@ -7,13 +7,21 @@ if command -v nft >/dev/null 2>&1; then
 fi
 
 netflix() {
-	if [ -f "$TMP_DNSMASQ_PATH/gfw_list.conf" ]; then
-		for line in $(cat /etc/ssrplus/netflix.list); do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_list.conf; done
-		for line in $(cat /etc/ssrplus/netflix.list); do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_base.conf; done
+	if [ -f "$TMP_DNSMASQ_PATH/gfw_list.conf" ] && [ -s /etc/ssrplus/netflix.list ]; then
+		grep -vE '^\s*#|^\s*$' /etc/ssrplus/netflix.list > /tmp/ssrplus_netflix.list.clean
+		if [ -s /tmp/ssrplus_netflix.list.clean ]; then
+			grep -v -F -f /tmp/ssrplus_netflix.list.clean "$TMP_DNSMASQ_PATH/gfw_list.conf" > "$TMP_DNSMASQ_PATH/gfw_list.conf.tmp"
+			mv "$TMP_DNSMASQ_PATH/gfw_list.conf.tmp" "$TMP_DNSMASQ_PATH/gfw_list.conf"
+			if [ -f "$TMP_DNSMASQ_PATH/gfw_base.conf" ]; then
+				grep -v -F -f /tmp/ssrplus_netflix.list.clean "$TMP_DNSMASQ_PATH/gfw_base.conf" > "$TMP_DNSMASQ_PATH/gfw_base.conf.tmp"
+				mv "$TMP_DNSMASQ_PATH/gfw_base.conf.tmp" "$TMP_DNSMASQ_PATH/gfw_base.conf"
+			fi
+		fi
+		rm -f /tmp/ssrplus_netflix.list.clean
 	fi
 	if [ "$nft_support" = "1" ]; then
 		# 移除 ipset
-		cat /etc/ssrplus/netflix.list | sed '/^$/d' | sed '/#/d' | sed "/.*/s/.*/server=\/&\/127.0.0.1#$1\nnftset=\/&\/4#inet#ss_spec#netflix/" >$TMP_DNSMASQ_PATH/netflix_forward.conf
+		cat /etc/ssrplus/netflix.list | sed '/^$/d' | sed '/#/d' | sed "/.*/s/.*/server=\/&\/127.0.0.1#$1\nnftset=\/&\/inet#ss_spec#netflix/" >$TMP_DNSMASQ_PATH/netflix_forward.conf
 	else
 		cat /etc/ssrplus/netflix.list | sed '/^$/d' | sed '/#/d' | sed "/.*/s/.*/server=\/&\/127.0.0.1#$1\nipset=\/&\/netflix/" >$TMP_DNSMASQ_PATH/netflix_forward.conf
 	fi
@@ -27,12 +35,12 @@ else
 fi
 
 if [ "$nft_support" = "1" ]; then
-    # 移除 ipset 指令
-    for conf_file in gfw_base.conf gfw_list.conf; do
-        if [ -f "$TMP_DNSMASQ_PATH/$conf_file" ]; then
-            sed -i 's|ipset=/\([^/]*\)/\([^[:space:]]*\)|nftset=/\1/4#inet#ss_spec#\2|g' "$TMP_DNSMASQ_PATH/$conf_file"
-        fi
-    done
+	# 移除 ipset 指令
+	for conf_file in gfw_base.conf gfw_list.conf; do
+		if [ -f "$TMP_DNSMASQ_PATH/$conf_file" ]; then
+			sed -i 's|ipset=/\([^/]*\)/\([^[:space:]]*\)|nftset=/\1/inet#ss_spec#\2|g' "$TMP_DNSMASQ_PATH/$conf_file"
+		fi
+	done
 fi
 
 if [ "$(uci_get_by_type global netflix_enable 0)" == "1" ]; then
@@ -55,17 +63,26 @@ $(uci_get_by_type global global_server nil) | $switch_server | same)
 esac
 
 # 此处使用while方式读取 防止 /etc/ssrplus/ 目录下的 black.list white.list deny.list 等2个或多个文件一行中存在空格 比如:# abc.com 而丢失:server
-while read line; do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_list.conf; done < /etc/ssrplus/black.list
-while read line; do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_base.conf; done < /etc/ssrplus/black.list
-while read line; do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_list.conf; done < /etc/ssrplus/white.list
-while read line; do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_base.conf; done < /etc/ssrplus/white.list
-while read line; do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_list.conf; done < /etc/ssrplus/deny.list
-while read line; do sed -i "/$line/d" $TMP_DNSMASQ_PATH/gfw_base.conf; done < /etc/ssrplus/deny.list
+# Optimize: Batch filter using grep
+for list_file in /etc/ssrplus/black.list /etc/ssrplus/white.list /etc/ssrplus/deny.list; do
+	if [ -s "$list_file" ]; then
+		grep -vE '^\s*#|^\s*$' "$list_file" > "${list_file}.clean"
+		if [ -s "${list_file}.clean" ]; then
+			for target_file in "$TMP_DNSMASQ_PATH/gfw_list.conf" "$TMP_DNSMASQ_PATH/gfw_base.conf"; do
+				if [ -f "$target_file" ]; then
+					grep -v -F -f "${list_file}.clean" "$target_file" > "${target_file}.tmp"
+					mv "${target_file}.tmp" "$target_file"
+				fi
+			done
+		fi
+		rm -f "${list_file}.clean"
+	fi
+done
 
 # 此处直接使用 cat 因为有 sed '/#/d' 删除了 数据
 if [ "$nft_support" = "1" ]; then
-	cat /etc/ssrplus/black.list | sed '/^$/d' | sed '/#/d' | sed "/.*/s/.*/server=\/&\/127.0.0.1#$dns_port\nnftset=\/&\/4#inet#ss_spec#blacklist/" >$TMP_DNSMASQ_PATH/blacklist_forward.conf
-	cat /etc/ssrplus/white.list | sed '/^$/d' | sed '/#/d' | sed "/.*/s/.*/server=\/&\/127.0.0.1\nnftset=\/&\/4#inet#ss_spec#whitelist/" >$TMP_DNSMASQ_PATH/whitelist_forward.conf
+	cat /etc/ssrplus/black.list | sed '/^$/d' | sed '/#/d' | sed "/.*/s/.*/server=\/&\/127.0.0.1#$dns_port\nnftset=\/&\/inet#ss_spec#blacklist/" >$TMP_DNSMASQ_PATH/blacklist_forward.conf
+	cat /etc/ssrplus/white.list | sed '/^$/d' | sed '/#/d' | sed "/.*/s/.*/server=\/&\/127.0.0.1\nnftset=\/&\/inet#ss_spec#whitelist/" >$TMP_DNSMASQ_PATH/whitelist_forward.conf
 else
 	cat /etc/ssrplus/black.list | sed '/^$/d' | sed '/#/d' | sed "/.*/s/.*/server=\/&\/127.0.0.1#$dns_port\nipset=\/&\/blacklist/" >$TMP_DNSMASQ_PATH/blacklist_forward.conf
 	cat /etc/ssrplus/white.list | sed '/^$/d' | sed '/#/d' | sed "/.*/s/.*/server=\/&\/127.0.0.1\nipset=\/&\/whitelist/" >$TMP_DNSMASQ_PATH/whitelist_forward.conf
@@ -75,10 +92,16 @@ cat /etc/ssrplus/deny.list | sed '/^$/d' | sed '/#/d' | sed "/.*/s/.*/address=\/
 if [ "$(uci_get_by_type global adblock 0)" == "1" ]; then
 	cp -f /etc/ssrplus/ad.conf $TMP_DNSMASQ_PATH/
 	if [ -f "$TMP_DNSMASQ_PATH/ad.conf" ]; then
-		for line in $(cat /etc/ssrplus/black.list); do sed -i "/$line/d" $TMP_DNSMASQ_PATH/ad.conf; done
-		for line in $(cat /etc/ssrplus/white.list); do sed -i "/$line/d" $TMP_DNSMASQ_PATH/ad.conf; done
-		for line in $(cat /etc/ssrplus/deny.list); do sed -i "/$line/d" $TMP_DNSMASQ_PATH/ad.conf; done
-		for line in $(cat /etc/ssrplus/netflix.list); do sed -i "/$line/d" $TMP_DNSMASQ_PATH/ad.conf; done
+		for list_file in /etc/ssrplus/black.list /etc/ssrplus/white.list /etc/ssrplus/deny.list /etc/ssrplus/netflix.list; do
+			if [ -s "$list_file" ]; then
+				grep -vE '^\s*#|^\s*$' "$list_file" > "${list_file}.clean"
+				if [ -s "${list_file}.clean" ]; then
+					grep -v -F -f "${list_file}.clean" "$TMP_DNSMASQ_PATH/ad.conf" > "$TMP_DNSMASQ_PATH/ad.conf.tmp"
+					mv "$TMP_DNSMASQ_PATH/ad.conf.tmp" "$TMP_DNSMASQ_PATH/ad.conf"
+				fi
+				rm -f "${list_file}.clean"
+			fi
+		done
 	fi
 else
 	rm -f $TMP_DNSMASQ_PATH/ad.conf