javascript request.connection.remoteAddress 现在在 node.js 中以 ::ffff 为前缀
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24896386/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
request.connection.remoteAddress Now Prefixed in ::ffff in node.js
提问by Kirk Ouimet
I recently changed my router over to one provided by Google for Google Fiber (yay!) and now I am noticing a change in what I am seeing when I inspect request.connection.remoteAddress while I develop on my local server. Before, I used to see this:
我最近将我的路由器改成了 Google 为 Google Fiber 提供的路由器(是的!),现在我注意到我在本地服务器上开发时检查 request.connection.remoteAddress 时看到的内容发生了变化。之前,我经常看到这个:
request.connection.remoteAddress; // 192.168.1.10
Now I am seeing this:
现在我看到了这个:
request.connection.remoteAddress; // ::ffff:192.168.1.10
- Can anyone explain what is going on?
- Is my Node server listening to IPv6 addresses?
- Is
::ffff:192.168.1.10
actually an IPv6 address or is it an IPv4 address? - Is the easiest way to tell if a remoteAddress is IPv6 to check if the string contains
::
? - When storing IPv4 addresses in the database I used to use something like
INET_ATON
to change them into large integers. Should I abandon this and just store all remote addresses as strings that can be 45 characters long (maximum length of an IPv6 address string)
- 谁能解释一下这是怎么回事?
- 我的 Node 服务器是否正在侦听 IPv6 地址?
- 是
::ffff:192.168.1.10
实际上是一个IPv6地址或者是IPv4地址? - 是判断 remoteAddress 是否为 IPv6 以检查字符串是否包含的最简单方法
::
? - 在数据库中存储 IPv4 地址时,我曾经使用类似的
INET_ATON
方法将它们更改为大整数。我是否应该放弃这一点,将所有远程地址存储为长度为 45 个字符的字符串(IPv6 地址字符串的最大长度)
回答by Wladimir Palant
Is my Node server listening to IPv6 addresses?
我的 Node 服务器是否正在侦听 IPv6 地址?
Yes. Your server is listening to IPv6 connections and the IPV6_V6ONLY
flag isn't set with the result that IPv4 connections are processed by the same socket. You can read some more about this flag in this question.
是的。您的服务器正在侦听 IPv6 连接,并且IPV6_V6ONLY
未设置该标志,结果是 IPv4 连接由同一个套接字处理。您可以在此问题中阅读有关此标志的更多信息。
Whether IPv6 connections are possible (can be routed to your server) is irrelevant in that case - the important thing is that IPv4 connections are received by a socket listening to IPv6 connections.
在这种情况下,IPv6 连接是否可能(可以路由到您的服务器)无关紧要 - 重要的是 IPv4 连接是由侦听 IPv6 连接的套接字接收的。
Is
::ffff:192.168.1.10
actually an IPv6 address or is it an IPv4 address?
是
::ffff:192.168.1.10
实际上是一个IPv6地址或者是IPv4地址?
Both. IPv6 addresses can embed IPv4 addresses - and this is one of these embedded addresses. See IPv4-mapped IPv6 addresses.
两个都。IPv6 地址可以嵌入 IPv4 地址 - 这是这些嵌入地址之一。请参阅IPv4 映射的 IPv6 地址。
Is the easiest way to tell if a remoteAddress is IPv6 to check if the string contains
::
?
是判断 remoteAddress 是否为 IPv6 以检查字符串是否包含的最简单方法
::
?
An IPv6 address doesn't necessarily contain ::
, it's rather a short notation indicating some number of zeroes. ::ffff:192.168.1.10
is equivalent to 0:0:0:0:0:ffff:192.168.1.10
or 0:0:0:0:0:ffff:c0a8:010a
(see IPv6 address presentation). So in order to distinguish IPv6 and IPv4 addresses you should simply check for a single colon - :
.
IPv6 地址不一定包含::
,它是表示一些零的简短符号。::ffff:192.168.1.10
等效于0:0:0:0:0:ffff:192.168.1.10
or 0:0:0:0:0:ffff:c0a8:010a
(请参阅IPv6 地址介绍)。因此,为了区分 IPv6 和 IPv4 地址,您只需检查单个冒号 - :
。
When storing IPv4 addresses in the database I used to use something like INET_ATON to change them into large integers. Should I abandon this and just store all remote addresses as strings that can be 45 characters long (maximum length of an IPv6 address string)
在数据库中存储 IPv4 地址时,我曾经使用 INET_ATON 之类的东西将它们更改为大整数。我是否应该放弃这一点,将所有远程地址存储为长度为 45 个字符的字符串(IPv6 地址字符串的最大长度)
An IPv6 address is a 128-bit number - even if you can store it as a number (e.g. as two BIGINT
numbers in MySQL), it's questionable whether this approach really makes sense. The only scenario I can think of where you would need to work with numbers is evaluating subnet masks, for everything else a string is sufficient and easier to handle.
IPv6 地址是一个 128 位的数字——即使你可以将它存储为一个数字(例如BIGINT
在 MySQL 中作为两个数字),这种方法是否真的有意义也是值得怀疑的。我能想到的唯一需要处理数字的情况是评估子网掩码,对于其他所有内容,字符串就足够了并且更容易处理。
回答by DuBistKomisch
re: #4, a library like ipaddr.jsworks well, e.g.:
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
}