ハクソク

世界を動かす技術を、日本語で。

Noq: n0の新しいRustによるQUIC実装

概要

  • noqは、汎用的なQUIC実装で、マルチパスとNATトラバーサルに対応
  • irohでv0.96から本番運用中、他用途にも利用可能
  • Quinnからのハードフォークに至った経緯
  • QUIC MultipathやNATトラバーサル等、先進的な機能を実装
  • 今後も機能拡張やコミュニティとの協力を継続予定

noq発表と背景

  • noq(number 0 QUIC)は、独自開発の汎用QUIC実装
  • Multipath(マルチパス)およびNATトラバーサルをサポート
  • iroh v0.96以降のトランスポート層として本番運用
  • iroh以外の用途にも適用可能な設計

Quinnからのフォーク理由

  • iroh開発時、Quinnの上でリレー/ダイレクト切替やNATトラバーサル、輻輳制御状態管理など多くの独自処理を実装
  • これらはQUICレイヤーから見えず、外部からの改善が困難
  • 当初はQuinnを追従しつつ最小限の差分で運用
  • マルチパスやリレー機能の深掘りにより、開発サイクルが乖離
  • Quinn側のレビューバーデン増大、構造的な改修が困難に
  • 問題解決にはハードフォークが最善と判断、協力は継続方針
  • Quinnへの拒否ではなく、目的特化のための分岐

noqの主な特徴

  • QUIC Multipath仕様のフル実装

    • Quinn/irohでの最大のアーキテクチャ転換点
    • 以前は複数経路(リレー、IPv4/IPv6直通)をQUIC下で独自管理
    • Multipath実装により、全経路がQUIC上のファーストクラス市民
    • 各経路ごとに輻輳状態を管理し、適切な経路選択が可能
    • レイテンシ改善等もシステマティックに処理
    • 汎用的なMultipath実装で、iroh以外でも利用可能
  • QUIC NATトラバーサルドラフトの独自解釈・実装

    • 本番グレードでの初事例
    • 多様なNAT環境下での動作をiroh数十万台で実地検証
    • QUICレイヤーでNATホールパンチを直接表現、輻輳制御やロス検出が高精度
    • 仕様は未確定だが、今後も継続的に改善予定
  • **QUIC Address Discovery(QAD)**の実装

    • iroh v0.32から運用
    • クライアントのパブリックIPアドレス取得をQUICで実現
    • 以前のSTUNと比較して、暗号化やプライバシー向上、プロトコルの硬直化防止
  • Qlogによる詳細なQUIC接続ログ対応

    • 多様なイベントをカバーし、qvis等の可視化ツールにも対応
    • Multipath専用イベントも拡張
    • 複数経路でのパケットフローを可視化するビューワプロトタイプも提供
  • WeakConnectionHandle型の追加

    • コネクション自体のライフタイムを保持しないハンドル
    • 必要時にフルConnectionへ昇格可能
    • std::sync::Weakに似た挙動だが、Arc不要
    • コネクションマネージャ等の実装で有用

noqの運用実績と互換性

  • iroh v0.96以降で本番運用中
  • Multipath実装の自己検証に加え、picoquic等他実装との相互運用テストも実施

今後の展望

  • 長期的な基盤として継続開発
  • NATトラバーサルやパフォーマンス最適化の更なる改善
  • QUICワーキンググループやQuinnチームとの協力継続
  • QUIC実装やP2Pトランスポート、多様なネットワーク環境でのアプリ開発者との連携を歓迎
  • Rust製QUIC Multipath実装を試したい場合は、noqドキュメント参照を推奨

irohについて

  • irohは、「どのデバイスでも繋がる」ネットワーキングライブラリ
  • 必要なプロトコルを組み合わせて機能追加、またはシンプルな抽象化レイヤーの上でカスタム開発も可能
  • オープンソースで、既に数十万台のデバイスで本番運用中
  • ドキュメント参照、コード閲覧、Discordでの質問が可能

Hackerたちの意見

このコメントスレッドで、Irohの人たちがフォークを決める話をしているのを見て、礼儀正しくて尊重し合ったやり取りがあって素敵だなと思いました。 :)
本当にそう思う。オープンソースのドラマが多い中で、いい対比になってるね。
いいやり取りだね。過去にメンテナがフォークを敵対的に扱ったり、「私たちの仕事を盗んだ」と言った問題があったから、すごく新鮮だよ。このメッセージは、内部の変更をアップストリームするのがどれだけ難しいかという現実も示しているね。彼らは、すべての作業を小さなインクリメンタルパッチとして再提出する時間がないと認めているんだ。レビューを受けるためには、約100のPRが必要になると見積もっているよ。これは、前に進み続けなければならない会社にとっては非常に大きな時間投資だね。フォーク元のプロジェクトの実装の詳細には、できるだけ近くにいてほしいな。フォークが十分にテストされたら、またインクリメンタル開発として扱うのではなく、大きな塊でマージを始めるのも合理的かもしれないね。
QUICのマルチパスRFCをちょうど読んでたんだけど、昨日出たばかりじゃなかった? 実装がRFCを先取りするのはよくあることだけど、こうやって連続して見るとちょっと驚くよね。
ずっとドラフトだったけど、最近やっと承認されたんだよね。
IETFのドラフトは、RFCとして最終化される前にかなり完成していることが多いよね。例えば、TLSでのML-KEMのサポートはまだドラフトだけど、技術的な部分が固まったのはかなり前だから、すでに大規模な導入がいくつかあるんだ。
多くのQUIC機能は、RFCのデザインを反復しながらドラフト段階で実装されるんだ(例えば、ACK Frequency[0]は現在ドラフト版14で、私は3年前にquinnでサポートを実装したよ)。 [0]: https://datatracker.ietf.org/doc/html/draft-ietf-quic-ack-fr...
グループが仕様が完成したとみなすのは、実装経験がある程度ないと難しいことが多いよね。実際の実装者が仕様の中で面白いバグを見つけることが多いし、実装なしでは測定が難しいことも多いから。
n0の人たちが大好き! 彼らのsendme CLIを使って、ピアツーピアのファイル転送をよくやってるよ!
なるほどね。普段はマジックワームホールを使ってるんだけど、これが結構便利なんだ。ただ、実現するためにたくさんのPythonモジュールをインストールしないといけなくて、うちのプロダクションのWindows SQLサーバーにそれをインストールするのはちょっと躊躇しちゃうんだよね。あんまり触らないから、触るときはだいたいPowerShellのスニペットか、https://github.com/linsomniac/toothpykを使って「netcat」みたいなことをするか、Windows側で「wget」しちゃう。SQL ServerのISOは、Windowsに内蔵されてるwgetがめっちゃ遅いけどね。送信先のヒントありがとう。
irohは、個人用アプリケーションを急速に構築している時代にとても良いポジションにいる製品だと思う。彼らがどう成長していくのか、すごく興味がある。個人的には、OSSで自己ホスティング可能(希望があれば)、ゼロコンフィグで自分のネットワーク上のアプリやデータにリモートアクセスできる「アプリリレー」を提供することを考えているんだ。これは「ネットワークリレー」(Tailscaleみたいな)とは別で、アプリケーションサーバーとクライアントの一部として選択的に行われるし、ユーザーとしての知識や設定も必要ないから、露出する面積がずっと小さいんだよね。
ゼロコンフィグの部分が実際には難しいところなんだよね。mDNSベースのディスカバリーをいろんな家庭のネットワークで動かすのに時間がかかったけど、めちゃくちゃだった。消費者向けのルーターの半分はサブネット間のマルチキャストを静かにドロップしちゃうし、いくつかは無駄になるほどレート制限をかけてくる。結局、フォールバックを重ねて(ブロードキャスト、次に直接プローブ、次にリレー)どのパスが実際に機能するかを選ぶためのヒューリスティックを書く羽目になった。QUICにマルチパスが組み込まれていれば、トランスポートがすべてのパスを試して一番良いものに収束してくれたら、かなり楽だったのに。
ここに私のリストがあるよ: https://github.com/anderspitman/awesome-tunneling 特にOpenZitiは、アプリにトンネルを埋め込むことに似た焦点を当てていると思うよ。
irohチームは本当に頑張ってるね。週末にじっくりirownをいじる時間ができるのが楽しみで、ずっとやりたいと思ってたんだ。nebulaみたいなオーバーレイネットワークを作りたいな。
すみません、どこかで説明されているかもしれませんが、noq/irohはピア間でQUICパケットをどうやって中継するんですか? 中継は、受け取ったQUICパケットをどこに送るべきかどうやって知るんでしょう? QUICは追跡が難しいことで有名ですよね。新しい/退役したconnection_idパケットを別の接続を通じて中継にストリームして、特定のピアにリンクさせるんですか? それとも、中継されたQUICは別のプロトコルでラップされているんですか?
noq自体はリレーのロジックを実装してないんだ。noqの視点から見ると、irohのリレーはパケットを送信したり受信したりする別のIPサブネットに過ぎないから、ただの別の経路ってわけ。 > それとも、リレーされたQUICは別のプロトコルでラップされてるの? そう、それが起こってるんだ。iroh/iroh-relay側では、WebSocketを使ってこのリレーを実装してる。データグラムには、どのEndpointId(ed25519の公開鍵)にパケットをリレーしたいかを示すヘッダーが付いてるんだ。irohクライアントとirohリレーの間のハンドシェイクのおかげで、リレーはリレーするデータグラムのソースEndpointIdを知っていて認証も済んでる。だから、QUICのデータグラムをTCPの上でHTTPSでトンネリングしてるってこと(暗号化は二重にしてる)。リレーは本当にフォールバックと調整のためだけだよ。UDPのブロッキングに影響されないように、フォールバックの最大の普及を目指してこれらの選択をしたんだ。
> noq(「ナンバー0 QUIC」) それならn0qになるんじゃない?
そうそう、俺もそう言ったんだ。でもチームのみんなは、ホストしてるirohを「n0des」って名付けようとする俺に疲れちゃって、今はそれが無理だったって認める準備ができたよ。だから今はn0qをnoqって綴ってる。人生ってそんなもんだよね。
これって、相手側がCA証明書を持っていなくてもQUIC接続を確立できるの? それとも、他の多くのQUICライブラリのように、企業が承認したドメインへの接続しか許可しないのかな?
「デフォルトを少数のクレイジーな人たちに合わせて、他のすべての人に不便を強いる」って人気がないことが分かったよ。実際、ほんの少数の好みを優先するのは本質的に人気がないんだ。それが政策としての定義的な特徴だね。
TLS認証の話は完全に設定可能だよ。これはQuinnと比べても変わってない。irohではnoqを使ってて、irohでは生の公開鍵(RFC7250)を使ってる。irohを使うときは、DNSやTLS証明書を設定する必要はなくて、ただ鍵を生成して公開鍵を共有すれば、他の人が接続できるんだ。(もちろん、公開鍵を安全に共有するのが難しいって問題はあるけどね。)
みんな、nQUICをチェックした? NoiseがNoqに統合されるのも面白そうだね :)