avahi icon indicating copy to clipboard operation
avahi copied to clipboard

Wide-Area DNS-SD related DNS queries fail if response is larger than 512 Bytes

Open taladar opened this issue 5 years ago • 2 comments

The problem can be reproduced by creating a Wide-Area DNS-SD service with a single TXT record (possibly with multiple key/value pairs as often found in _ipp._tcp oder _printer._tcp services). The size of the record needs to exceed 512 Bytes.

We used a bind 9.10.3 server.

The problem is visible in avahi-browse when used e.g. like this

avahi-browse -a -t -k -d example.com -r

when it shows an error like this somewhere in the output

Failed to resolve service 'Printer' of type '_ipp._tcp' in domain 'example.com': Not found

Further debugging via the SIGUSR1 dump of the cache to the log reveals that the SRV-record for the service is cached but the TXT-record is not.

Using the dig Tool with default options displays the record as expected.

Wireshark based diffing of the behavior of dig vs Avahi reveals that Avahi sends the same UDP query as dig but without an EDNS-Section in the query.

Changing the dig Parameters to make them most similar in behavior we get to

dig -t TXT Printer._ipp._tcp.example.com +noadflag +nocookie +noedns

Now the queries look basically identical in Wireshark apart from the fact that dig follows up the truncated UDP response with a TCP query to get the full response. We can make dig behave exactly like Avahi by using the +ignore parameter. Now dig also does not return a response anymore.

dig -t TXT Printer._ipp._tcp.example.com +noadflag +nocookie +noedns +ignore

Looking at the source code of Avahi 0.7 to confirm we can see in avahi-core/wide-area.c in the function send_to_dns_server() that it calls avahi_send_dns_packet_ipv4() or avahi_send_dns_packet_ipv6() depending on the DNS server address.

Each of these (in avahi-core/socket.c) just sends a single UDP query with EDNS. The response is then processed in avahi_recv_dns_packet_ipv4() or avahi_recv_dns_packet_ipv6() and truncation of the DNS response is not handled.

Apparently without the EDNS Header setting a buffer size DNS servers do not return responses larger than 512 bytes since that is the body size of the smallest packet IPv4 implementations are supposed to be able to reassemble (576 bytes total, with minimal IPv4 and UDP headers).

taladar avatar Aug 16 '19 14:08 taladar