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:
request.connection.remoteAddress; // 192.168.1.10
Now I am seeing this:
request.connection.remoteAddress; // ::ffff:192.168.1.10
::ffff:192.168.1.10
actually an IPv6 address or is it an IPv4 address?::
?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)Is my Node server listening to IPv6 addresses?
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.
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.
Is
::ffff:192.168.1.10
actually an IPv6 address or is it an IPv4 address?
Both. IPv6 addresses can embed IPv4 addresses - and this is one of these embedded addresses. See IPv4-mapped IPv6 addresses.
Is the easiest way to tell if a remoteAddress is IPv6 to check if the string contains
::
?
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 - :
.
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)
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.