2015-12-14 41 views
0

从节点,可用的地址列表:Node.js的 - 无法在UDP6套接字绑定到特定的地址

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 ”。请注意,我在节点的REPL中逐一运行这些语句,因此在尝试检查地址时绑定已完成。

我可以做

udp6.bind() 
udp6.address() 

它打印

{ address: '::', family: 'IPv6', port: 51897 } 

,但并没有告诉我这解决它绑定到(我以告知其他同行NEED)。

为什么我可以绑定到特定的IPv4地址而不是IPv6地址?这似乎不一致。这可能是运行时错误吗? Relevant bug in Node issue tracker.

我需要具有特定地址的udp套接字,这些地址反映了os.networkInterfaces中可用的地址,因为我是buildingICE agent

我正在使用Node v4.2.2。

回答

1

好吧,所以看起来我需要在Link-local addresses的背景。

要点在于,使用IPv4时,通常使用类似DHCP的协议来分配本地IP地址。如果你不这样做,你可以选择一个,并希望你不要与网络上的其他主机相冲突。这样的地址被称为“链路本地地址”。这些在IPv4中是可选的,现在在IPv6中是必需的。链路本地地址始终具有用于IPv6地址的前缀fe80 ::前缀。

在Node.js的,你可以听的链路本地地址,但你必须后缀与接口的名称地址字符串,例如:

udp6.bind(null, 'fe80::e46a:6cff:fe68:a76a%en0'); 

特别是字符串可以从运行的ifconfig找到。

然后,如果它们位于同一网络上,其他对等方可以与您联系,但他们也必须在同一网络上指定网络设备的接口。恩。

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链路本地地址相对应的主机候选。”

相关问题