Merge pull request #1243 from abcfy2/dev

检测端口冲突时区分 tcp 和 udp 端口,防止误报
This commit is contained in:
juewuy
2026-03-22 20:41:16 -07:00
committed by GitHub
4 changed files with 1363 additions and 1300 deletions

View File

@@ -43,36 +43,47 @@ checkrestart() {
# 检查端口冲突 # 检查端口冲突
checkport() { checkport() {
. "$CRASHDIR"/menus/check_port.sh
while true; do while true; do
# Before each round of checks begins, execute netstat only once and cache the results local conflict_found=0
# Avoid calling the system command once for each port local conflict_port=""
current_listening=$(netstat -ntul 2>&1) local conflict_info=""
conflict_found=0 conflict_info=$(check_port_with_info "$mix_port")
if [ $? -ne 0 ]; then
conflict_found=1
conflict_port="$mix_port"
fi
for portx in $dns_port $mix_port $redir_port $((redir_port + 1)) $db_port; do if [ "$conflict_found" -eq 0 ]; then
# Use `grep` to search within the cached variables instead of re-running `netstat` conflict_info=$(check_port_with_info "$redir_port")
conflict_line=$(echo "$current_listening" | grep ":$portx ") [ $? -ne 0 ] && conflict_found=1 && conflict_port="$redir_port"
fi
if [ -n "$conflict_line" ]; then if [ "$conflict_found" -eq 0 ]; then
conflict_info=$(check_port_with_info "$((redir_port + 1))")
[ $? -ne 0 ] && conflict_found=1 && conflict_port="$((redir_port + 1))"
fi
comp_box "$portx】:$MENU_PORT_CONFLICT_TITLE" \ if [ "$conflict_found" -eq 0 ]; then
"\033[0m$(echo "$conflict_line" | head -n 1)\033[0m" \ conflict_info=$(check_port_with_info "$dns_port")
[ $? -ne 0 ] && conflict_found=1 && conflict_port="$dns_port"
fi
if [ "$conflict_found" -eq 0 ]; then
conflict_info=$(check_port_with_info "$db_port" tcp)
[ $? -ne 0 ] && conflict_found=1 && conflict_port="$db_port"
fi
if [ "$conflict_found" -eq 1 ]; then
comp_box "$conflict_port】:$MENU_PORT_CONFLICT_TITLE" \
"\033[0m$conflict_info\033[0m" \
"\033[36m$MENU_PORT_CONFLICT_HINT\033[0m" "\033[36m$MENU_PORT_CONFLICT_HINT\033[0m"
. "$CRASHDIR"/menus/2_settings.sh && set_adv_config . "$CRASHDIR"/menus/2_settings.sh && set_adv_config
. "$CRASHDIR"/libs/get_config.sh . "$CRASHDIR"/libs/get_config.sh
else
# Mark conflict and exit the for loop, triggering the while loop to restart the check
# This replaces the original recursive call to `checkport`
conflict_found=1
break
fi
done
# If no conflicts are found after the entire for loop completes,
# the while loop exits and the function terminates.
if [ "$conflict_found" -eq 0 ]; then
break break
fi fi
done done

View File

@@ -389,17 +389,30 @@ set_redir_mod() {
} }
inputport() { inputport() {
local protocol="${1:-all}"
line_break line_break
read -r -p "$INPUT_PORT165535> " portx read -r -p "$INPUT_PORT165535> " portx
. "$CRASHDIR"/menus/check_port.sh # 加载测试函数 . "$CRASHDIR"/menus/check_port.sh
if check_port "$portx"; then
setconfig "$xport" "$portx" if ! check_port "$portx" "$protocol"; then
msg_alert "\033[32m$COMMON_SUCCESS\033[0m"
return 0
else
msg_alert "\033[31m$COMMON_FAILED\033[0m" msg_alert "\033[31m$COMMON_FAILED\033[0m"
return 1 return 1
fi fi
local ports_to_check=""
[ "$xport" != "mix_port" ] && ports_to_check="$ports_to_check|$mix_port"
[ "$xport" != "redir_port" ] && ports_to_check="$ports_to_check|$redir_port"
[ "$xport" != "dns_port" ] && ports_to_check="$ports_to_check|$dns_port"
[ "$xport" != "db_port" ] && ports_to_check="$ports_to_check|$db_port"
if echo "$ports_to_check|" | grep -q "|$portx|"; then
msg_alert "\033[31m$CHECK_PORT_DUP_ERR\033[0m"
return 1
fi
setconfig "$xport" "$portx"
msg_alert "\033[32m$COMMON_SUCCESS\033[0m"
return 0
} }
# 端口设置 # 端口设置
@@ -476,7 +489,7 @@ set_adv_config() {
;; ;;
5) 5)
xport=db_port xport=db_port
inputport inputport tcp
if [ $? -eq 1 ]; then if [ $? -eq 1 ]; then
break break
else else

View File

@@ -316,8 +316,13 @@ set_vmess() {
vms_port='' vms_port=''
setconfig vms_port "" "$GT_CFG_PATH" setconfig vms_port "" "$GT_CFG_PATH"
elif check_port "$text"; then elif check_port "$text"; then
if echo "|$mix_port|$redir_port|$dns_port|$db_port|" | grep -q "|$text|"; then
msg_alert "\033[31m$CHECK_PORT_DUP_ERR\033[0m"
sleep 1
else
vms_port="$text" vms_port="$text"
setconfig vms_port "$text" "$GT_CFG_PATH" setconfig vms_port "$text" "$GT_CFG_PATH"
fi
else else
sleep 1 sleep 1
fi fi
@@ -439,8 +444,13 @@ set_shadowsocks() {
sss_port='' sss_port=''
setconfig sss_port "" "$GT_CFG_PATH" setconfig sss_port "" "$GT_CFG_PATH"
elif check_port "$text"; then elif check_port "$text"; then
if echo "|$mix_port|$redir_port|$dns_port|$db_port|" | grep -q "|$text|"; then
msg_alert "\033[31m$CHECK_PORT_DUP_ERR\033[0m"
sleep 1
else
sss_port="$text" sss_port="$text"
setconfig sss_port "$text" "$GT_CFG_PATH" setconfig sss_port "$text" "$GT_CFG_PATH"
fi
else else
sleep 1 sleep 1
fi fi
@@ -677,4 +687,3 @@ set_wireguard() {
esac esac
done done
} }

View File

@@ -3,17 +3,47 @@
load_lang check_port load_lang check_port
_get_netstat_cmd() {
case "$1" in
tcp) echo "netstat -ntl" ;;
udp) echo "netstat -nul" ;;
*) echo "netstat -ntul" ;;
esac
}
check_port() { check_port() {
if [ "$1" -gt 65535 ] || [ "$1" -le 1 ]; then local port="$1"
local protocol="${2:-all}"
if [ "$port" -gt 65535 ] || [ "$port" -le 1 ]; then
msg_alert "\033[31m$CHECK_PORT_RANGE_ERR\033[0m" msg_alert "\033[31m$CHECK_PORT_RANGE_ERR\033[0m"
return 1 return 1
elif echo "|$mix_port|$redir_port|$dns_port|$db_port|" | grep -q "|$1|"; then fi
msg_alert "\033[31m$CHECK_PORT_DUP_ERR\033[0m"
return 1 local check_cmd
elif netstat -ntul | grep -q ":$1[[:space:]]"; then check_cmd=$(_get_netstat_cmd "$protocol")
if $check_cmd 2>/dev/null | grep -q ":${port}[[:space:]]"; then
msg_alert "\033[31m$CHECK_PORT_OCCUPIED_ERR\033[0m" msg_alert "\033[31m$CHECK_PORT_OCCUPIED_ERR\033[0m"
return 1 return 1
else
return 0
fi fi
return 0
}
check_port_with_info() {
local port="$1"
local protocol="${2:-all}"
local check_cmd
check_cmd=$(_get_netstat_cmd "$protocol")
local conflict_line
conflict_line=$($check_cmd 2>/dev/null | grep ":${port}[[:space:]]" | head -n 1)
if [ -n "$conflict_line" ]; then
echo "$conflict_line"
return 1
fi
return 0
} }