Node.js - 无法将 udp6 套接字绑定到特定地址
Node.js - Can't bind a udp6 socket to a specific address
来自 Node,此可用地址列表:
var os = require('os');
os.networkInterfaces()
打印:
{ lo0:
[ { address: '::1',
netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
family: 'IPv6',
mac: '00:00:00:00:00:00',
scopeid: 0,
internal: true },
{ address: '127.0.0.1',
netmask: '255.0.0.0',
family: 'IPv4',
mac: '00:00:00:00:00:00',
internal: true },
{ address: 'fe80::1',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: '00:00:00:00:00:00',
scopeid: 1,
internal: true } ],
en0:
[ { address: 'fe80::2acf:e9ff:fe1f:3939',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: '28:cf:e9:1f:39:39',
scopeid: 4,
internal: false },
{ address: '10.0.0.8',
netmask: '255.255.255.0',
family: 'IPv4',
mac: '28:cf:e9:1f:39:39',
internal: false } ],
awdl0:
[ { address: 'fe80::e46a:6cff:fe68:a76a',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: 'e6:6a:6c:68:a7:6a',
scopeid: 8,
internal: false } ] }
但是如果我尝试创建特定的 udp 套接字,我可以绑定 udp4 但不能绑定 udp6 套接字。
var dgram = require('dgram');
var udp4 = dgram.createSocket('udp4');
udp4.bind(null, '10.0.0.8');
udp4.address()
打印
{ address: '10.0.0.8', family: 'IPv4', port: 65061 }
但是
var udp6 = dgram.createSocket('udp6');
udp6.bind(null, 'fe80::e46a:6cff:fe68:a76a');
投掷:
Error: bind EADDRNOTAVAIL fe80::e46a:6cff:fe68:a76a
at Object.exports._errnoException (util.js:874:11)
at exports._exceptionWithHostPort (util.js:897:20)
at dgram.js:213:18
at doNTCallback3 (node.js:452:9)
at process._tickDomainCallback (node.js:399:17)
同样的事情发生在地址 'fe80::2acf:e9ff:fe1f:3939' 上。注意,我在 Nodes 的 REPL 中 运行 这些语句,所以当我尝试检查地址时绑定已经完成。
我能做到
udp6.bind()
udp6.address()
打印
{ address: '::', family: 'IPv6', port: 51897 }
但这并没有告诉我它绑定到哪个地址(我需要它来通知其他同行)。
为什么我可以绑定到特定的 IPv4 地址而不是 IPv6 地址?这似乎不一致。这可能是运行时中的错误吗? Relevant bug in Node issue tracker.
我需要具有特定地址的 udp 套接字,这些地址反映了 os.networkInterfaces 的可用内容,因为我是 building an ICE agent。
我正在使用 Node v4.2.2。
好的,看来我需要 Link-local addresses 的背景知识。
要点是,对于 IPv4,您通常使用 DHCP 等协议来分配本地 IP 地址。如果你不这样做,你可以选择一个并希望你不会与网络上的其他主机发生冲突。这样的地址称为“Link 本地地址”。这些在 IPv4 中是可选的,现在在 IPv6 中是必需的。 Link 本地地址始终具有前缀 fe80:: IPv6 地址前缀。
在 Node.js 中,您可以监听 link 本地地址,但您必须在地址字符串后加上接口名称,例如:
udp6.bind(null, 'fe80::e46a:6cff:fe68:a76a%en0');
可以从 运行 ifconfig.
中找到具体的字符串
那么,同网的其他peer可以联系你,但是也必须指定同网的网络设备的接口。例如
nc6 -u fe80::2acf:e9ff:fe1f:3939%wlp3s0 65022
其中wlp3s0是朋友无线网卡的接口。
如果他们插入以太网并连接到同一网络,则他们可以通过以太网接口发送,但除非它连接到同一本地网络。
此外,我发布的 IP 地址表明我的家庭路由器没有分配 IPv6 地址。在工作中,我得到了一个 IPv6 地址,所以我可以毫无问题地监听一个非 fe80 前缀的地址。在工作中,os.networkInterfaces() 看起来更像是:
en0:
[ { address: 'fe80::2acf:e9ff:fe1f:3939',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: '28:cf:e9:1f:39:39',
scopeid: 4,
internal: false },
{ address: '10.252.28.131',
netmask: '255.255.248.0',
family: 'IPv4',
mac: '28:cf:e9:1f:39:39',
internal: false },
{ address: '2620:101:80fc:224:2acf:e9ff:fe1f:3939',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: '28:cf:e9:1f:39:39',
scopeid: 0,
internal: false },
{ address: '2620:101:80fc:224:4d78:1087:39a2:65d7',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: '28:cf:e9:1f:39:39',
scopeid: 0,
internal: false } ],
所以我可以成功绑定到任何 2620: 前缀地址。
最后,对于我的 ICE 代理,updated draft spec 表示“不得收集对应于 IPv6 link 本地地址的候选主机。”
来自 Node,此可用地址列表:
var os = require('os');
os.networkInterfaces()
打印:
{ lo0:
[ { address: '::1',
netmask: 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
family: 'IPv6',
mac: '00:00:00:00:00:00',
scopeid: 0,
internal: true },
{ address: '127.0.0.1',
netmask: '255.0.0.0',
family: 'IPv4',
mac: '00:00:00:00:00:00',
internal: true },
{ address: 'fe80::1',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: '00:00:00:00:00:00',
scopeid: 1,
internal: true } ],
en0:
[ { address: 'fe80::2acf:e9ff:fe1f:3939',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: '28:cf:e9:1f:39:39',
scopeid: 4,
internal: false },
{ address: '10.0.0.8',
netmask: '255.255.255.0',
family: 'IPv4',
mac: '28:cf:e9:1f:39:39',
internal: false } ],
awdl0:
[ { address: 'fe80::e46a:6cff:fe68:a76a',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: 'e6:6a:6c:68:a7:6a',
scopeid: 8,
internal: false } ] }
但是如果我尝试创建特定的 udp 套接字,我可以绑定 udp4 但不能绑定 udp6 套接字。
var dgram = require('dgram');
var udp4 = dgram.createSocket('udp4');
udp4.bind(null, '10.0.0.8');
udp4.address()
打印
{ address: '10.0.0.8', family: 'IPv4', port: 65061 }
但是
var udp6 = dgram.createSocket('udp6');
udp6.bind(null, 'fe80::e46a:6cff:fe68:a76a');
投掷:
Error: bind EADDRNOTAVAIL fe80::e46a:6cff:fe68:a76a
at Object.exports._errnoException (util.js:874:11)
at exports._exceptionWithHostPort (util.js:897:20)
at dgram.js:213:18
at doNTCallback3 (node.js:452:9)
at process._tickDomainCallback (node.js:399:17)
同样的事情发生在地址 'fe80::2acf:e9ff:fe1f:3939' 上。注意,我在 Nodes 的 REPL 中 运行 这些语句,所以当我尝试检查地址时绑定已经完成。
我能做到
udp6.bind()
udp6.address()
打印
{ address: '::', family: 'IPv6', port: 51897 }
但这并没有告诉我它绑定到哪个地址(我需要它来通知其他同行)。
为什么我可以绑定到特定的 IPv4 地址而不是 IPv6 地址?这似乎不一致。这可能是运行时中的错误吗? Relevant bug in Node issue tracker.
我需要具有特定地址的 udp 套接字,这些地址反映了 os.networkInterfaces 的可用内容,因为我是 building an ICE agent。
我正在使用 Node v4.2.2。
好的,看来我需要 Link-local addresses 的背景知识。
要点是,对于 IPv4,您通常使用 DHCP 等协议来分配本地 IP 地址。如果你不这样做,你可以选择一个并希望你不会与网络上的其他主机发生冲突。这样的地址称为“Link 本地地址”。这些在 IPv4 中是可选的,现在在 IPv6 中是必需的。 Link 本地地址始终具有前缀 fe80:: IPv6 地址前缀。
在 Node.js 中,您可以监听 link 本地地址,但您必须在地址字符串后加上接口名称,例如:
udp6.bind(null, 'fe80::e46a:6cff:fe68:a76a%en0');
可以从 运行 ifconfig.
中找到具体的字符串那么,同网的其他peer可以联系你,但是也必须指定同网的网络设备的接口。例如
nc6 -u fe80::2acf:e9ff:fe1f:3939%wlp3s0 65022
其中wlp3s0是朋友无线网卡的接口。
如果他们插入以太网并连接到同一网络,则他们可以通过以太网接口发送,但除非它连接到同一本地网络。
此外,我发布的 IP 地址表明我的家庭路由器没有分配 IPv6 地址。在工作中,我得到了一个 IPv6 地址,所以我可以毫无问题地监听一个非 fe80 前缀的地址。在工作中,os.networkInterfaces() 看起来更像是:
en0:
[ { address: 'fe80::2acf:e9ff:fe1f:3939',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: '28:cf:e9:1f:39:39',
scopeid: 4,
internal: false },
{ address: '10.252.28.131',
netmask: '255.255.248.0',
family: 'IPv4',
mac: '28:cf:e9:1f:39:39',
internal: false },
{ address: '2620:101:80fc:224:2acf:e9ff:fe1f:3939',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: '28:cf:e9:1f:39:39',
scopeid: 0,
internal: false },
{ address: '2620:101:80fc:224:4d78:1087:39a2:65d7',
netmask: 'ffff:ffff:ffff:ffff::',
family: 'IPv6',
mac: '28:cf:e9:1f:39:39',
scopeid: 0,
internal: false } ],
所以我可以成功绑定到任何 2620: 前缀地址。
最后,对于我的 ICE 代理,updated draft spec 表示“不得收集对应于 IPv6 link 本地地址的候选主机。”