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

Kir*_*met 31 javascript networking ip-address node.js

我最近将我的路由器更改为谷歌为Google Fiber提供的路由器(是的!)现在我注意到当我在本地服务器上开发时检查request.connection.remoteAddress时所看到的内容发生了变化.之前,我曾经看过这个:

request.connection.remoteAddress; // 192.168.1.10
Run Code Online (Sandbox Code Playgroud)

现在我看到了这个:

request.connection.remoteAddress; // ::ffff:192.168.1.10
Run Code Online (Sandbox Code Playgroud)
  1. 谁能解释一下发生了什么?
  2. 我的Node服务器是否在侦听IPv6地址?
  3. ::ffff:192.168.1.10实际上是一个IPv6地址或者是IPv4地址?
  4. 是判断remoteAddress是否为IPv6以检查字符串是否包含的最简单方法::
  5. 在数据库中存储IPv4地址时,我习惯使用类似的东西INET_ATON将它们变成大整数.我是否应该放弃这个并将所有远程地址存储为长度为45个字符的字符串(IPv6地址字符串的最大长度)

Wla*_*ant 43

我的Node服务器是否在侦听IPv6地址?

是.您的服务器正在侦听IPv6连接,并且IPV6_V6ONLY未设置标志,结果是IPv4连接由同一套接字处理.您可以在此问题中阅读有关此标志的更多信息.

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

::ffff:192.168.1.10实际上是一个IPv6地址或者是IPv4地址?

都.IPv6地址可以嵌入IPv4地址 - 这是这些嵌入地址之一.请参阅IPv4映射的IPv6地址.

是判断remoteAddress是否为IPv6以检查字符串是否包含的最简单方法::

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个字符的字符串(IPv6地址字符串的最大长度)

IPv6地址是一个128位的数字 - 即使你可以将它存储为数字(例如BIGINTMySQL中的两个数字),这种方法是否真的有意义是值得怀疑的.我能想到你需要使用数字的唯一场景是评估子网掩码,其他一切字符串就足够了,更容易处理.


DuB*_*sch 15

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
}
Run Code Online (Sandbox Code Playgroud)