2015-12-14 40 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鏈路本地地址相對應的主機候選。」

相關問題