Thank you Trent.

My use case  --> I have been using avahi-core on Android for NDK (c++) apps.  Android's NsdManager (java) has too many bugs / is not reliable.  Maybe I can add into avahi-core an api to call when the network interfaces change as you suggest.  Maybe

avahi_s_interface_add(something)

avahi_s_interface_remove(something)

It really sucks to do this.  Google should ship avahi-client for NDK stuff.

Jon

On 2022-02-27 8:11 p.m., Trent Lloyd wrote:
Yes this is currently correct. Avahi needs a way to see a list of interfaces 
and IP addresses as well to monitor when they are added and removed. Currently 
the only interface for that on Linux is netlink.

If you want to go without it you’d have to write a replacement iface-*.c code 
to leverage whatever APIs are available.

What’s your use case?

Trent

On 28 Feb 2022, at 1:47 am, Jonathan Bagg <jb...@lenbrook.com> wrote:

Hello,

I have built libavahi-core.a from source without netlink support on Linux (x86 Debian 
11).  Why --> Google has disabled binding to a netlink socket in api >= 30.  
Unfortunately my program is not able to publish or browse for services without 
netlink enabled in avahi-core.  Is this correct behaviour?  I noticed iface-none.c is 
built instead of iface-linux.c.

Jon

On 2021-12-07 8:24 p.m., Trent Lloyd wrote:
Hi Folkert,

On 8 Dec 2021, at 4:56 am, folkert <folk...@vanheusden.com> wrote:
I made a program which sends an mDNS announcement every 121 seconds.
The TTL is 120 seconds.

Yet every time avahi (with --debug) complains about:

dec 07 10:27:54 lappiemctopface avahi-daemon[937]: Received conflicting
record [_apple-midi._udp.local        IN        PTR
mymdnstest._apple-midi._udp.local ; ttl=120]. Resetting our record.

I've uploaded a pcap:
https://linkprotect.cudasvc.com/url?a=https%3a%2f%2fvps001.vanheusden.com%2f~folkert%2fmdns.pcap&c=E,1,qAnUYiH7cFCdxQbDZpGLALJ3CssMNFzEVwiE1YbVHM6xWACOIfv0bXq4NyQO47Se-scGGdgXM8Y-4LPX_zaw-lMTYcZTObE8F7JZtvBCze4WWoAqIg,,&typo=1
(text dump: 
https://linkprotect.cudasvc.com/url?a=https%3a%2f%2fvps001.vanheusden.com%2f~folkert%2fmdns.txt&c=E,1,j_MXzszdG-MCfApSpw2sf4M8LBrQJcvTlDZUHKUshzPaBaT2VINalQ-vLxTh1PcaTI7hzfBzJ8GIdmcqriVdhknuL4iP35MAIF2fNwH9jQZ_2tNyB-AAdodHqJs,&typo=1
 )

Anyone an idea what is going wrong?
I just verified that I get this error already on the first packet.

So I start avahi-daemon, let the other program send the mdns message
once and immediately avahi complains about a conflicting record.
What is sending these other packets? I think there are two main problems. The 
first one leading to the immediate conflict is that mDNS records can be either 
“Unique” (owned by a single host) or “Shared” (a record publish by multiple 
hosts, or, a list of records published in aggregate by multiple hosts).

If you refer to RFC6762 Section 10.2 
(https://linkprotect.cudasvc.com/url?a=https%3a%2f%2fdatatracker.ietf.org%2fdoc%2fhtml%2frfc6762%23section-10.2&c=E,1,hRneuq7gmccKO3LOVORaP2tWQygWE5bJiKLRQha1JzYmzqty-tJg-1qQYtkUu_e_UjO2kU6ACgPcwFQz4fxni2UFlKtmaHdTPZhuKufxrZxAWjuemctkl_UUwB8,&typo=1)

    The semantics of the cache-flush bit are as follows: normally when a
    resource record appears in a Resource Record Section of the DNS
    response it means, "This is an assertion that this information is
    true".  When a resource record appears in a Resource Record Section
    of the DNS response with the cache-flush bit set, it means, "This is
    an assertion that this information is the truth and the whole truth,
    and anything you may have heard more than a second ago regarding
    records of this name/rrtype/rrclass is no longer true”.


Unique records such as your hostname ‘mydnstest.local’ are expected to have the 
cache-flush bit to be set. But for shared resources such as the list of 
services (_apple-midi._udp.local PTR) we expect a “Shared” record so the 
cache-flush bit is false. This is because the “_apple-midi._udp.local” record 
is a shared list of services where multiple services all contribute to the list.

Additionally the SRV record looks wrong.. from your text output it says:
         _apple-midi._udp.local: type SRV, class IN, cache flush, priority 0, 
weight 0, port 5004, target mymdnstest.local

The name of this record should be ‘mydnstest._apple-midi._udp.local’ instead, 
the same name as the target for the PTR record.


The hierarchy of announcements is:
(1) PTR from the shared service name (_http._tcp) with a target of your unique 
service instance (test._http._tcp.local)

_http._tcp.local PTR test._http._tcp.local (Shared record, cache-flush=false)

(2) SRV record from your unique service name with the port number and target 
hostname
test._http._tcp.local SRV port 80 target primary.local (Non-shared record, 
cache-flush=true)

There may also be a TXT record of the same name with any properties

(3) A/AAAA record for the IP address of the target hostname referenced in the 
SRV (the hostname is usually shared by all services from the same host)
primary.local A 192.168.1.1 (Typically non-shared with cache-flush=true)

Here is an example Wireshark capture I took just now of publishing a service 
using avahi (avahi-publish-service test _http._tcp 80). I’d suggest reviewing 
and comparing your announcement to that:

         test._http._tcp.local: type TXT, class IN, cache flush
             Name: test._http._tcp.local
             Type: TXT (Text strings) (16)
             .000 0000 0000 0001 = Class: IN (0x0001)
             1... .... .... .... = Cache flush: True
             Time to live: 4500 (1 hour, 15 minutes)
             Data length: 1
             TXT Length: 0
             TXT:
         _http._tcp.local: type PTR, class IN, test._http._tcp.local
             Name: _http._tcp.local
             Type: PTR (domain name PoinTeR) (12)
             .000 0000 0000 0001 = Class: IN (0x0001)
             0... .... .... .... = Cache flush: False
             Time to live: 4500 (1 hour, 15 minutes)
             Data length: 2
             Domain Name: test._http._tcp.local
         test._http._tcp.local: type SRV, class IN, cache flush, priority 0, 
weight 0, port 80, target primary.local
             Service: test
             Protocol: _http
             Name: _tcp.local
             Type: SRV (Server Selection) (33)
             .000 0000 0000 0001 = Class: IN (0x0001)
             1... .... .... .... = Cache flush: True
             Time to live: 120 (2 minutes)
             Data length: 16
             Priority: 0
             Weight: 0
             Port: 80
             Target: primary.local
         primary.local: type A, class IN, cache flush, addr 192.168.1.1
             Name: primary.local
             Type: A (Host Address) (1)
             .000 0000 0000 0001 = Class: IN (0x0001)
             1... .... .... .... = Cache flush: True
             Time to live: 120 (2 minutes)
             Data length: 4
             Address: 192.168.1.1

(The below record is optional, it makes it so you can browse what types of 
services exist on the local network)
         _services._dns-sd._udp.local: type PTR, class IN, _http._tcp.local
             Name: _services._dns-sd._udp.local
             Type: PTR (domain name PoinTeR) (12)
             .000 0000 0000 0001 = Class: IN (0x0001)
             0... .... .... .... = Cache flush: False
             Time to live: 4500 (1 hour, 15 minutes)
             Data length: 2
             Domain Name: _http._tcp.local

Hope that helps?

Cheers,
Trent (@lathiat)

Reply via email to