Repository navigation
feat: WebTransport(HTTP/3、UDP、BBR)で中継する。だめなら WebSocket に戻る / v0.8.0 - #56
Conversation
msquic を P/Invoke で直接呼び、HTTP/3 と QPACK と WebTransport を自前で話す。 System.Net.Quic は QUIC の datagram を宣言できず、Kestrel の WebTransport は draft-02 で止まっている。 輻輳制御は BBR、datagram の受信を有効にする。 - MsQuic.cs: msquic の API 表と構造体、接続と stream の包み - Http3.cs / Qpack.cs: 可変長整数、フレーム、SETTINGS、静的表と Huffman の QPACK - WebTransport.cs: 拡張 CONNECT のセッション、0x41 / 0x54 の stream、datagram、capsule - Program.cs: 証明書(ECDSA P-256、13 日)を作り、エコーのサーバーと試験のページを動かす - headless.cjs: Playwright の Chromium で test.html を開く Chromium 141 で双方向、単方向、datagram、セッションの close を確かめた。 Chrome の SETTINGS は draft-02(0x2b603742)だけだったので、draft-02 と draft-07 の両方を宣言する。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M2BadDnB3uH3FDGjaPMP4J
msquic を P/Invoke で直接呼び、HTTP/3 と QPACK と WebTransport を自前で話す(server/Quic/)。 輻輳制御は BBR。/wt の最初の双方向 stream で、/ws と同じ RDCleanPath の中継をする。 - サーバー: UDP 443 で待ち受ける(設定 webtransport。tls が acme なら既定で使う)。証明書は ACME のものを PKCS#12 にして渡し、取り直したら次の接続から差し替える。msquic が読めなければ WebSocket だけで動く - 認証: CONNECT の Origin と /wt?token= の使い捨てのトークンを見て、RDCleanPath の proxy_auth が 同じトークンであることを確かめる(Cookie が付かないので) - 中継: Relay を IRelayChannel で包み、WebSocket とバイトの流れの両方で動かす。 受信は溜まりすぎたら msquic の受信を止め、送信は msquic がバッファを返すまで待つ - msquic.dll(Microsoft.Native.Quic.MsQuic.Schannel 2.6.2)を exe の隣に置き、MSI に入れる。 ファイアウォールに UDP 443 を足す - クライアント: /api/session の wt があれば WebTransport を 1.5 秒試し、だめなら WebSocket。診断に道を出す - 試験: varint、QPACK、Huffman、SETTINGS、CONNECT、トークン、バイトの流れでの中継。 tools/wt-e2e で Linux の mado と xrdp を headless の Chromium でつなぐ - tools/wt-poc は server/Quic に移したので消す Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M2BadDnB3uH3FDGjaPMP4J
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M2BadDnB3uH3FDGjaPMP4J
|
Claude finished @5ym's task in 42s —— View job レビュー結果WebTransport を足す設計は筋が通っていて、既存の 指摘1. 要確認: 認証前の接続が残り続ける(
2. 認証の強さの説明(
3. 軽微:
4. 軽微:
良い点
確認できていないこと
|
| log("wt open"); | ||
| try | ||
| { | ||
| await Relay.Run(new StreamChannel(bytes), auth => |
There was a problem hiding this comment.
要確認(堅牢性): ここから Relay.Run は RDCleanPath の要求が届くまで、時間制限なしに待ちます。WebTransport は KeepAliveIntervalMs = 15s なので、CONNECT を通ったあとに stream を開いて何も送らない接続は、idle timeout(60s)で切れず、ずっと残ります。
/ws では Cookie でログイン済みの相手に限られますが、こちらは CONNECT に有効なトークン(60 秒で切れるが、CONNECT では使い切らない)があれば、同じトークンで何本でも CONNECT と stream を開けます。
- 要求が届くまでに数秒〜十数秒の期限を付ける(
cts.CancelAfterを要求が揃ったら解除する形など) - または、CONNECT を通すときにトークンを使い切る
どちらかを検討してください。
レビューの指摘への対応。 - トークンは CONNECT で使う(2 度目の CONNECT は 401)。RDCleanPath の proxy_auth は、 CONNECT で使ったトークンと同じ文字列だけを通す(ここではもう使わない) - 1 つの QUIC 接続にセッションは 1 つ(2 つ目は 429)。中継は最初の双方向 stream だけ - 時間切れ: 握手の後とセッションの後、10 秒のうちに正しい CONNECT が来なければ接続を閉じる。 CONNECT の後 10 秒のうちに中継の stream が来なければセッションを閉じる。 RDCleanPath の要求は 10 秒で揃わなければ 408 を返して閉じる(/ws も同じ) - 上限: QUIC の接続は全部で 64、確かめる前は 16、同じ IP から確かめる前は 4(ConnectionLimits) - WebTransportServer の SetCertificate と Dispose を重ねない - WebTransportByteStream.DisposeAsync は何度呼んでもよい - クライアント: WebSocket に移るときはトークンを取り直す(CONNECT の後で待ち時間が切れることがあるため) - トークンの扱いを RelayTokens にまとめる - 文書: WebTransport の認証(Origin と使い捨てのトークン)、URL のトークンはログに残らないこと Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M2BadDnB3uH3FDGjaPMP4J
|
Claude finished @5ym's task in 18s —— View job レビュー結果(最新コミット
|
ブラウザと mado の間を、WebTransport(HTTP/3 over QUIC、UDP)でもつなげるようにする。輻輳制御は BBR。UDP が通らなければ、今の WebSocket に戻る。
サーバー
server/Quic/)。HTTP/3・QPACK(動的表なし、Huffman)・WebTransport(draft-02 と draft-07 の設定)を自前で書いたwebtransportの設定。falseで止める)。証明書は ACME のものを使い、更新したら作り直す/wt?token=のトークンを CONNECT で確かめ、RDCleanPath の proxy_auth も同じトークンで使い切る。WebTransport には cookie が付かないが、トークンは cookie で守られた/api/tokenでしか出さないので、/wsより弱くはならない/wsと同じ(Relay.csをIRelayChannelで WebSocket とバイト列の両方に)。受信が溜まったら止めるmsquic.dllを mado.exe の隣に入れ、ファイアウォールで UDP 443 を開けるブラウザ
/api/sessionのwtがあれば WebTransport を先に試し、1.5 秒で ready にならなければ WebSocket に移る。診断に「中継: WebTransport / WebSocket」試験
🤖 Generated with Claude Code
https://claude.ai/code/session_01M2BadDnB3uH3FDGjaPMP4J