Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mDNS is using the wrong / only one interface with IPv6 on Linux #5783

Open
T-X opened this issue Dec 30, 2024 · 0 comments
Open

mDNS is using the wrong / only one interface with IPv6 on Linux #5783

T-X opened this issue Dec 30, 2024 · 0 comments

Comments

@T-X
Copy link

T-X commented Dec 30, 2024

Summary

Problem

We tried using Qaul.net, which uses rust-libp2p, via mDNS with IPv6 enabled through the following commit/branch: qaul/qaul.net@main...mdns_IPv6

We observed the issue on a desktop Linux/Debian (Sid) that rust-libp2p uses only one interface for mDNS with IPv6. More specifically it uses the first interface found in the local routing table, here htc0:

$ ip -6 route show table local
...
multicast ff00::/8 dev htc0 proto kernel metric 256 pref medium
multicast ff00::/8 dev enx3c18a01499aa proto kernel metric 256 pref medium
multicast ff00::/8 dev wlp1s0 proto kernel metric 256 pref medium

So Linux installs one IPv6 multicast route per interface with a long prefix length, all having the same priority. Linux then just chooses the first one, here htc0, which is typically not the one we are interested in. The decision can then be monitored/seen here:

$ ip maddr show dev htc0
7:	htc0
...
	link  33:33:00:00:00:fb users 2
...
	inet6 ff02::fb
...
$ ip maddr show dev wlp1s0
[empty]

We could verify that the routing table influences the decision. For instance if we install, as a workaround, a more specific route as follows then we do see mDNS v6 on the desired wlp1s0 WLAN interface from rust-libp2p:

$ ip -6 route add ff02::fb/128 dev wlp1s0 table local

It seems that rust-libp2p does not enforce a specific interface in its socket.join_multicast_v6() call in protocols/mdns/src/behaviour/iface.rs. The interface ID is set to 0 there in its call, leaving the decision to the OS.

Note that a IPV6_ADD_MEMBERSHIP / IPV6_JOIN_GROUP might behave a bit counter intuitively / different compared to a socket that binds to 0.0.0.0/::. Such a socket for unicast would receive from all interfaces. For the multicast join however even with a zero/unspecified interface ID only one interface is chosen, instead of all.

Solution/Suggestion

rust-libp2p should call/maintain join_multicast_v6 for each interface.

(Or could alternatively use/try a OS provided API if available first. avahi-daemon for instance already correctly installs an mDNS listener on all available interfaces and performs the IPV6_JOIN_GROUP on all of them. And rust-libp2p could probably register its service to avahi-daemon.)

Expected behavior

mDNS with IPv6 should work on all interfaces by default.

Actual behavior

Only the first interface matching in the IPv6 "local" routing table on Linux is used for mDNS v6 in rust-libp2p.

Relevant log output

No response

Possible Solution

No response

Version

last version

Would you like to work on fixing this bug?

Yes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant