cool cool - 3 months ago 20
Node.js Question

Stripping "::ffff:" prefix from request.connection.remoteAddress nodejs

I am implementing subscription/response possibility using nodejs (express). When visitor send request, beside other parameters within request (port, time interval etc...) I am going to collect ip in order to be able to send response to that ip from time to time.

I am fetching visitor ip address using folowing:

var ip = req.headers['x-forwarded-for'] ||
req.connection.remoteAddress ||
req.socket.remoteAddress ||
req.connection.socket.remoteAddress;


based on How can I get the user's IP address using Node.js?

Point is that after i get ip I have something like this : "::ffff:192.168.1.10" (explained at request.connection.remoteAddress Now Prefixed in ::ffff in node.js )

I am woundering, is it "safe" just to strip "::ffff:" prefix in order to get ip address which I will be able to use in order to reply via http response, or I am missing something else over here, and that is not what i should do?

Answer

Yes, it's safe to strip. Here's a quick way to do it.

address.replace(/^.*:/, '')

What happens is your OS is listening with a hybrid IPv4-IPv6 socket, which converts any IPv4 address to IPv6, by embedding it within the IPv4-mapped IPv6 address format. This format just prefixes the IPv4 address with :ffff:, so you can recover the original IPv4 address by just stripping the :ffff:. (Some deprecated mappings prefix with :: instead of :ffff:, so we use the regex /^.*:/ to match both forms.)

If you aren't sure that incoming IPv6 address came from an IPv4, you can check that it matches the IPv6-mapping template first:

template = /^:(ffff)?:(?!0)(?!.*\.$)((1?\d?\d|25[0-5]|2[0-4]\d)(\.|$)){4}$/
has_ipv4_version = template.test(address)