zapret-kvn/xray_fluent/network/ping_worker.py
loop-uh ec655661f9
Some checks failed
Windows project source guards / test (push) Has been cancelled
Пинг через ядро, VPN без пресета Zapret, окно без консоли, прокси для локальной сети
- Пинг: вместо пустого TCP-соединения — настоящее подключение тем ядром, что и
  VPN (Xray, sing-box, Hysteria), и «тёплый» запрос через него: число — RTT до
  сервера, Hysteria2/TUIC больше не «мёртвые», имя сервера разрешается своим
  DoH, а не провайдерским DNS; «не измерен» не превращается в «мёртв».
- Zapret выключен для сайтов → winws2 несёт только правило VPN-сервера, пресет
  не запускается; отсутствующие списки пресета пропускаются (профиль без своих
  списков — целиком), шипуемые пресеты ссылаются только на свои списки
  (netrogat.txt → list-exclude.txt, ipset-base.txt убран). Жалоба 0.8.45:
  «Запуск VPN заблокирован: правило Zapret… не готово».
- Сборка оконной программой: в Windows 11 консоль открывалась во вкладке
  Windows Terminal и не пряталась; дочерние процессы — с CREATE_NO_WINDOW.
- «Прокси для устройств в локальной сети»: в режиме VPN локальный SOCKS/HTTP
  слушает все адреса, правило брандмауэра только для локальной подсети,
  в карточке — адрес ПК для PS5/ТВ.
- Тест скорости: без российской цели для серверов с российским адресом.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-27 15:19:55 -04:00

56 lines
2.2 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Применение замера задержки к серверу; TCP-замер остался для зондов, где нужен голый connect.
Сам замер сервера — через ядро, ``latency_probe``; очередь — ``ping_service``.
"""
from __future__ import annotations
import socket
import time
from ..engines.singbox.config_builder import is_singbox_endpoint_node
from ..profiles.models import Node
def tcp_observation(host: str, port: int, timeout: float = 2.0) -> tuple[int | None, tuple[str, ...]]:
if not host or not port:
return None, ()
start = time.perf_counter()
try:
with socket.create_connection((host, port), timeout=timeout) as connection:
elapsed = int((time.perf_counter() - start) * 1000.0)
try:
peer = (str(connection.getpeername()[0]),)
except OSError:
peer = ()
return elapsed, peer
except OSError:
return None, ()
def tcp_ping(host: str, port: int, timeout: float = 2.0) -> int | None:
return tcp_observation(host, port, timeout)[0]
def ping_node(node: Node, timeout: float = 2.0) -> int | None:
"""TCP-пинг ноды; endpoint-ноды (UDP-only, напр. WireGuard/AWG) не пингуются."""
if is_singbox_endpoint_node(node):
return None
return tcp_ping(node.server, node.port, timeout)
def apply_ping_measurement(node: Node, ping_ms: int | None, *, measured: bool = True) -> None:
"""Применяет результат замера задержки к ноде.
``measured=False`` — проверить было нечем (ядра нет, адрес не узнать без
открытого DNS): прежний вывод о сервере остаётся, «мёртвым» он не становится.
"""
if not measured:
return
if is_singbox_endpoint_node(node):
# Endpoint-ноды (WireGuard/AWG) замер не проверяет: не «мёртвые».
node.ping_ms = None
return
node.ping_ms = ping_ms
if ping_ms is not None or node.is_alive is None:
node.is_alive = ping_ms is not None