androidipv6bonjourjmdns

Which IPv6 address should I use for Bonjour?


In one of my Android apps, I'm using JmDNS for Bonjour support. When starting up, I create one JmDNS instance for each InetAddress in a NetworkInterface. So the code looks something like:

for(InetAddress addr : addresses) {
    JmDNS jmdns = JmDNS.create(addr, "SomeName");
}

This has thus far worked well, and by doing this for both v4 and v6 addresses, I'm able to view everything properly from other clients (e.g. on iOS).

However, with IPv6, one Network adapter can actually be associated with multiple v6 addresses. So, for example, one of my beta testers has sent me a "bug report" with the following Network setup (I've changed some of the numbers to prevent leaking info - hope it doesn't change the meaning):

- ip: /fe80::b4a:8eff:fe91:b1bb%mlan0
isLoopBack: false
isLinkLocal: true
isAnyLocal: false
isSiteLocal: false

- ip: /1234:d000:1234:d1:b4a:8eff:fe91:b1bb
isLoopBack: false
isLinkLocal: false
isAnyLocal: false
isSiteLocal: false

- ip: /10.0.1.5
isLoopBack: false
isLinkLocal: false
isAnyLocal: false
isSiteLocal: true

Looking at that output, it would appear that the two IPv6 addresses are actually quite similar, with perhaps one being link-local while the other isn't. Reading the article on Wikipedia, I was able to glean that in IPv6, all interfaces actually must have a link-local address as well.

However, I'm stumped about which of the two to actually use for my JmDNS registration. If I register both, I get a constant stream of logs that say:

Got conflicting probe from ourselves incoming: [x@123456789 type: TYPE_SRV index 33, class: CLASS_IN index 1, name: something._tcp.local. ttl: '3599/3600' server: 'SomeName.local.:5000']

So which of them should I use? And is there some general rule for deciding which addresses from the group to register with?


Solution

  • The answer is in those four bits.

    Loopback is not good for Bonjour, so eliminate loopback. For Bonjour you want a localish address because Bonjour is localish in nature, but if there's more than one ethernet you probably want all. Therefore, I suggest that if there is a sitelocal address you take that, otherwise take the linklocal address. The linklocal is guaranteed to be there.

    When you get the address, note its preferred_lft (that is its lifetime for new connections, there's also a longer valid_lft for existing connections) and set up a timer to reregister after that period.