「Proxying Listener UDP in HTTP」という提案仕様がIETFに提出されている。
これは、HTTP/3のCONNECT-UDPを介してWebRTC通信を可能にするための提案である。まだ議論の呼び水と鳴るdraftであるため、ここから仕様は大きく変わると思うが、ざっと眺めていく。
HTTP/3のCONNECT-UDP
本論に入る前に、まずCONNECT-UDPについて説明します。
IETFではすでに「Proxying UDP in HTTP」という仕様が議論されている。これが通称CONNECT-UDPと呼ばれているものである。実は、AppleのPrivate Relayでもすでに使用されているものである。
これは、Proxyと確立したHTTP/3コネクションをトンネリングしてUDPパケットを中継させる機能です。
この通信は第三者からはただのHTTP/3通信としてか観測できないという特徴があります。確立した通信路を通して自由なUDPパケットを中継させることが出来ます。
このCONNECT-UDPでは、H3-Datagramという仕様でUDPパケットを扱います。詳しくは以前書いた記事を参照ください。
asnokaze.hatenablog.com
Proxying Listener UDP in HTTP
通常のCONNECT-UDPではProxyを中継して通信する相手は1つでしたが、WebRTCはSTUNと通信した上で、通信相手のブラウザからもパケットを受け付ける必要があります。そこで、既存のCONNECT-UDPの拡張機能として「Proxying Listener UDP in HTTP」が登場しました。
(提案者はユースケースとしてWebRTCをあげていますが、それに限定されるものでは有りません)
主な通信の流れ
上記の図に沿って通信の流れを説明します。
CONNECTリクエストとレスポンス
まずは、ブラウザAと中継サーバとでHTTP/3のコネクションを確立したのち、中継の要望を出す。
通常のCONNECT-UDPのように、拡張CONNECTメソッドを用いる(:protocolにconnect-udpが指定される)。
connect-udp-listenヘッダを付けることで、Proxying Listener UDP in HTTP の通信であることを明示する。ヘッダの値は使用するH3-DatagramのContext-IDを指定する。
HEADERS :method = CONNECT :protocol = connect-udp :scheme = https :path = /.well-known/masque/udp/*/*/ :authority = proxy.example.org connect-udp-listen = 2 capsule-protocol = ?1 |<< 中継サーバは、200番のレスポンスを返し、CONNECTリクエストの受け入れる意志を示す。 >|| HEADERS :status = 200 capsule-protocol = ?1
STUNサーバへのUDPパケットの中継
ブラウザA側は、H3-DatagramでUDPパケットを中継サーバに送信する。このとき、中継先となるターゲットのIPとポートを付加して送る。
DATAGRAM Quarter Stream ID = 11 Context ID = 2 IP Version = 4 IP Address = 192.0.2.42 UDP Port = 1234 UDP Payload = Encapsulated UDP Payload
中継サーバは、指定されたIP宛にUDPパケットを中継する。
中継サーバはSTUNサーバから応答となるUDPパケットを受け取ると、ブラウザA側に中継する。このときもH3-DatagramでUDPパケットを中継することになる。
このときのH3-Datagramでは、どこからきたUDPパケットなのかが付加されている。
DATAGRAM Quarter Stream ID = 11 Context ID = 2 IP Version = 4 IP Address = 192.0.2.42 UDP Port = 1234 UDP Payload = Encapsulated UDP Payload