Add TCP ping fallback for servers that block ICMP (XRay, VLESS, Reality)

Made-with: Cursor
This commit is contained in:
anten-ka
2026-03-07 15:08:58 +03:00
parent ee13a9e512
commit f4dc06b09c
3 changed files with 119 additions and 7 deletions

View File

@@ -261,7 +261,9 @@ probe_server_cli() {
[ -n "$_RET_NOTE" ] && set_alias_note "$ip" "$_RET_NOTE"
if [ ${#pings[@]} -eq 0 ]; then
echo -e "${YELLOW}[WARN] Сервер не отвечает на ping.${NC}"
echo -e "${YELLOW}[WARN] Сервер не отвечает на ICMP ping.${NC}"
echo -e "${WHITE}(Это нормально для VLESS/XRay — ICMP часто заблокирован)${NC}"
echo -e "${WHITE}TCP-проверка будет доступна после добавления правила.${NC}"
read -p "Продолжить? (y/n): " ans
[[ "$ans" != "y" ]] && return 1
fi
@@ -403,6 +405,31 @@ get_target_ips() {
get_rules_list | awk -F'|' '{split($3,a,":"); print a[1]}' | sort -u
}
get_port_for_ip() {
local ip="$1"
get_rules_list | awk -F'|' -v ip="$ip" '{split($3,a,":"); if(a[1]==ip){print a[2]; exit}}'
}
tcp_ping() {
local ip="$1" port="$2" tout="${3:-3}"
local raw
raw=$(curl -so /dev/null -w '%{time_connect}' --max-time "$tout" --connect-timeout "$tout" "http://${ip}:${port}/" 2>/dev/null)
[ -z "$raw" ] && return 1
local ms
ms=$(awk "BEGIN {v=$raw*1000; if(v<0.5) exit 1; printf \"%.2f\", v}" 2>/dev/null) || return 1
echo "$ms"
}
smart_ping() {
local ip="$1" tout="${2:-3}" port="${3:-}"
local ms
ms=$(ping -c 1 -W "$tout" "$ip" 2>/dev/null | sed -n 's/.*time=\([0-9.]*\).*/\1/p')
if [ -n "$ms" ]; then echo "$ms"; return 0; fi
[ -z "$port" ] && port=$(get_port_for_ip "$ip")
[ -z "$port" ] && return 1
tcp_ping "$ip" "$port" "$tout"
}
remove_rules_for_port() {
local proto="$1" in_port="$2"
iptables -t nat -S PREROUTING 2>/dev/null | grep "DNAT" | grep -- "--dport ${in_port} " | grep -- "-p ${proto} " | while read -r rule; do
@@ -717,14 +744,18 @@ ping_live() {
trap 'running=0' INT
local _port; _port=$(get_port_for_ip "$ip")
local _mode="ICMP"
[ -n "$_port" ] && _mode="ICMP/TCP:${_port}"
while [ "$running" -eq 1 ]; do
local ms
ms=$(ping -c 1 -W 3 "$ip" 2>/dev/null | sed -n 's/.*time=\([0-9.]*\).*/\1/p')
ms=$(smart_ping "$ip" 3 "${_port:-}")
((count++))
clear
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${CYAN} Live Ping: ${WHITE}$label${CYAN} [Ctrl+C — стоп]${NC}"
echo -e "${CYAN} Live Ping: ${WHITE}$label${CYAN} (${_mode}) [Ctrl+C — стоп]${NC}"
echo -e "${CYAN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
if [ -n "$ms" ]; then
@@ -885,7 +916,7 @@ monitor_daemon() {
[ -f "$ckf" ] && lc=$(cat "$ckf")
if (( now - lc >= MON_INTERVAL )); then
echo "$now" > "$ckf"
local pr; pr=$(ping -c 1 -W 3 "$MON_IP" 2>/dev/null | sed -n 's/.*time=\([0-9.]*\).*/\1/p')
local pr; pr=$(smart_ping "$MON_IP" 3)
if [ -z "$pr" ]; then
monitor_alert "$MON_IP" "TIMEOUT" "$MON_THRESHOLD" "$MON_COOLDOWN"
else
@@ -1204,7 +1235,7 @@ bot_handle_callback() {
ps:*) local ip="${data#ps:}"; local lb; lb=$(fmt_ip_short "$ip")
tg_edit "$chat_id" "$msg_id" "🏓 <b>$lb</b>\nРежим:" "$(kbd_ping_opts "$ip")" ;;
po:*) local ip="${data#po:}"; local lb; lb=$(fmt_ip_short "$ip")
( local ms; ms=$(ping -c 1 -W 3 "$ip" 2>/dev/null | sed -n 's/.*time=\([0-9.]*\).*/\1/p')
( local ms; ms=$(smart_ping "$ip" 3)
[ -n "$ms" ] && tg_send "$chat_id" "🏓 <b>$lb</b>\n<code>${ms} ms</code>" "$(kbd_back)" > /dev/null \
|| tg_send "$chat_id" "🏓 <b>$lb</b>\n<code>timeout</code>" "$(kbd_back)" > /dev/null ) & ;;
p10:*) local ip="${data#p10:}"; local lb; lb=$(fmt_ip_short "$ip")
@@ -1212,7 +1243,7 @@ bot_handle_callback() {
local mid; mid=$(echo "$resp" | jq -r '.result.message_id // empty')
local -a res=(); local lost=0 txt=""
for n in $(seq 1 10); do
local ms; ms=$(ping -c 1 -W 3 "$ip" 2>/dev/null | sed -n 's/.*time=\([0-9.]*\).*/\1/p')
local ms; ms=$(smart_ping "$ip" 3)
[ -n "$ms" ] && res+=("$ms") && txt+="#$n: ${ms}ms\n" || { ((lost++)); txt+="#$n: timeout\n"; }
sleep 1
done
@@ -1226,7 +1257,7 @@ bot_handle_callback() {
local mid; mid=$(echo "$resp" | jq -r '.result.message_id // empty')
local -a res=(); local lost=0
for n in $(seq 1 60); do
local ms; ms=$(ping -c 1 -W 3 "$ip" 2>/dev/null | sed -n 's/.*time=\([0-9.]*\).*/\1/p')
local ms; ms=$(smart_ping "$ip" 3)
[ -n "$ms" ] && res+=("$ms") || ((lost++))
if (( n % 10 == 0 )) && [ -n "$mid" ]; then
local p="🏓 <b>$lb</b>: ${n}/60с\nОК: ${#res[@]} | Lost: $lost"