Closed12

WebTransport のサンプルをローカル環境で動かす in 2022/04

やまゆやまゆ

噂によると、 WSL2 とホスト機の間で UDP 通信が出来ないらしいので再現するか確認中(ネットワークはうといので原因とか理由とかはよくわかってない)

やまゆやまゆ
$ python3 webtransport_server.py localhost.pem localhost-key.pem
DEBUG:asyncio:Using selector: EpollSelector
INFO:webtransport_server:Listening on https://::1:4433

WSL2 上でサーバを起動した場合、接続を試みても何もログが追加されないのを確認。

やまゆやまゆ
> python3 .\server.py .\localhost.pem .\localhost-key.pem
server.py:246: DeprecationWarning: There is no current event loop
  loop = asyncio.get_event_loop()
DEBUG:asyncio:Using proactor: IocpProactor
INFO:webtransport_server:Listening on https://::1:4433
Listening on https://::1:4433

PowerShell で起動するとそもそもワーニングが出るので、根本的に何か違ってそう(ソースコードは同じ)

やまゆやまゆ

https://scoop.sh/

PowerShell で動かしている python は scoop を使ってインストールしている。ライブラリをコンパイルするのに、多分 Visual C++ のなにがしか必要(メモり忘れた)

やまゆやまゆ

クライアントのページから接続しようとすると、下記エラーが出る。


Initialize protocol
DEBUG:quic:[bb5a734fc689848c] Network path ('::1', 60322, 0, 0) discovered
DEBUG:quic:[bb5a734fc689848c] QuicConnectionState.FIRSTFLIGHT -> QuicConnectionState.CONNECTED
INFO:quic:[bb5a734fc689848c] Duplicate CRYPTO data received for epoch Epoch.INITIAL      
INFO:quic:[bb5a734fc689848c] Duplicate CRYPTO data received for epoch Epoch.INITIAL      
INFO:quic:[bb5a734fc689848c] Duplicate CRYPTO data received for epoch Epoch.INITIAL      
INFO:quic:[bb5a734fc689848c] Duplicate CRYPTO data received for epoch Epoch.INITIAL      
INFO:quic:[bb5a734fc689848c] Duplicate CRYPTO data received for epoch Epoch.INITIAL      
INFO:quic:[bb5a734fc689848c] Duplicate CRYPTO data received for epoch Epoch.INITIAL      
INFO:quic:[bb5a734fc689848c] Duplicate CRYPTO data received for epoch Epoch.INITIAL      
DEBUG:quic:[bb5a734fc689848c] TLS State.SERVER_EXPECT_CLIENT_HELLO -> State.SERVER_EXPECT_FINISHED
ProtocolNegotiated(alpn_protocol='h3')
DEBUG:quic:[bb5a734fc689848c] Discarding epoch Epoch.INITIAL
DEBUG:quic:[bb5a734fc689848c] Network path ('::1', 60322, 0, 0) validated by handshake   
INFO:quic:[bb5a734fc689848c] Connection close received (code 0x12E, reason 199:TLS handshake failure (ENCRYPTION_HANDSHAKE) 46: certificate unknown)
DEBUG:quic:[bb5a734fc689848c] QuicConnectionState.CONNECTED -> QuicConnectionState.DRAINING
DEBUG:quic:[bb5a734fc689848c] Discarding epoch Epoch.HANDSHAKE
DEBUG:quic:[bb5a734fc689848c] Discarding epoch Epoch.ONE_RTT
DEBUG:quic:[bb5a734fc689848c] QuicConnectionState.DRAINING -> QuicConnectionState.TERMINATED
ConnectionTerminated(error_code=302, frame_type=0, reason_phrase='199:TLS handshake failure (ENCRYPTION_HANDSHAKE) 46: certificate unknown')

HELLO は届いているが、証明書がわからんとなる。

やまゆやまゆ

Google Chrome のショートカットを作成して、プロパティから「リンク先」の所を編集。

"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --origin-to-force-quic-on=localhost:4433 https://googlechrome.github.io/samples/webtransport/client.html

--origin-to-force-quic-on=localhost:4433 これは Chrome の挙動として、デフォルトでは HTTP/2 または 1.1 で接続を開始し、 Alt-Svc を見て HTTP/3 に繋ぎなおすというのが現在の状態なので、指定したサーバに接続する時は強制的に QUIC でつないでもらうためのオプションの様子。

やまゆやまゆ

他の Chrome ウィンドウを消して上のショートカットから起動。

connect ボタンを押してこうなったら接続が確立された証拠。

やまゆやまゆ
Initialize protocol
DEBUG:quic:[401650361d6f8d6a] Network path ('::1', 53657, 0, 0) discovered
DEBUG:quic:[401650361d6f8d6a] QuicConnectionState.FIRSTFLIGHT -> QuicConnectionState.CONNECTED
INFO:quic:[401650361d6f8d6a] Duplicate CRYPTO data received for epoch Epoch.INITIAL      
INFO:quic:[401650361d6f8d6a] Duplicate CRYPTO data received for epoch Epoch.INITIAL      
INFO:quic:[401650361d6f8d6a] Duplicate CRYPTO data received for epoch Epoch.INITIAL      
INFO:quic:[401650361d6f8d6a] Duplicate CRYPTO data received for epoch Epoch.INITIAL      
INFO:quic:[401650361d6f8d6a] Duplicate CRYPTO data received for epoch Epoch.INITIAL      
DEBUG:quic:[401650361d6f8d6a] TLS State.SERVER_EXPECT_CLIENT_HELLO -> State.SERVER_EXPECT_FINISHED
ProtocolNegotiated(alpn_protocol='h3')
DEBUG:quic:[401650361d6f8d6a] Discarding epoch Epoch.INITIAL
DEBUG:quic:[401650361d6f8d6a] Network path ('::1', 53657, 0, 0) validated by handshake   
DEBUG:quic:[401650361d6f8d6a] TLS State.SERVER_EXPECT_FINISHED -> State.SERVER_POST_HANDSHAKE
DEBUG:quic:[401650361d6f8d6a] Discarding epoch Epoch.HANDSHAKE
INFO:quic:[401650361d6f8d6a] ALPN negotiated protocol h3
HandshakeCompleted(alpn_protocol='h3', early_data_accepted=False, session_resumed=False) 
DEBUG:quic:[401650361d6f8d6a] Stream 2 created by peer
ConnectionIdIssued(connection_id=b'\xb1\xaa 5.\xee\xe7w')
StreamDataReceived(data=b"...", end_stream=False, stream_id=2)
DEBUG:quic:[401650361d6f8d6a] Stream 10 created by peer
DEBUG:quic:[401650361d6f8d6a] Stream 0 created by peer
StreamDataReceived(data=b'...', end_stream=False, stream_id=10)
StreamDataReceived(data=b'...', end_stream=False, stream_id=0)
DEBUG:quic:[325826080f47f0fa] Discarding epoch Epoch.ONE_RTT
DEBUG:quic:[325826080f47f0fa] QuicConnectionState.CONNECTED -> QuicConnectionState.TERMINATED
ConnectionTerminated(error_code=<QuicErrorCode.INTERNAL_ERROR: 1>, frame_type=<QuicFrameType.PADDING: 0>, reason_phrase='Idle timeout')
DEBUG:quic:[757b4b5967f86243] Discarding epoch Epoch.ONE_RTT
DEBUG:quic:[757b4b5967f86243] QuicConnectionState.CONNECTED -> QuicConnectionState.TERMINATED
ConnectionTerminated(error_code=<QuicErrorCode.INTERNAL_ERROR: 1>, frame_type=<QuicFrameType.PADDING: 0>, reason_phrase='Idle timeout')

接続成功時のサーバ側のログはこんな感じ。

やまゆやまゆ

ということで

  • WSL2 で WebTransport サーバを立てることは(まだ)出来ない(話によると WSL 2 上で UDP サーバ自体立てれないらしい)
  • このサーバサンプルコードでは --origin-to-force-quic-on=localhost:4433 を指定して起動しないといけないので、エンドユーザーに使ってもらうのは結構厳しい
  • 証明書は mkcert で作った奴なら、 https://github.com/aiortc/aioquic/tree/main/examples にある --ignore-certificate-errors-spki-list=BSQJ0jkQ7wwhR7KvPZ+DSNk2XTZ/MS6xCbo9qu++VdQ= オプションをつけなくてもいい(無効な証明書をスルーするオプション)
  • サンプルコード自体は動作することが分かった

サーバサイドのコードで、 HTTP/2, 1.1, 0.9? もリッスンできるようにして、手動でプロトコルを HTTP/3 に付け替えるような実装が出来れば、起動オプションを指定しなくてもつながるようになるかもしれない。しかし aioquic の実装はようわからんので、もうちょっと深追いする必要がありそう。

このスクラップは2022/04/13にクローズされました