request.connection.remoteAddress现在在node.js中的前缀为:: ffff

我最近把路由器改成了Google为Google Fiber(yay!)提供的路由器,现在我注意到当我在本地服务器上开发时检查request.connection.remoteAddress时所看到的变化。 之前,我曾经看到这个:

request.connection.remoteAddress; // 192.168.1.10 

现在我看到了这个:

 request.connection.remoteAddress; // ::ffff:192.168.1.10 
  1. 任何人都可以解释发生了什么事?
  2. 我的节点服务器是否正在侦听IPv6地址?
  3. Is ::ffff:192.168.1.10实际上是IPv6地址还是IPv4地址?
  4. 最简单的方法是判断remoteAddress是否是IPv6来检查string是否包含::
  5. 当在数据库中存储IPv4地址时,我曾经使用类似INET_ATON东西将它们变成大整数。 我应该放弃这一点,只将所有的远程地址存储为长度为45个字符的string(IPv6地址string的最大长度)

我的节点服务器是否正在侦听IPv6地址?

是。 您的服务器正在侦听IPv6连接,并且IPV6_V6ONLY标志未设置为IPv4连接由同一个套接字处理的结果。 你可以在这个问题上多读一些这个标志。

IPv6连接是否可能(可以路由到您的服务器)在这种情况下是无关紧要的 – 重要的是,IPv4连接由侦听IPv6连接的套接字接收。

Is ::ffff:192.168.1.10实际上是IPv6地址还是IPv4地址?

都。 IPv6地址可以embeddedIPv4地址 – 这是这些embedded式地址之一。 请参阅IPv4映射的IPv6地址 。

最简单的方法是判断remoteAddress是否是IPv6来检查string是否包含::

一个IPv6地址不一定包含:: ,它只是一个简短的表示,表示一些零。 ::ffff:192.168.1.10等于0:0:0:0:0:ffff:192.168.1.100:0:0:0:0:ffff:c0a8:010a (请参阅IPv6地址显示 )。 所以为了区分IPv6和IPv4地址,你应该简单地检查一下冒号。

当在数据库中存储IPv4地址时,我曾经使用类似INET_ATON的东西将它们变成大整数。 我应该放弃这一点,只将所有的远程地址存储为长度为45个字符的string(IPv6地址string的最大长度)

一个IPv6地址是一个128位的数字 – 即使你可以把它作为一个数字来存储(例如,在MySQL中是两个BIGINT数字),这个方法是否真的有意义还是值得怀疑的。 唯一的情况是我可以想到你需要使用数字的地方是评估子网掩码,对于其他的一个string是足够的,更容易处理。

re:#4,像ipaddr.js这样的库运行良好,例如:

 var ipString = request.connection.remoteAddress; if (ipaddr.IPv4.isValid(ipString)) { // ipString is IPv4 } else if (ipaddr.IPv6.isValid(ipString)) { var ip = ipaddr.IPv6.parse(ipString); if (ip.isIPv4MappedAddress()) { // ip.toIPv4Address().toString() is IPv4 } else { // ipString is IPv6 } } else { // ipString is invalid }