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: packets are excessively large #5790

Open
T-X opened this issue Jan 3, 2025 · 1 comment
Open

mDNS: packets are excessively large #5790

T-X opened this issue Jan 3, 2025 · 1 comment

Comments

@T-X
Copy link

T-X commented Jan 3, 2025

Description

It would be great if the mDNS packet size could be reduced, they are currently very large, leading to multiple, fragmented IP packets. By default, an mDNS packet transmitted on one interface should maybe only contain addresses from this specific interface? The mDNS RFC6762, section 6.2 also says (even if rust-libp2p's reply is not strictly an mDNS response to an address query):

6.2.  Responding to Address Queries

   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,
   and MUST NOT include addresses that are not valid on that interface
   (such as addresses that may be configured on the host's other
   interfaces).
...

The implementation also currently violates RFC6762, section 17:

17.  Multicast DNS Message Size
  ...
   A Multicast DNS packet larger than the interface MTU, which is sent
   using fragments, MUST NOT contain more than one resource record.

Also:

...
   In the case of a single Multicast DNS resource record that is too
   large to fit in a single MTU-sized multicast response packet, a
   Multicast DNS responder SHOULD send the resource record alone, in a
   single IP datagram, using multiple IP fragments.  Resource records
   this large SHOULD be avoided, except in the very rare cases where
   they really are the appropriate solution to the problem at hand.
   Implementers should be aware that many simple devices do not
   reassemble fragmented IP datagrams, so large resource records SHOULD
   NOT be used except in specialized cases where the implementer knows

Motivation

While trying Qaul.net on our local Freifunk network we noticed that mDNS packets are very large, over 1100 4000 bytes. Example packet from an Android phone (which has one extra interface through using NetGuard).

https://gist.github.com/T-X/19b5044df4c669306f1316555a6b8005

Currently this size typically breaks using the stateless multicast packet type in our mesh routing protocol batman-adv in our network. The fallback to batman-adv broadcast packets is in turn by default filtered by our firmware framework Gluon due to scalability concerns regarding broadcasts. (So partially self-induced, but still would be nice to reduce the size. With more interfaces / addresses would also be easy to exceed a 1500 bytes MTU size, leading to IP fragmentation.)

Another concern is privacy. The current approach might make it easy to figure out a person's location.

Current Implementation

In the current implementation IPv4/IPv6 unicast addresses from all interfaces are included in an mDNS packet transmitted by rust-libp2p. For my Android phone this were 11 addresses leading to 22 entries (x2 for TCP+UDP) in the mDNS packet of >4000 bytes size.

From interfaces:

  • lo:
    • 127.0.0.1
    • ::1
  • wlan0:
    • fdef:ffc0:3dd7:0:424e:... (IPv6 ULA)
    • 2001:67c:2d50:0:424e:... (IPv6 global)
    • fdef:ffc0:3dd7:0:14b2:a8e2:53c5:d366 (IPv6 ULA, privacy extension)
    • 2001:67c:2d50:0:14b2:a8e2:53c5:d366 (IPv6 global, privacy extension)
    • 10.130.27.220
  • USB tethering:
    • 192.168.42.129
  • NetGuard (tun):
    • 10.1.10.1
    • fd00:1:fd00:1:fd00:1:fd00:1
  • Cellular (rmnet_data):
    • 10.194.37.146

(But somehow IPv6 link-local addresses are missing? Which would be the most reliable, stable one for link-local communication?)

Are you planning to do it yourself in a pull request?

No

Edit: Originally wrote they'd be >1100 bytes. Actually they are even >4000 bytes and already IP fragmented.

@elenaf9
Copy link
Contributor

elenaf9 commented Jan 4, 2025

Thank you for opening the issue and for the detailed description! Those are very good points.

Regarding 6.2 Responding to Address Queries:

I wasn't able to find any prio discussion on this, neither in this repo, nor in go-libp2p or the specs.
However, I looked into zeroconf, the mDNS implementation that go-libp2p is using, and it seems like they are only responding with the listening addresses of the matching interface, instead of sending all addresses. And IMO that completely makes sense, and it's something we can easily change in rust-libp2p.

Still, I need to look into it some more.

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

2 participants