feat: QUIC ハンドシェイク RTT で死活監視する via=quic モードを追加#13
Merged
Conversation
毎プローブで新規 QUIC(TLS1.3) ハンドシェイクを張り、dial→確立完了までの 壁時計を RTT とする。ステートレス単発 Send 契約のままで、tcp= 接続プローブの in-process な兄弟。CloseWithError で毎回ソケットを回収し、連続運用でも goroutine/fd をリークしないことを手動テストで確認。 設定: via=quic [port=443] [alpn=h3] [sni=NAME] [verify=on]。 TLS 証明書検証は既定 OFF(IP 宛プローブ向け、routeros と逆)。source= は DialAddr が [::]:0 を bind するため非対応(無視+起動時警告)。 依存: github.com/quic-go/quic-go v0.60.0(基盤 quic パッケージのみ使用、 qpack は不要)。バイナリ増分は約 +1.2MB。 テスト: 単体(verify 既定反転・SNI/port/alpn)、config パース、手動 (到達/不達/リーク監視)を追加。README と deadman.conf を更新。
- RTT 計測窓から DNS 解決を分離: ホスト名は Send 直前に解決し、計測は handshake のみにする(直接 ICMP と同じ。dns.google 実測で 62ms→25ms)。 - port= を構築時に検証: 無効値(abc/0/99999 等)は起動時警告+永続 X 行と なり、サイレント X のデバッグを回避(routeros の username 検証と同様)。 - ゾーン付き IPv6 リテラル fe80::1%eth0 を netip.ParseAddr で literal 判定し、 ゾーンが SNI に漏れないようにする(icmp_linux.go と同じ理由)。 - source= 無視の警告文言とテストコメントに quic を追加(本 PR の取りこぼし)。 - README: resolve_family が quic で無視される理由文を訂正(quic はローカル解決)。 - 単体テスト追加: 無効 port/ゾーン IPv6 の SNI 空/literal の resolveAddr。 見送り(理由): 永続 Transport 化=Pinger に Close() が無くリロード時に socket リーク/t グリフ=in-process 系は X に統一する既存方針/per-mode キー集合・ Method→capability テーブル=本 PR の範囲外(follow-up 候補)。
…honor follow-up 対応(コードレビュー #10 / #4): #10 source 可否の二重管理を解消: - Method ごとの {build, name, sourceUnsupported} を methodRegistry に集約。 New はテーブル参照になり、先の gocyclo/cyclop nolint を解消。 - SourceUnsupported とその起動時警告のモード一覧を同一レジストリから導出し、 文言の取りこぼし(本 PR で起きた #2)を構造的に防止。SourceUnsupportedModeNames を公開し parse_warn が自動生成。Describe は Spec 依存のため switch 据え置き。 #4(B) via=quic で resolve_family を honor: - quicPinger に解決ネットワークを持たせ LookupNetIP に反映(A/AAAA 固定)。 IP リテラルはファミリー確定済みのため対象外。README 契約を 「direct ICMP と via=quic で有効」に更新。 lint: - goconst を ignore-tests に(モード名とテストのケース名の綴り重複による誤検知を 回避。既存の test 除外方針の完成)。不要になった config の //nolint:goconst を削除。 テスト追加: TestSourceModeNames / TestNewQUICPingerResolveFamily。
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 166755dd85
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. |
コードレビューの P1 指摘(IPv6 ターゲットで DialAddr が機能しない)を実測検証。
quic-go の net.ListenUDP("udp", {IP: net.IPv4zero}) は IPv4zero が wildcard の
ため Go が [::] の dual-stack ソケットを開き、IPv6 にも届く(実測: LocalAddr=[::]、
IPv6/IPv4 とも WriteToUDP 成功、IPv6 リテラル h3 へのハンドシェイクも rtt~50ms で
成立)。よって family 別 PacketConn 化は不要。TestQUICReachableIPv6 で回帰を固定。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要
ping over QUIC モード(
via=quic)を追加します。upstream 作者の qping に着想を得たもので、毎プローブで新規 QUIC(TLS1.3)ハンドシェイクを張り、dial→確立完了までの壁時計を RTT として測ります。deadman のステートレス単発Send契約にそのまま収まる、tcp=接続プローブの in-process な兄弟です。設定(README も同時更新)
InsecureSkipVerify)。QUIC プローブは IP アドレスを直接対象にすることが多く、証明書/SAN 検査でほぼ毎回失敗するため(routeros とは既定が逆)。verify=onでオプトイン。DialAddrが[::]:0を bind するため)。指定すると無視+起動時警告。via=quicで有効(A/AAAA 固定)。IP リテラルは対象外。h3。SNI は省略時ホスト名、IP リテラルは空(ゾーン付き IPv6 も literal 判定)。RTT の意味
これはセッション確立 RTT で、TLS1.3 の暗号処理を含むため ICMP よりやや高めに出ます。qping の「確立済み接続上で PING フレームを撃つ定常 RTT」とは別物です(quic-go の公開 API にオンデマンドで PING を撃つ手段が無く、ステートレス契約に綺麗に収まる確立 RTT を採用しました)。README に明記しています。
依存
github.com/quic-go/quic-go v0.60.0(基盤quicパッケージのみ使用、qpack は不要)。go 1.25.0据え置き。内部設計
errorではなくResult.Code(既存契約を踏襲、Xグリフ)。methodRegistry(map[Method]{build, name, sourceUnsupported})に集約。New/SourceUnsupported/ 起動時の source 無効警告のモード一覧を単一ソースから導出し、文言 drift を構造的に防止。Describeは Spec 依存ラベルのため switch 据え置き。テスト・検証
//go:build manual): 到達(dns.google・1.1.1.1+sni)/ 不達(TEST-NET タイムアウト)/ リーク監視(30 プローブで goroutine・fd 増分ゼロ)。make check(tidy-check / fmt-check / vet / lint 0 issues / test)green、make cross(6 OS×arch)green。備考
goconst: ignore-tests: trueを追加(レジストリのnameがテストのケース名と綴り重複する誤検知の回避。既存の test 除外方針の完成形)。