3

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.

SHR
  • 7,940
  • 9
  • 38
  • 57
  • Why can't you listen on "ANY"? What flags are you passing in for `hints.ai_flags` in the call to `getaddrinfo()`? According to the Linux man page on [`getaddrinfo(3)`](http://linux.die.net/man/3/getaddrinfo), the sorting function used is based off of [RFC 3484](http://tools.ietf.org/html/rfc3484), but I don't know if Windows also uses the same sorting. – Adam Rosenfield Dec 19 '13 at 18:26
  • Because if you have two networks and you want your server to run only on one network, than you want to get local addresses to listen on. when you give hostname to `getaddrinfo` it resolve it. you can give hostname per network card. – SHR Dec 19 '13 at 18:30

2 Answers2

1

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.

zneak
  • 134,922
  • 42
  • 253
  • 328
  • It is good idea to ignore the link locals. but if I have 2 network cards? how can I tell which IPv6 address match to Which IPv4 address? should I take the first "not fe80::" and the first "not 168.192.x.x"? – SHR Dec 19 '13 at 18:29
  • Linux/UNIX machines not giving me the link local addresses. do you have a reason why? – SHR Dec 19 '13 at 18:33
  • 1
    There is no convention to match IPv4 and IPv6 addresses by interface, but you can [ask Windows to enumerate interfaces and the IP addresses associated with them](http://stackoverflow.com/questions/5213629/how-to-enumerate-all-available-network-interfaces) instead of using `getaddrinfo`. – zneak Dec 19 '13 at 18:34
  • I would guess that the addresses order is meaningful. until now I always selected the first address in multi result cases. but here it breaks this rule. – SHR Dec 19 '13 at 18:39
  • 1
    This is not an assumption I'm comfortable making. *Most likely*, the addresses will be in some sort of logical order because it would be more trouble to have them otherwise, but looking for patterns in that might be more trouble in the long run than iterating through interfaces. For Linux I don't really know, my Linux computer has a link-local address all right. Maybe your computer is configured to delete it once it acquires a global address. – zneak Dec 19 '13 at 18:41
  • @zneak How can I fetch global address only by parsing through the addrinfo result returned from getaddrinfo()? I'm talking about a local machine's case. And also how will I identify which global ipv6 address to use given there more than one addresses starting with 200*::? – Antarus Feb 20 '14 at 08:47
  • @Antarus, there is no such thing as a "global address". Any network interface can have many IP addresses that are all addressable through the larger Internet. You should probably make a distinct question for your question. – zneak Feb 20 '14 at 15:42
0

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.

thahgr
  • 718
  • 1
  • 10
  • 27
  • It is very depends on your configuration. the only ways I've found was to parse the `ifconfig` results, or to manually set it in `/etc/hosts` with given names, when using `ANY` it prevent you to run several different servers on the same machine using the same port, each one on other network card. – SHR Jun 26 '15 at 13:47