#!/bin/bash # QUIC 握手细节:跑一个**临时的** debug 实例(60 秒),不动生产实例。 # # 目的:拿到 "timeout: no recent network activity" 背后的握手细节 —— # 是 Initial 包发出去没回应?还是 TLS 阶段断的?还是 MTU 卡在某个大小? # # 注意:这个临时实例会往同一个具名隧道多注册 1 条连接, # 60 秒后自己退出。对生产只有极轻微影响。 set -u LOG=/tmp/quic_debug.log rm -f "$LOG" echo "════════ 1. 跑 60 秒 debug 实例 ════════" echo " 参数: --protocol quic --ha-connections 1 --loglevel debug" echo " metrics 用 20299(避开生产的 20241/20242)" echo timeout 60 /usr/local/bin/cloudflared tunnel \ --protocol quic \ --edge-ip-version 4 \ --ha-connections 1 \ --no-autoupdate \ --loglevel debug \ --metrics 127.0.0.1:20299 \ --config /root/.cloudflared/config.yml \ run lanremote > "$LOG" 2>&1 || true echo " 日志行数: $(wc -l < "$LOG")" echo echo "════════ 2. 握手相关的事件 ════════" grep -iE 'initial|handshake|dial|registration|curve|version|mtu|congestion|tls' "$LOG" \ | head -40 | sed 's/^/ /' echo echo "════════ 3. QUIC 特有的细节 ════════" grep -iE 'quic|udp' "$LOG" | head -25 | sed 's/^/ /' echo echo "════════ 4. 失败/警告 ════════" grep -iE 'ERR|WRN|failed|timeout|refused|unreachable' "$LOG" | head -25 | sed 's/^/ /' echo echo "════════ 5. 成功注册了吗 ════════" grep -c 'Registered tunnel connection' "$LOG" | sed 's/^/ 成功注册次数: /' grep 'Registered tunnel connection' "$LOG" | tail -3 | sed 's/^/ /' echo echo "════════ 6. 用了多久完成握手 ════════" # 找第一条和注册成功的时间戳 first=$(head -1 "$LOG" | grep -oE '^[0-9T:.Z-]+' || echo "?") last=$(grep 'Registered tunnel connection' "$LOG" | head -1 | grep -oE '^[0-9T:.Z-]+' || echo "?") echo " 首行时间: $first" echo " 注册成功: $last" echo echo "════════ 7. debug 级别的包级细节(前 30 行原始日志)════════" head -30 "$LOG" | sed 's/^/ /' echo echo "════════ 8. 确认生产实例没受影响 ════════" for port in 20241 20242; do n=$(curl -s --max-time 4 "http://127.0.0.1:$port/metrics" 2>/dev/null \ | grep '^cloudflared_tunnel_ha_connections' | awk '{print $2}') echo " 端口 $port: ${n:-无响应}" done echo " 20299(临时实例,应该已退出): $(ss -tlnp 2>/dev/null | grep -c 20299)" echo " 长测进度: 健康 $(wc -l < /root/long2h_health.tsv) 条, 轮询 $(wc -l < /root/rp_poll30.tsv) / 30"