nest: Docker側に接続してみるテスト(Preflightメッセージの実装)

とりあえず動作するDockerのイメージはできたので、
$ docker run -v `pwd`/vol:/state \
-e FNEST_STATEDIR=/state \
-e FNEST_EXTERNAL_IP4=172.28.255.212 \
-e FNEST_ENABLE_COTURN=1 \
-p 3478:3478 -p 3040:3040 fnest node /fnest/nodeserv.mjs
みたいな感じで起動できるようになった。が、今のプロトコルだとICEを始めた後に初めてメッセージの交換をするのでTURNサーバー等のアドレスを渡すチャンスがない。
TURNサーバーのアドレスをデバイス側から渡す方法は2つ考えられて、
- Devicekeyに格納する。現在、デバイスキーには通信先のHTTPサーバーのアドレスと、署名用の公開鍵を入れている。これにTURNサーバーのアドレスも含めれば目的は達成できる。
- WebRTC接続を行う前にPreflight(事前のメッセージ交換)を行う。
携帯端末の場合、Devicekeyの受け渡しにはQRコードを使うのでできればDevicekeyは短い方が好ましい。というわけで、今回はプロトコルの流れをガッツリ変更してpreflightを実装することにした。
(また、preflightしないとTURNサーバーのID/Passwordを動的生成にできないという問題もある)

node-datachannel
がTURN TCPに対応していない
2025-06-21 04:10:21.207 WARN [1] [rtc::impl::IceTransport::addIceServer@159] TURN transports TCP and TLS are not supported with libjuice
マジかよ。。まぁローカルでUDP transportするしか無いかな。。
というかAPI documentにはTCPのサンプル載ってるじゃん。。
TURN Server Example (TCP) : turn:USERNAME:PASSWORD@TURN_IP_OR_ADDRESS:PORT?transport=tcp

そもそもFirefoxはlocalhostをICE candidateにできない
えぇ...

疎通しない
とりあえずFirefoxは置いておいて、Chromeで試しても疎通しない。Chromeからは正常にTCPのTURNリクエストを投げているので、libdatachannel(のlibjuice)が正常にUDP側のTURNを使えているかが問題になる。
docker run -v `pwd`/vol:/state -e FNEST_STATEDIR=/state \
-e FNEST_EXTERNAL_IP4=172.28.255.212 -e FNEST_ENABLE_COTURN=1 \
-p 3478:3478 -p 3040:3040 \
--cap-add=NET_ADMIN --cap-add=NET_RAW fnest node /fnest/nodeserv.mjs
--cap-add=NET_ADMIN --cap-add=NET_RAW
して中でtcpdumpできるようにして、
tcpdump -i any -w /state/dump.pcap
でダンプを取る。
2025-06-21 08:33:56.577 INFO [44] [rtc::impl::IceTransport::LogCallback@390] juice: Got STUN mapped address 127.0.0.1:59642 from TURN server
2025-06-21 08:33:56.578 INFO [44] [rtc::impl::IceTransport::LogCallback@390] juice: Allocated TURN relayed address 10.0.2.100:64831
2025-06-21 08:33:56.578 INFO [44] [rtc::impl::IceTransport::LogCallback@390] juice: Candidate gathering done
とりあえず、Binding requestがUDPで飛んでいることは確認できた。
... ややこしいので一旦片持ち構成にするか。。つまり、Dockerの外はTURNを使い、Dockerの内部ではTURNを使わないように構成してみる。

片持ち構成では正常に疎通した
とりあえずコレで良いか。。一旦 127.0.0.1
をやってみているのがわかる。

getUserMedia
するとWebRTCの挙動がかわる
Firefoxは → https://zenn.dev/link/comments/b8039b7f043357
ややこしいのでこういうのはデバッグ画面にも出しといて欲しい。。つまりFirefoxの場合はダミーの getUserMedia
をするための機能も必要って事になるな。。