4

In node.js 4.x for the function http.request the docs say

Options

  • family: IP address family to use when resolving host and hostname. Valid values are 4 or 6. When unspecified, both IP v4 and v6 will be used.

What is the logic behind when node.js will choose ipv6 or ipv4 when family is not specified?

As far as I can tell when I don't specify it it defaults to or prefers ipv4 whereas browsers, at least, chrome, prefers ipv6

Is there a way to get node.js to choose ipv6 when available or do I have to do with manually?

If I was to do it manually what should do?

  • pass in family: 6, if timeout then pass in family: 4?

  • Make a DNS request and check if I get an ipv6 address back, then set the family?

gman
  • 100,619
  • 31
  • 269
  • 393

1 Answers1

7

TL;DR: it seems that Node leaves this up to the OS.

Longer story: http.request() will use the net module under the hood. How that module handles DNS lookups can be found here: "if family isn't 4 and family isn't 6 and there are no special getaddrinfo hints provided, use dns.ADDRCONFIG as default lookup hint".

dns.ADDRCONFIG means:

Returned address types are determined by the types of addresses supported by the current system. For example, IPv4 addresses are only returned if the current system has at least one IPv4 address configured. Loopback addresses are not considered.

This still doesn't say anything about the order in which the IP-addresses will be picked, but as far as I can tell, this is left to the implementation of getaddrinfo.

AFAIK, if you have both IPv6 and IPv4 interfaces, two DNS queries will be performed to look up a hostname: A for IPv4 and AAAA for IPv6. It might be (but I'm guessing here) that the first lookup to succeed will supply the IP-address that is passed back to Node.

Is there a way to get node.js to choose ipv6 when available or do I have to do with manually?

It doesn't look like you can do that from http.request(), so yeah, I think you're going to have to do that manually by means of performing a DNS request with family : 6.

robertklep
  • 198,204
  • 35
  • 394
  • 381
  • I can't find why, but it does not leave it to the OS. `getent hosts hostname` returns IPv6 address, but `dns.lookup('hostname')` passes IPv4 address to the callback. – nert Feb 09 '17 at 21:37
  • 1
    @nert my guess would be that the resolver will perform an IPv4 lookup against your DNS server and only use `/etc/hosts` for the IPv6-part. – robertklep Feb 10 '17 at 07:55
  • Why would it do so? If I pass `{ all: true }` to `dns.lookup`, then it resolves all addresses, but still, the IPv4 one is first. So I did `dig hostname ANY` and that returned them in the same order. So it looks like node really **does** leave it to the system, it's just that the other programs have their own preference. So now I need to figure the rest out. Thanks ;) – nert Feb 10 '17 at 18:01