Select a listening addresses for IPv6 server (Dual stack)

1.4k views Asked by At

It will be seem a weird question to some. but I've searched and didn't find any answer.

When I want a dual stack server, I need to listen on INADDR_ANY for IPv4 and to in6addr_any for IPv6.

If I have more than one network card then I need to choose if I want to listen to all, or to specify which card to listen.

For this exact propose I'm using getaddrinfo method with configurable host_name. If the host_name had not configured, then I call getaddrinfo with NULL, and get the two "ANY" addresses. If I configured it with an IP (v6 or v4) I get only one address, which is also fine.

But when I'm using my hostname as the configured host_name, on a Windows machine I'm getting from getaddrinfo 3 address: one IPv4 address, and two IPv6 address. the first is seen by ipconfig as "Link-local IPv6 Address" the second is seen as "IPv6 Address" under the section "Tunnel adapter 6TO4 Adapter:". The addresses ordered like this:

  1. IPv6 Link Local
  2. IPv6 Address
  3. IPv4

So, if I'm listening to all the addresses the dual stack is actually triple stack. If I take the first IPv6 address, (as it was the convention in IPv4 server with configured host_name) I'm listening only on the "Link-local IPv6 Address" which is less accessible than the "IPv6 Address" and many client can't connect to it, while they can connect to the IPv4 address.

Now I'm trying to complicate it further. I'm connected my cellphone to the USB and activate the USB Tethering. when I resolve addresses by getaddrinfo I'm getting 5 addresses: by this order:

  1. USB IPv6 Link Local
  2. Ethernet IPv6 Link Local
  3. IPv6 Address
  4. USB IPv4
  5. Ethernet IPv4

So my questions are:

  1. If it was IPv4 only I would say I take only the first IPv4. and don't care about the rest. but when using IPv6, it look like the last IPv6 is the most appropriate. is there any convention for it?

  2. If I have multi-network machine I need to choose the first network, and listen on both IPv4 and IPv6, but here the results are mixed. again, is there any convention?

  3. Do I need to listen to all IPv6 addresses? in that case I will listen to an IPv6 address which I don't listen to the corresponding IPv4. and I hope to avoid from it.

Thanks for any help or comment. But please don't advice to listen only on "ANY" since I can't.

2

There are 2 answers

1
thahgr On

Old post, i know, how did you resolve it finally? I am really interested to know.

For this I would recommend the option you avoid, bind to ANY, wildcard "::" , bind(.., "::", ..) and use some firewall or pack filter rules to rule out the connections you don't want to.

7
zneak On

Link-local addresses are valid only within a network segment and often just for your machine to the machine at the other end of the communication link. For instance, your USB link-local address will work only for communications between your phone and your computer but not beyond that; your link-local Ethernet IPv6 address will be usable from all machines on the same hub/switch but not beyond a router (somewhat similar to a private IPv4 address). If this is not your expected use case, I suggest that you simply ignore link-local addresses.

Auto-assigned link-local addresses are created with a very specific pattern and mask, so you can detect them programmatically. Link-local IPv6 addresses are in the fe80::/64 range (meaning the first bytes of the address are fe80:0000:0000:0000 and the 8 remaining bytes can be anything), and link-local IPv4 addresses range from 169.254.1.0 to 169.254.255.255.

Also note that all hosts configure all IPv6-capable interfaces with a link-local address, and will retain it even if they are assigned another address, so there's no getting away from it.