初投稿です。
経緯
Node.jsでUDP双方向通信プログラムを書いている上で何故だか急にIPv6対応したくなってきました。
しかし、IPv4の方が未だ多く使用されているため、IPv4を捨てることもできず、IPv6と両方対応できるソケットはないか探してみました。
TL; DR
UDP
まずソケットをudp4からudp6にします。
const socket = dgram.createSocket("udp4");
const socket = dgram.createSocket("udp6");
そして、待受アドレスを0.0.0.0
から::
に変更します。
socket.bind(PORT, "0.0.0.0");
socket.bind(PORT, "::");
これだけです。
こうすることでIPv4・IPv6両対応のソケットを立てることができます。
TCP
プログラムの書き換えは必要ありません。
接続先アドレスをIPv6に指定するだけで勝手にIPv6で接続してくれます。
デュアルスタックサポート
全く知らなかったのですが、UDPのnet
モジュールのserver.listen
、dgram
モジュールのdgram.createSocket
のオプションにはipv6Only
というオプションがあり、true
にするとIPv6のみに対応したソケットができるそうです。
そもそも、IPv6には「デュアルスタックサポート」というものがついており、IPv4とIPv6アドレスを同時に持ち、IPv4とIPv6を共存させることができる機能だそうです。知らなかった
注意点
当たり前ですが、IPv6対応ルーター等でなければIPv6は使用できません。
その場合こんなエラーが出ます。
/home/fami/udp_client.js:11
if (err) throw err;
^
Error: send EINVAL xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:50002
at doSend (node:dgram:714:16)
at defaultTriggerAsyncIdScope (node:internal/async_hooks:433:18)
at afterDns (node:dgram:660:5)
at processTicksAndRejections (node:internal/process/task_queues:84:21) {
errno: -22,
code: 'EINVAL',
syscall: 'send',
address: 'xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx',
port: 50002
}
製品で使用するときはIPv6を使用できるか確認し、使えるならIPv6で接続し、使えないのであればIPv4で接続する、という処理を挟めばいいと思いました。
最後に
udp4
とかudp6
とか紛らわしい名前つけないでください