avahi / avahi

Avahi - Service Discovery for Linux using mDNS/DNS-SD -- compatible with Bonjour
http://www.avahi.org
GNU Lesser General Public License v2.1
1.19k stars 329 forks source link

RFE: Always advertise link-local addresses #243

Open srd424 opened 5 years ago

srd424 commented 5 years ago

Avahi doesn't advertise a link-local address if a global address is available. This was queried many years ago on the mailing list: https://lists.freedesktop.org/archives/avahi/2010-March/001863.html

It does in fact cause problems in some circumstances, where some machines have e.g. static global addresses assigned, and others have link local only. For example, Pidgin's Bonjour module is unable to match the source address on an incoming connection with the address that was originally advertised: https://bugs.launchpad.net/ubuntu/+source/pidgin/+bug/1841621

There's an old patch in Launchpad to change this behaviour, but a quick review suggests it is not quite correct: https://bugs.launchpad.net/ubuntu/+source/avahi/+bug/1102906

KaiJan57 commented 4 years ago

I can confirm that this is a problem. In my configuration, I have avahi configured to advertise a squid server on IPv6 that only accepts connections from link-local addresses. As avahi always chooses the global address, clients on lan cannot connect to the squid server by the address avahi advertises. To work around avahi not preferring link-local addresses, I configured avahi to only advertise the squid server's IPv4 address.

lathiat commented 4 years ago

I think we can do this but first we need to implement support for "ordering" the list of addresses given by both API calls and nss-mdns - as right now the order is random and it's possible to give the 'less preferred' address. Which can be a problem particularly for link local addresses if applications don't support setting the sin6_scope.

nss-mdns now sets sin6_scope so that helps a lot - it's part of the reason it was disabled in the past. but I think we should still order the lookups first.

gabekassel commented 3 years ago

@lathiat any updates on this enhancement? Thanks so much!

EskoDijk commented 3 years ago

Most discussion on this are around which address to use; e.g. link-local or global address. But what about the requirements for mDNS RFC 6762 section 6.2 ?

When a Multicast DNS responder sends a Multicast DNS response message containing its own address records, it MUST include all addresses that are valid on the interface on which it is sending the message ...

For example, if an interface has both an IPv6 link- local and an IPv6 routable address, both should be included in the response message

So this says both addresses must be included in case global/link-local addresses are available. Then an ordering of addresses seems not needed, right?

TownCube commented 3 years ago

Great find, just to quote the next bit which is important because it conveys the intent that it's the querier's choice about which address they use and so any ordering on the part of the responder has no bearing on which address is ultimately used. You could argue one before the other means preferred but I can't see any reference to that in the RFC so it'd be building complexity in that may never be used by a querier.

For example, if an interface has both an IPv6 link- local and an IPv6 routable address, both should be included in the response message so that queriers receive both and can make their own choice about which to use.

KiraleDev commented 2 years ago

Find a patch for Avahi attached in order to address two issues concerning IPv6 addressing and to ensure compliance with RFC6762. One of them is related to this thread.

Even though the Debian package used has been avahi-daemon (0.7-4+deb10u1), I guess it would be easy to adapt the patch for any other version affected by these issues.

I hope it helps you.

rfc6762_ipv6_addressing_issues.txt

EskoDijk commented 2 years ago

Thanks, yes the 2nd issue is the IPv6 source address of the mDNS response: if it is sent to a link-local IPv6 destination address, the IPv6 source address must also be selected as link-local scope per the IPv6 source address selection rules RFC 6724.

Interesting further point of RFC 6762 mDNS is that it states that all valid addresses must be included which happens to include also deprecated addresses (see RFC 4862), however I think it is generally best to exclude deprecated addresses alltogether if the responding interface will always have at least a (valid) link-local address. This conforms best to the use of deprecated addresses; that they shouldn't be used to initiate any new connections (which is what typically follows after mDNS discovery).

martin-belanger commented 1 year ago

I realize that this is an older post (although still open), but I am trying to decide how my application will decide which address to select considering that an application that requests the list of IP addresses associated with a service type will not receive that list atomically from the avahi-daemon.

As stated before, RFC6762 section 6.2 says:

For example, if an interface has both an IPv6 link-local and an IPv6 routable address, both should be included in the response message so that queriers receive both and can make their own choice about which to use. This allows a querier that only has an IPv6 link-local address to connect to the link-local address, and a different querier that has an IPv6 routable address to connect to the IPv6 routable address instead.

And:

When a Multicast DNS responder places an IPv4 or IPv6 address record (rrtype "A" or "AAAA") into a response message, it SHOULD also place any records of the other address type with the same name into the additional section, if there is space in the message. This is to provide fate sharing, so that all a device's addresses are delivered atomically in a single message, to reduce the risk that packet loss could cause a querier to receive only the IPv4 addresses and not the IPv6 addresses, or vice versa.

In order for an application to decide which address to select, it must have the full list of addresses associated with an interface. However, it receives these addresses one at a time from the avahi resolver and it doesn't know when all of the addresses for a given interface have been received. Is there a way for an application to know for sure that it has received the complete list of addresses from the avahi resolver? A workaround would be to use a timer (duration: 100, 200, 500, ??? msec) and that timer gets restarted each time a resolved record is received. When the timer expires it must mean that all the records have been received. This, however, is not guaranteed to always work. If, for any reason (e.g. busy system), a record takes longer than usual to be received from the resolver, the application may falsely conclude that the list is complete and select a less than optimal address from that incomplete list.

Any thoughts?

EskoDijk commented 1 year ago

@martin-belanger What you describe is a query for a service type (that would be a PTR query) to which multiple mDNS devices can potentially answer, and it is unknown how long this would take and when the responses from mDNS devices would end. That case is covered by the RFC as it describes the use case of a GUI/UI list of found services that gets live updated as more information comes in. The waiting time is then determined by how long the user is willing to wait!

Maybe the issue is then that sometimes the IP addresses for the mDNS device, hosting a particular service, come in later than the PTR answer that identifies the service, and possibly later than the related SRV record that identifies more information about the service and which port it can be found on. This is caused by the Additional Record Generation feature of mDNS that is quite flexible in what a responder can send or not. If the responder doesn't send a particular piece of information then the resolving device needs to send extra queries to get that information (one by one) which takes time. And maybe a responder did not send all its address records in the Additional record section; because this is only a "SHOULD" in the spec it means a responder could just not do it for its own particular reasons.

Now if the address information (A and/or AAAA records) is coming in late at the resolver, then in principle the resolver knows that this information is still coming (because it determined that the information either still needs to be fetched or it was missing in the Additional record section of the answer). So it would be silly for the application to wait in a timer-based manner on the resolver, because the resolver is still busy and it knows more is coming - it's working to get that information. That said, I haven't looked yet at the Avahi resolver API and if it can signal to the application that it is still busy fetching the address information, or not.

In general for this issue we need to study the specification text a bit more and its intention: because it's not immediately clear if the requirements for including all addresses hold for A and AAAA records in the Answer section, in the Additional section, or both sections. That makes quite a difference.

marcosfrm commented 1 year ago

Windows 10 22H2 responds with all IPv6 addresses from the interface which the query was made:

1 0.000000000 192.168.0.156 → 224.0.0.251  MDNS 87 Standard query 0x0000 A DESKTOP-XXXXXXX.local, "QM" question AAAA DESKTOP-XXXXXXX.local, "QM" question
2 0.078261068 192.168.0.13 → 224.0.0.251  MDNS 224 Standard query response 0x0000 A 192.168.0.13 AAAA 2804:xxx:xxxx:xxxx:yyyy:yyyy:yyyy:yyyy AAAA 2804:xxx:xxxx:xxxx:uuuu:uuuu:uuuu:uuuu AAAA 2804:xxx:xxxx:xxxx:zzzz:zzzz:zzzz:zzzz AAAA fe80::jjjj:jjjj:jjjj:jjjj

It appears to put link-local one at the end, if that matters.

troglobit commented 7 months ago

How is this still a thing? As pointed out in https://github.com/avahi/avahi/issues/243#issuecomment-863054215 the RFC clearly states that all addresses should be included. Also, the whole point of an mDNS daemon is to simplify access on a LAN, so including fe80 addresses should be a nobrainer, even the reference mDNSResponder does this.

EskoDijk commented 7 months ago

@troglobit Agreed; the only thing that was recently being discussed is some finer details - those come up because the inclusion of any addresses, in the answer to a PTR query, is not mandatory. It's recommended (SHOULD) but that also means an implementation may have its reasons to not include the addresses. That leads to some potential corner cases as explained in my last hard-to-read post.

It's just that nobody has made a PR yet to fix this. And the maintainers were unwilling so far to label this issue a "bug", for some reason it's an "enhancement" now which I don't agree with.