mirror of
https://gitee.com/xmz7891/ykxmz.git
synced 2026-10-18 12:30:44 +00:00
纠正一个传出去的错误结论:不是「运营商封了 UDP」
我在给部署脚本的指示里写过:
实测这条线路上运营商对 UDP 有限制 ——
12 个 Cloudflare edge IP:TCP 12/12 通、UDP 0/12 通
它照这个把注释写进了 relay/deploy.sh。
**但这个测量是无效的。** relay-stability 后来自己纠正了:
那个 UDP 探测包是手搓的简化包,格式不对,
Cloudflare 本来就不该回应它 —— 「0/12 无回应」什么都证明不了。
用 cloudflared --loglevel debug 跑临时实例,真相是:
UDP Connectivity region1/region2 PASS QUIC connection successful
SUMMARY: Environment is healthy. cloudflared will use 'quic'
Registered tunnel connection (握手 1 秒)
**UDP 完全通。**
真因是:QUIC 建连要 6+ 个包往返,而 TCP 的 SYN 只有 3 个包、
内核还会按 1s/2s/4s 激进重传。约 5.4%/包 丢包下:
(1 - 0.054)^6 ≈ 72% <- 和实测的 72% 对得上
所以 QUIC 的弱点在「连不上」,不在「连上之后不好」;
一旦连上,它没有 TCP 的跨流队头阻塞,反而更稳。
结论的**用途**没变(还是要两条协议一起跑),但留着错误的根因注释会:
* 误导后人以为 UDP 被封 -> 可能做出「干脆别用 QUIC」的错误决定
* 掩盖真正可优化的方向(QUIC 握手对丢包敏感是链路物理属性,
只能靠 HTTP/2 兜底来绕,不是「运营商限制」)
改动:relay/deploy.sh 两处、_build/test_deploy_sh.sh 一处。
教训记一笔:**手搓协议包去探测可达性非常容易得出错误结论** ——
那个包格式不对,对方根本没义务回应。要么用官方工具的自检
(cloudflared 自己会打 UDP Connectivity PASS/FAIL),
要么别下结论。
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""守住「局域网/中转对比基准」的两个坑。
|
||||
|
||||
为什么专门为测试脚本立一个测试:
|
||||
这个基准一度是红的,报告里写着「这是中转链路的产品 bug」——
|
||||
而实际上产品是好的,是基准自己有两个 bug:
|
||||
1. 两条路用了同一个配对码 -> 第 2 台被「一码一机」规则拒掉,
|
||||
而第 1 台虽然被杀、中转还以为在线,于是"看着成功、实际没人回包"
|
||||
2. relay_connect() 里 attach 用的还是旧码,attach 到死设备上
|
||||
这两个 bug 让一个已经修好的产品背了黑锅,而且**很难自己发现** ——
|
||||
因为症状(连接超时)看起来完全像产品问题。
|
||||
|
||||
所以既要做源码守卫(防止改回去),也要真跑一遍短版本
|
||||
(防止断言与实现脱钩)。
|
||||
|
||||
覆盖:
|
||||
一、源码守卫:两条路必须用不同的码
|
||||
二、源码守卫:attach 必须用 relay_code
|
||||
三、源码守卫:start_agent 的判据必须认码(不能被僵尸设备骗过)
|
||||
四、真跑一遍短基准:两条路都要通
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
BENCH = ROOT / "_tests" / "bench_lan_vs_relay.py"
|
||||
|
||||
passed = 0
|
||||
failed = 0
|
||||
|
||||
|
||||
def check(name, ok, detail=""):
|
||||
global passed, failed
|
||||
if ok:
|
||||
passed += 1
|
||||
print(" [PASS] " + name)
|
||||
else:
|
||||
failed += 1
|
||||
print(" [FAIL] " + name + ((" —— " + str(detail)) if detail else ""))
|
||||
|
||||
|
||||
def main() -> int:
|
||||
check("基准脚本存在", BENCH.is_file(), BENCH)
|
||||
if not BENCH.is_file():
|
||||
return 1
|
||||
src = BENCH.read_text(encoding="utf-8")
|
||||
|
||||
# ---------------------------------------------------------- 一
|
||||
print(" ---- 一、两条路用不同的配对码 ----")
|
||||
has_lan = re.search(r'^\s*code\s*=\s*"(\d{6})"', src, re.M)
|
||||
has_relay = re.search(r'^\s*relay_code\s*=\s*"(\d{6})"', src, re.M)
|
||||
check("定义了局域网用的 code", bool(has_lan),
|
||||
"找不到 `code = \"数字\"`")
|
||||
check("定义了中转用的 relay_code", bool(has_relay),
|
||||
"找不到 `relay_code = ...`")
|
||||
if has_lan and has_relay:
|
||||
check("两个码不一样(否则第 2 台会被一码一机规则拒掉)",
|
||||
has_lan.group(1) != has_relay.group(1),
|
||||
"两个码都是 %s" % has_lan.group(1))
|
||||
|
||||
# ---------------------------------------------------------- 二
|
||||
print(" ---- 二、attach 要用 relay_code ----")
|
||||
# 找出 relay_connect 函数体
|
||||
m = re.search(r"def relay_connect\(\):(.*?)(?=\n def |\n relay =)",
|
||||
src, re.S)
|
||||
body = m.group(1) if m else ""
|
||||
check("能定位到 relay_connect", bool(body), "函数没找到或改名了")
|
||||
if body:
|
||||
check("relay_connect 里用的是 relay_code",
|
||||
"relay_code" in body,
|
||||
"里面还在用 code —— attach 会打到局域网那台死设备上")
|
||||
check("relay_connect 里没有裸 attach(code)",
|
||||
not re.search(r"attach\(\s*code\s*\)", body),
|
||||
"attach(code) 还在,要改成 attach(relay_code)")
|
||||
|
||||
# ---------------------------------------------------------- 三
|
||||
print(" ---- 三、start_agent 的判据要认码 ----")
|
||||
m2 = re.search(r"def start_agent\(([^)]*)\):(.*?)(?=\n def )",
|
||||
src, re.S)
|
||||
body2 = m2.group(2) if m2 else ""
|
||||
check("start_agent 接受码参数", bool(m2) and "agent_code" in m2.group(1),
|
||||
m2.group(1) if m2 else "没找到")
|
||||
if body2:
|
||||
# 不能只判断"有没有在线设备"
|
||||
only_online = re.search(
|
||||
r'if\s+any\(d\.get\("online"\)', body2)
|
||||
check("没有「只看有没有在线设备」的松判据", not only_online,
|
||||
"僵尸设备会骗过它 —— 上一台被杀但中转还没清理")
|
||||
check("判据里比对了配对码", "agent_code" in body2,
|
||||
"应改成「在线且码正好是这一台要用的码」")
|
||||
|
||||
# ---------------------------------------------------------- 四
|
||||
print(" ---- 四、真跑一遍短基准(两条路都要通)----")
|
||||
try:
|
||||
proc = subprocess.run(
|
||||
[sys.executable, "-u", str(BENCH),
|
||||
"--rounds", "6", "--relay-rounds", "6", "--relay-timeout", "40"],
|
||||
cwd=str(ROOT), capture_output=True, text=True,
|
||||
encoding="utf-8", errors="replace", timeout=420)
|
||||
out = (proc.stdout or "") + (proc.stderr or "")
|
||||
m3 = re.search(r"BENCH_RESULT\s+(.*)", out)
|
||||
result = m3.group(1) if m3 else ""
|
||||
check("基准跑完并输出了 BENCH_RESULT", bool(result),
|
||||
out[-300:] if not result else "")
|
||||
if result:
|
||||
nums = dict(re.findall(r"(\w+)=([\w/.\-]+)", result))
|
||||
lan_ok = nums.get("lan_ok", "0/0")
|
||||
relay_ok = nums.get("relay_ok", "0/0")
|
||||
check("局域网那条路通了", lan_ok.startswith("6/6"), lan_ok)
|
||||
check("中转那条路通了", relay_ok.startswith("6/6"), relay_ok)
|
||||
except subprocess.TimeoutExpired:
|
||||
check("基准在 420 秒内跑完", False, "超时")
|
||||
except Exception as exc: # noqa: BLE001
|
||||
check("基准能跑起来", False, exc)
|
||||
|
||||
print()
|
||||
print("=" * 56)
|
||||
print(" 通过 %d 项,失败 %d 项" % (passed, failed))
|
||||
return 0 if failed == 0 else 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -400,6 +400,17 @@ $stageOut = & python (Join-Path $root "_tests\check_encoding.py") 2>&1
|
||||
Show-Fails $stageOut
|
||||
Record "编码与换行" ($LASTEXITCODE -eq 0)
|
||||
|
||||
# ---------------------------------------------------------------- 3a5
|
||||
Banner "3a5/7 局域网/中转对比基准(防测试自己骗人)"
|
||||
# 这个基准一度是红的,而且报告里写着「这是中转链路的产品 bug」——
|
||||
# 实际是基准自己有两个 bug:两条路用了同一个配对码、
|
||||
# 以及 attach 用了旧码(打到已经死掉的设备上)。
|
||||
# 一个已经修好的产品因此背了黑锅,而且症状(连接超时)
|
||||
# 看起来完全像产品问题,极难自己发现。
|
||||
$stageOut = & python (Join-Path $root "_tests\test_lan_bench_guard.py") 2>&1
|
||||
Show-Fails $stageOut
|
||||
Record "局域网对比基准" ($LASTEXITCODE -eq 0)
|
||||
|
||||
# ---------------------------------------------------------------- 3b
|
||||
Banner "3b/7 Python 静态检查(pyflakes)"
|
||||
# 这一层能抓到"运行到某行才炸"的问题。
|
||||
|
||||
Reference in New Issue
Block a user