Discussion:
[avahi] Receive mDNS annoucnements
Jon Fitt
2014-11-21 17:59:43 UTC
Permalink
Hello,I am looking for a way for a Linux machine to tell when I return home. My idea is that my iPhone will always do an mDNS announcement when it joins my home wifi. So I'm looking for a way to watch for mDNS announcements and perform and action if the right one is seen. Obviously the avahi-daemon is watching these all the time and updating its cache, so I was thinking that there might be a good place to start. However the only command line way I can see to get to the avahi-daemon cache is to send a SIGUSR1 to get it to dump to /var/log/syslog. Then I can look at the timestamp to determine the last time it registered and compare with now. That seems quite ugly though, and I don't like the idea of continually dumping to syslog.
So is there a way to make it more event driven with the avahi-daemon? I think from looking at the D-Bus API that might be the way to go?If it is the right approach, I would appreciate it if someone knew of a related chunk of source that I could use as a starting point.
Thanks!Jonathan
Jonathan Fitt
2014-11-21 22:08:17 UTC
Permalink
Thanks! I'll give that a go and let you know how it goes.

Jonathan
Hello,I am looking for a way for a Linux machine to tell when I return home. My idea is that my iPhone will always do an mDNS announcement when it joins my home wifi. So I'm looking for a way to watch for mDNS announcements and perform and action if the right one is seen. Obviously the avahi-daemon is watching these all the time and updating its cache, so I was thinking that there might be a good place to start. However the only command line way I can see to get to the avahi-daemon cache is to send a SIGUSR1 to get it to dump to /var/log/syslog. Then I can look at the timestamp to determine the last time it registered and compare with now. That seems quite ugly though, and I don't like the idea of continually dumping to syslog.
So is there a way to make it more event driven with the avahi-daemon? I think from looking at the D-Bus API that might be the way to go?If it is the right approach, I would appreciate it if someone knew of a related chunk of source that I could use as a starting point.
Thanks!Jonathan
Write a small program that uses the Avahi API. A very high level wrapper for the Avahi API is: https://github.com/johanneshilden/qtzeroconf
Using that, you can detect your phone joining your home network in under 10 lines of code.
Create the service browser object
Connect that new object to a qt slot that'll respond to the new service joining your network, Tell the service browser object which services to listen for.
From there, you can do whatever you want with the information. Perhaps you would want to send some kind of DBus signal to let other programs know.
I'm afraid I haven't investigated the DBus API, so I'm not certain I can give you any advice in that direction, but I have written apps using the high level Qt API that I linked above, and I've never had any trouble with it.
--Michael Jones
_______________________________________________
avahi mailing list
http://lists.freedesktop.org/mailman/listinfo/avahi
Jon Fitt
2014-11-25 19:17:45 UTC
Permalink
Hi Michael,
I'm looking at your ZConfBrowserWidget and I see that it needs a service type. Technically I believe from what I've been reading the mDNS host announcements are different to an DNS-SD service, although they are both announced in a similar way.Is there a "service type" that catches the mDNS hostname announcements?
Regards,
Jonathan

On Friday, 21 November 2014, 15:08, Jonathan Fitt <***@yahoo.com> wrote:


Thanks! I'll give that a go and let you know how it goes. 
Jonathan
On Nov 21, 2014, at 1:25 PM, Michael Jones <***@jonesmz.com> wrote:




Hello,I am looking for a way for a Linux machine to tell when I return home. My idea is that my iPhone will always do an mDNS announcement when it joins my home wifi. So I'm looking for a way to watch for mDNS announcements and perform and action if the right one is seen. Obviously the avahi-daemon is watching these all the time and updating its cache, so I was thinking that there might be a good place to start. However the only command line way I can see to get to the avahi-daemon cache is to send a SIGUSR1 to get it to dump to /var/log/syslog. Then I can look at the timestamp to determine the last time it registered and compare with now. That seems quite ugly though, and I don't like the idea of continually dumping to syslog.
So is there a way to make it more event driven with the avahi-daemon? I think from looking at the D-Bus API that might be the way to go?If it is the right approach, I would appreciate it if someone knew of a related chunk of source that I could use as a starting point.
Thanks!Jonathan



Write a small program that uses the Avahi API. A very high level wrapper for the Avahi API is: https://github.com/johanneshilden/qtzeroconf

Using that, you can detect your phone joining your home network in under 10 lines of code.
Create the service browser object
Connect that new object to a qt slot that'll respond to the new service joining your network, Tell the service browser object which services to listen for.

From there, you can do whatever you want with the information. Perhaps you would want to send some kind of DBus signal to let other programs know.

I'm afraid I haven't investigated the DBus API, so I'm not certain I can give you any advice in that direction, but I have written apps using the high level Qt API that I linked above, and I've never had any trouble with it.

--Michael Jones
Jon Fitt
2014-11-25 22:24:50 UTC
Permalink
In the avahi-client C-API there is the concept of a Service Browser and a Record Browser. Service Browser sounds like what you are using now:

| AvahiServiceBrowser* avahi_service_browser_new | ( | AvahiClient *  | client, |
| | | AvahiIfIndex  | interface, |
| | | AvahiProtocol  | protocol, |
| | | const char *  | type, |
| | | const char *  | domain, |
| | | AvahiLookupFlags  | flags, |
| | | AvahiServiceBrowserCallback  | callback, |
| | | void *  | userdata  |
| | ) |


The type being for example _http._tcp. Whereas a Record Browser looks like this:

| AvahiRecordBrowser* avahi_record_browser_new | ( | AvahiClient *  | client, |
| | | AvahiIfIndex  | interface, |
| | | AvahiProtocol  | protocol, |
| | | const char *  | name, |
| | | uint16_t  | clazz, |
| | | uint16_t  | type, |
| | | AvahiLookupFlags  | flags, |
| | | AvahiRecordBrowserCallback  | callback, |
| | | void *  | userdata  |
| | ) |


I wonder if that is a more generic mDNS browser? Unfortunately the parameters, and what a "record" is, is not explained in the online documentation. I'll have a look in the source to see if I can find out more.
Regards,Jonathan

On Tuesday, 25 November 2014, 13:17, Michael Jones <***@jonesmz.com> wrote:





Hi Michael,
I'm looking at your ZConfBrowserWidget and I see that it needs a service type. Technically I believe from what I've been reading the mDNS host announcements are different to an DNS-SD service, although they are both announced in a similar way.Is there a "service type" that catches the mDNS hostname announcements?
Regards,
Jonathan

     On Friday, 21 November 2014, 15:08, Jonathan Fitt <***@yahoo.com> wrote:


 Thanks! I'll give that a go and let you know how it goes. 
Jonathan
On Nov 21, 2014, at 1:25 PM, Michael Jones <***@jonesmz.com> wrote:




Hello,I am looking for a way for a Linux machine to tell when I return home. My idea is that my iPhone will always do an mDNS announcement when it joins my home wifi. So I'm looking for a way to watch for mDNS announcements and perform and action if the right one is seen. Obviously the avahi-daemon is watching these all the time and updating its cache, so I was thinking that there might be a good place to start. However the only command line way I can see to get to the avahi-daemon cache is to send a SIGUSR1 to get it to dump to /var/log/syslog. Then I can look at the timestamp to determine the last time it registered and compare with now. That seems quite ugly though, and I don't like the idea of continually dumping to syslog.
So is there a way to make it more event driven with the avahi-daemon? I think from looking at the D-Bus API that might be the way to go?If it is the right approach, I would appreciate it if someone knew of a related chunk of source that I could use as a starting point.
Thanks!Jonathan



Write a small program that uses the Avahi API. A very high level wrapper for the Avahi API is: https://github.com/johanneshilden/qtzeroconf

Using that, you can detect your phone joining your home network in under 10 lines of code.
Create the service browser object
Connect that new object to a qt slot that'll respond to the new service joining your network, Tell the service browser object which services to listen for.
From there, you can do whatever you want with the information. Perhaps you would want to send some kind of DBus signal to let other programs know.
I'm afraid I haven't investigated the DBus API, so I'm not certain I can give you any advice in that direction, but I have written apps using the high level Qt API that I linked above, and I've never had any trouble with it.

--Michael Jone


Hi Jonathan


That's a good question. I actually don't know. The qtzeroconf library isn't actually mine, originally. I made a lot of modifications to it (Here: https://github.com/jonesmz/qtzeroconf) that take advantage of Qt5 and C++11, but those changes aren't compatible with older versions of Qt, so I didn't want to recommend it to you.

If you feel like poking around at the Avahi C API and can demonstrate how to get mDNS host announcements out of the Avahi C api, I'd be willing to add support for that to my version of the qtzeroconf library (though, it'll still not be compatible with Qt4 or older versions of C++, so you might end up needing to backport the changes to the original authors github project.)

If you want to work just with what the current qtzeroconf library can do, you can just make your phone advertise an avahi service. Perhaps give the protocol name something like "_phone._tcp" or something.

Another thing to keep in mind, I don't know whether Avahi will automatically detect your phone on the local network unless your phone's operating system automatically sends that announcement. As far as I know, Android doesn't do that. I don't know about the other phone OS's.

Best of luck, and let me know if you want to investigate the host announcement support in qtzeroconf.

--Michael Jones
Trent Lloyd
2014-12-01 04:58:25 UTC
Permalink
A quick Avahi primer,

A “browser” is a long running process to watch for records coming and going,
A “resolver” is a short running process to resolve a record and get a final result.

Avahi is also a combination of two technologies, first “multicast dns” which implements DNS with special considerations for a shared multicast network — and then “DNS-SD” or DNS based service discovery. This is a set of DNS records that can be used to discover a service, it can be used over multicast dns, or in fact can also be used over normal DNS.


Generally you “browse” for some set of records, then if you are interested in one, you “resolve” it.

So generally in most Avahi applications, the “Service Browser” queries a list of services over time, e.g. get a list of all _http._tcp services. It then returns a list of such services, which you can then (optionally) resolve with the “Service Resolver”, that will then fetch the service and resolve it’s additional TXT records, the IP address for the hostname, etc.

A typically use case in an application is that you browse the service list with a ServiceBrowser, you provide the user with a list of the service names, they then click a service and you then run the ServiceResolver to get the IP and other TXT details — to then connect to it. Some applications will also run a ServiceResolver on every service because they need the TXT data to show extra information to the user.

The reason these are split is that it saves unnecessary network traffic if the application did not want to resolve the service. This can be a big issue in large networks, so you want to avoid every application resolving all services if possible. Or at least, not all the time.



The “Record Browser” is a more low level tool for browsing a specific DNS record over mDNS. It is not normally used by most applications, as they use the ServiceBrowser/ServiceResolver which queries multiple records for you and does extra logic to handle service discovery. But if you wanted to watch a specific record, this is the tool to use. For example perhaps you want to see if there is an entry for “my-computer.local” with an A record (IPv4 Address).

This might actually be ideal for this use case, since you want to know over time if a specific device is on the network or not - regardless of what services it is advertising.


Hope that helps!

- Trent
AvahiServiceBrowser <http://avahi.org/download/doxygen/lookup_8h.html#ade1392a93ff4d0407c1735374bc0ff7b>* avahi_service_browser_new <http://avahi.org/download/doxygen/lookup_8h.html#a52d55a5156a7943012d03e6700880d2b> ( AvahiClient <http://avahi.org/download/doxygen/client_8h.html#a3d65e9ea7182c44fa8df04a72f1a56bb> * client,
AvahiIfIndex <http://avahi.org/download/doxygen/address_8h.html#a2fda397a8f430cb537e37bbca0afb535> interface,
AvahiProtocol <http://avahi.org/download/doxygen/address_8h.html#a5342ada86ff1566a7fc6e855b3d46c3d> protocol,
const char * type,
const char * domain,
AvahiLookupFlags <http://avahi.org/download/doxygen/defs_8h.html#afa669747c3ff55190d86673dff960e50> flags,
AvahiServiceBrowserCallback <http://avahi.org/download/doxygen/lookup_8h.html#a666e712e840c612ba24d9e41673a94df> callback,
void * userdata
)
AvahiRecordBrowser <http://avahi.org/download/doxygen/lookup_8h.html#ad0a38359b6c52d4272acd831410186f2>* avahi_record_browser_new <http://avahi.org/download/doxygen/lookup_8h.html#a21ac2275126fb9e5eaaae8afe3b75532> ( AvahiClient <http://avahi.org/download/doxygen/client_8h.html#a3d65e9ea7182c44fa8df04a72f1a56bb> * client,
AvahiIfIndex <http://avahi.org/download/doxygen/address_8h.html#a2fda397a8f430cb537e37bbca0afb535> interface,
AvahiProtocol <http://avahi.org/download/doxygen/address_8h.html#a5342ada86ff1566a7fc6e855b3d46c3d> protocol,
const char * name,
uint16_t clazz,
uint16_t type,
AvahiLookupFlags <http://avahi.org/download/doxygen/defs_8h.html#afa669747c3ff55190d86673dff960e50> flags,
AvahiRecordBrowserCallback <http://avahi.org/download/doxygen/lookup_8h.html#a867a24784f27539ed34291e0db8b51b8> callback,
void * userdata
)
I wonder if that is a more generic mDNS browser? Unfortunately the parameters, and what a "record" is, is not explained in the online documentation. I'll have a look in the source to see if I can find out more.
Regards,
Jonathan
Hi Michael,
I'm looking at your ZConfBrowserWidget and I see that it needs a service type. Technically I believe from what I've been reading the mDNS host announcements are different to an DNS-SD service, although they are both announced in a similar way.Is there a "service type" that catches the mDNS hostname announcements?
Regards,
Jonathan
Thanks! I'll give that a go and let you know how it goes.
Jonathan
Hello,I am looking for a way for a Linux machine to tell when I return home. My idea is that my iPhone will always do an mDNS announcement when it joins my home wifi. So I'm looking for a way to watch for mDNS announcements and perform and action if the right one is seen. Obviously the avahi-daemon is watching these all the time and updating its cache, so I was thinking that there might be a good place to start. However the only command line way I can see to get to the avahi-daemon cache is to send a SIGUSR1 to get it to dump to /var/log/syslog. Then I can look at the timestamp to determine the last time it registered and compare with now. That seems quite ugly though, and I don't like the idea of continually dumping to syslog.
So is there a way to make it more event driven with the avahi-daemon? I think from looking at the D-Bus API that might be the way to go?If it is the right approach, I would appreciate it if someone knew of a related chunk of source that I could use as a starting point.
Thanks!Jonathan
Write a small program that uses the Avahi API. A very high level wrapper for the Avahi API is: https://github.com/johanneshilden/qtzeroconf <https://github.com/johanneshilden/qtzeroconf>
Using that, you can detect your phone joining your home network in under 10 lines of code.
Create the service browser object
Connect that new object to a qt slot that'll respond to the new service joining your network, Tell the service browser object which services to listen for.
From there, you can do whatever you want with the information. Perhaps you would want to send some kind of DBus signal to let other programs know.
I'm afraid I haven't investigated the DBus API, so I'm not certain I can give you any advice in that direction, but I have written apps using the high level Qt API that I linked above, and I've never had any trouble with it.
--Michael Jone
Hi Jonathan
That's a good question. I actually don't know. The qtzeroconf library isn't actually mine, originally. I made a lot of modifications to it (Here: https://github.com/jonesmz/qtzeroconf <https://github.com/jonesmz/qtzeroconf>) that take advantage of Qt5 and C++11, but those changes aren't compatible with older versions of Qt, so I didn't want to recommend it to you.
If you feel like poking around at the Avahi C API and can demonstrate how to get mDNS host announcements out of the Avahi C api, I'd be willing to add support for that to my version of the qtzeroconf library (though, it'll still not be compatible with Qt4 or older versions of C++, so you might end up needing to backport the changes to the original authors github project.)
If you want to work just with what the current qtzeroconf library can do, you can just make your phone advertise an avahi service. Perhaps give the protocol name something like "_phone._tcp" or something.
Another thing to keep in mind, I don't know whether Avahi will automatically detect your phone on the local network unless your phone's operating system automatically sends that announcement. As far as I know, Android doesn't do that. I don't know about the other phone OS's.
Best of luck, and let me know if you want to investigate the host announcement support in qtzeroconf.
--Michael Jones
_______________________________________________
avahi mailing list
http://lists.freedesktop.org/mailman/listinfo/avahi <http://lists.freedesktop.org/mailman/listinfo/avahi>
_______________________________________________
avahi mailing list
http://lists.freedesktop.org/mailman/listinfo/avahi
Jon Fitt
2014-12-01 17:32:50 UTC
Permalink
Hi Michael,
I  created a project on github for my hamfisted attempt to get this to work. It's my first use of Git, as a longtime user of CVS and Clearcase it took a little while to get it going :)https://github.com/jonfitt/client-browse-records

Regards,Jonathan



On Sunday, 30 November 2014, 21:58, Trent Lloyd <***@bur.st> wrote:


A quick Avahi primer,
A “browser” is a long running process to watch for records coming and going,A “resolver” is a short running process to resolve a record and get a final result.
Avahi is also a combination of two technologies, first “multicast dns” which implements DNS with special considerations for a shared multicast network — and then “DNS-SD” or DNS based service discovery.  This is a set of DNS records that can be used to discover a service, it can be used over multicast dns, or in fact can also be used over normal DNS.

Generally you “browse” for some set of records, then if you are interested in one, you “resolve” it.
So generally in most Avahi applications, the “Service Browser” queries a list of services over time, e.g. get a list of all _http._tcp services.  It then returns a list of such services, which you can then (optionally) resolve with the “Service Resolver”, that will then fetch the service and resolve it’s additional TXT records, the IP address for the hostname, etc.
A typically use case in an application is that you browse the service list with a ServiceBrowser,  you provide the user with a list of the service names, they then click a service and you then run the ServiceResolver to get the IP and other TXT details — to then connect to it.  Some applications will also run a ServiceResolver on every service because they need the TXT data to show extra information to the user.
The reason these are split is that it saves unnecessary network traffic if the application did not want to resolve the service.  This can be a big issue in large networks, so you want to avoid every application resolving all services if possible.  Or at least, not all the time.


The “Record Browser”  is a more low level tool for browsing a specific DNS record over mDNS.  It is not normally used by most applications,  as they use the ServiceBrowser/ServiceResolver which queries multiple records for you and does extra logic to handle service discovery.  But if you wanted to watch a specific record, this is the tool to use.  For example perhaps you want to see if there is an entry for “my-computer.local” with an A record (IPv4 Address).  
This might actually be ideal for this use case, since you want to know over time if a specific device is on the network or not - regardless of what services it is advertising.

Hope that helps!
- Trent

On 26 Nov 2014, at 6:24 am, Jon Fitt <***@yahoo.com> wrote:
In the avahi-client C-API there is the concept of a Service Browser and a Record Browser. Service Browser sounds like what you are using now:

| AvahiServiceBrowser* avahi_service_browser_new | ( | AvahiClient *  | client, |
| | | AvahiIfIndex  | interface, |
| | | AvahiProtocol  | protocol, |
| | | const char *  | type, |
| | | const char *  | domain, |
| | | AvahiLookupFlags  | flags, |
| | | AvahiServiceBrowserCallback  | callback, |
| | | void *  | userdata  |
| | ) |


The type being for example _http._tcp. Whereas a Record Browser looks like this:

| AvahiRecordBrowser* avahi_record_browser_new | ( | AvahiClient *  | client, |
| | | AvahiIfIndex  | interface, |
| | | AvahiProtocol  | protocol, |
| | | const char *  | name, |
| | | uint16_t  | clazz, |
| | | uint16_t  | type, |
| | | AvahiLookupFlags  | flags, |
| | | AvahiRecordBrowserCallback  | callback, |
| | | void *  | userdata  |
| | ) |


I wonder if that is a more generic mDNS browser? Unfortunately the parameters, and what a "record" is, is not explained in the online documentation. I'll have a look in the source to see if I can find out more.
Regards,Jonathan

On Tuesday, 25 November 2014, 13:17, Michael Jones <***@jonesmz.com> wrote:





Hi Michael,
I'm looking at your ZConfBrowserWidget and I see that it needs a service type. Technically I believe from what I've been reading the mDNS host announcements are different to an DNS-SD service, although they are both announced in a similar way.Is there a "service type" that catches the mDNS hostname announcements?
Regards,
Jonathan

     On Friday, 21 November 2014, 15:08, Jonathan Fitt <***@yahoo.com> wrote:


 Thanks! I'll give that a go and let you know how it goes. 
Jonathan
On Nov 21, 2014, at 1:25 PM, Michael Jones <***@jonesmz.com> wrote:




Hello,I am looking for a way for a Linux machine to tell when I return home. My idea is that my iPhone will always do an mDNS announcement when it joins my home wifi. So I'm looking for a way to watch for mDNS announcements and perform and action if the right one is seen. Obviously the avahi-daemon is watching these all the time and updating its cache, so I was thinking that there might be a good place to start. However the only command line way I can see to get to the avahi-daemon cache is to send a SIGUSR1 to get it to dump to /var/log/syslog. Then I can look at the timestamp to determine the last time it registered and compare with now. That seems quite ugly though, and I don't like the idea of continually dumping to syslog.
So is there a way to make it more event driven with the avahi-daemon? I think from looking at the D-Bus API that might be the way to go?If it is the right approach, I would appreciate it if someone knew of a related chunk of source that I could use as a starting point.
Thanks!Jonathan



Write a small program that uses the Avahi API. A very high level wrapper for the Avahi API is: https://github.com/johanneshilden/qtzeroconf

Using that, you can detect your phone joining your home network in under 10 lines of code.
Create the service browser object
Connect that new object to a qt slot that'll respond to the new service joining your network, Tell the service browser object which services to listen for.
From there, you can do whatever you want with the information. Perhaps you would want to send some kind of DBus signal to let other programs know.
I'm afraid I haven't investigated the DBus API, so I'm not certain I can give you any advice in that direction, but I have written apps using the high level Qt API that I linked above, and I've never had any trouble with it.

--Michael Jone


Hi Jonathan


That's a good question. I actually don't know. The qtzeroconf library isn't actually mine, originally. I made a lot of modifications to it (Here: https://github.com/jonesmz/qtzeroconf) that take advantage of Qt5 and C++11, but those changes aren't compatible with older versions of Qt, so I didn't want to recommend it to you.

If you feel like poking around at the Avahi C API and can demonstrate how to get mDNS host announcements out of the Avahi C api, I'd be willing to add support for that to my version of the qtzeroconf library (though, it'll still not be compatible with Qt4 or older versions of C++, so you might end up needing to backport the changes to the original authors github project.)

If you want to work just with what the current qtzeroconf library can do, you can just make your phone advertise an avahi service. Perhaps give the protocol name something like "_phone._tcp" or something.

Another thing to keep in mind, I don't know whether Avahi will automatically detect your phone on the local network unless your phone's operating system automatically sends that announcement. As far as I know, Android doesn't do that. I don't know about the other phone OS's.

Best of luck, and let me know if you want to investigate the host announcement support in qtzeroconf.

--Michael Jones

_______________________________________________
avahi mailing list
***@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/avahi


_______________________________________________
avahi mailing list
***@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/avahi
Jon Fitt
2014-12-01 17:40:57 UTC
Permalink
Hi Trent,
Thanks for the breakdown, that explains neatly what I had been coming to understand about the API. As I was saying to Michael, I had a go at turning client-browse-services.c into client-browse-records and uploaded it here: https://github.com/jonfitt/client-browse-recordsI've hardcoded "hostname.local" in the browser object creation, but I use a known working .local address when I run it. I get no records in response (CACHE_EXHAUSTED ALL_FOR_NOW) and then a seg fault. I'm sure I'm doing something stupid, but it eludes me.
As a side note it would be cool to be able to say "Give me all your AVAHI_DNS_CLASS_IN  AVAHI_DNS_TYPE_A records", without needing to specify a hostname. I know the hostname I'm looking for, so it's not a problem  for me. But I can see a case where you just want to get all the records.
Regards,
Jonathan

On Sunday, 30 November 2014, 21:58, Trent Lloyd <***@bur.st> wrote:


A quick Avahi primer,
A “browser” is a long running process to watch for records coming and going,A “resolver” is a short running process to resolve a record and get a final result.
Avahi is also a combination of two technologies, first “multicast dns” which implements DNS with special considerations for a shared multicast network — and then “DNS-SD” or DNS based service discovery.  This is a set of DNS records that can be used to discover a service, it can be used over multicast dns, or in fact can also be used over normal DNS.

Generally you “browse” for some set of records, then if you are interested in one, you “resolve” it.
So generally in most Avahi applications, the “Service Browser” queries a list of services over time, e.g. get a list of all _http._tcp services.  It then returns a list of such services, which you can then (optionally) resolve with the “Service Resolver”, that will then fetch the service and resolve it’s additional TXT records, the IP address for the hostname, etc.
A typically use case in an application is that you browse the service list with a ServiceBrowser,  you provide the user with a list of the service names, they then click a service and you then run the ServiceResolver to get the IP and other TXT details — to then connect to it.  Some applications will also run a ServiceResolver on every service because they need the TXT data to show extra information to the user.
The reason these are split is that it saves unnecessary network traffic if the application did not want to resolve the service.  This can be a big issue in large networks, so you want to avoid every application resolving all services if possible.  Or at least, not all the time.


The “Record Browser”  is a more low level tool for browsing a specific DNS record over mDNS.  It is not normally used by most applications,  as they use the ServiceBrowser/ServiceResolver which queries multiple records for you and does extra logic to handle service discovery.  But if you wanted to watch a specific record, this is the tool to use.  For example perhaps you want to see if there is an entry for “my-computer.local” with an A record (IPv4 Address).  
This might actually be ideal for this use case, since you want to know over time if a specific device is on the network or not - regardless of what services it is advertising.

Hope that helps!
- Trent

On 26 Nov 2014, at 6:24 am, Jon Fitt <***@yahoo.com> wrote:
In the avahi-client C-API there is the concept of a Service Browser and a Record Browser. Service Browser sounds like what you are using now:

| AvahiServiceBrowser* avahi_service_browser_new | ( | AvahiClient *  | client, |
| | | AvahiIfIndex  | interface, |
| | | AvahiProtocol  | protocol, |
| | | const char *  | type, |
| | | const char *  | domain, |
| | | AvahiLookupFlags  | flags, |
| | | AvahiServiceBrowserCallback  | callback, |
| | | void *  | userdata  |
| | ) |


The type being for example _http._tcp. Whereas a Record Browser looks like this:

| AvahiRecordBrowser* avahi_record_browser_new | ( | AvahiClient *  | client, |
| | | AvahiIfIndex  | interface, |
| | | AvahiProtocol  | protocol, |
| | | const char *  | name, |
| | | uint16_t  | clazz, |
| | | uint16_t  | type, |
| | | AvahiLookupFlags  | flags, |
| | | AvahiRecordBrowserCallback  | callback, |
| | | void *  | userdata  |
| | ) |


I wonder if that is a more generic mDNS browser? Unfortunately the parameters, and what a "record" is, is not explained in the online documentation. I'll have a look in the source to see if I can find out more.
Regards,Jonathan

On Tuesday, 25 November 2014, 13:17, Michael Jones <***@jonesmz.com> wrote:





Hi Michael,
I'm looking at your ZConfBrowserWidget and I see that it needs a service type. Technically I believe from what I've been reading the mDNS host announcements are different to an DNS-SD service, although they are both announced in a similar way.Is there a "service type" that catches the mDNS hostname announcements?
Regards,
Jonathan

     On Friday, 21 November 2014, 15:08, Jonathan Fitt <***@yahoo.com> wrote:


 Thanks! I'll give that a go and let you know how it goes. 
Jonathan
On Nov 21, 2014, at 1:25 PM, Michael Jones <***@jonesmz.com> wrote:




Hello,I am looking for a way for a Linux machine to tell when I return home. My idea is that my iPhone will always do an mDNS announcement when it joins my home wifi. So I'm looking for a way to watch for mDNS announcements and perform and action if the right one is seen. Obviously the avahi-daemon is watching these all the time and updating its cache, so I was thinking that there might be a good place to start. However the only command line way I can see to get to the avahi-daemon cache is to send a SIGUSR1 to get it to dump to /var/log/syslog. Then I can look at the timestamp to determine the last time it registered and compare with now. That seems quite ugly though, and I don't like the idea of continually dumping to syslog.
So is there a way to make it more event driven with the avahi-daemon? I think from looking at the D-Bus API that might be the way to go?If it is the right approach, I would appreciate it if someone knew of a related chunk of source that I could use as a starting point.
Thanks!Jonathan



Write a small program that uses the Avahi API. A very high level wrapper for the Avahi API is: https://github.com/johanneshilden/qtzeroconf

Using that, you can detect your phone joining your home network in under 10 lines of code.
Create the service browser object
Connect that new object to a qt slot that'll respond to the new service joining your network, Tell the service browser object which services to listen for.
From there, you can do whatever you want with the information. Perhaps you would want to send some kind of DBus signal to let other programs know.
I'm afraid I haven't investigated the DBus API, so I'm not certain I can give you any advice in that direction, but I have written apps using the high level Qt API that I linked above, and I've never had any trouble with it.

--Michael Jone


Hi Jonathan


That's a good question. I actually don't know. The qtzeroconf library isn't actually mine, originally. I made a lot of modifications to it (Here: https://github.com/jonesmz/qtzeroconf) that take advantage of Qt5 and C++11, but those changes aren't compatible with older versions of Qt, so I didn't want to recommend it to you.

If you feel like poking around at the Avahi C API and can demonstrate how to get mDNS host announcements out of the Avahi C api, I'd be willing to add support for that to my version of the qtzeroconf library (though, it'll still not be compatible with Qt4 or older versions of C++, so you might end up needing to backport the changes to the original authors github project.)

If you want to work just with what the current qtzeroconf library can do, you can just make your phone advertise an avahi service. Perhaps give the protocol name something like "_phone._tcp" or something.

Another thing to keep in mind, I don't know whether Avahi will automatically detect your phone on the local network unless your phone's operating system automatically sends that announcement. As far as I know, Android doesn't do that. I don't know about the other phone OS's.

Best of luck, and let me know if you want to investigate the host announcement support in qtzeroconf.

--Michael Jones

_______________________________________________
avahi mailing list
***@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/avahi


_______________________________________________
avahi mailing list
***@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/avahi
Jon Fitt
2016-01-08 23:57:17 UTC
Permalink
Hi Trent, or any other interested parties,
I don't know if you're watching this mailing list any more, but I'm trying to pick this up again.
What I'm looking to do is query the avahi service to get it to tell me all hosts that it has seen make any service announcements, and ideally when. I'd like to have my Raspberry Pi keep a passive list of all hosts it has seen and when they were last seen.
I'm ultimately looking for it to be able to tell when I have returned home because my iphone will make service announcements as soon as it rejoins the wifi.
I'd guess I can use a service browser to look for "ANY" service and then use a service resolver to resolve all of them to their hostname/IP, but that seems inefficient.
Is there a way to query the avahi service based on hostname, instead of service type?
Regards,
Jonathan



On Sunday, 30 November 2014, 21:58, Trent Lloyd <***@bur.st> wrote:


A quick Avahi primer,
A “browser” is a long running process to watch for records coming and going,A “resolver” is a short running process to resolve a record and get a final result.
Avahi is also a combination of two technologies, first “multicast dns” which implements DNS with special considerations for a shared multicast network — and then “DNS-SD” or DNS based service discovery.  This is a set of DNS records that can be used to discover a service, it can be used over multicast dns, or in fact can also be used over normal DNS.

Generally you “browse” for some set of records, then if you are interested in one, you “resolve” it.
So generally in most Avahi applications, the “Service Browser” queries a list of services over time, e.g. get a list of all _http._tcp services.  It then returns a list of such services, which you can then (optionally) resolve with the “Service Resolver”, that will then fetch the service and resolve it’s additional TXT records, the IP address for the hostname, etc.
A typically use case in an application is that you browse the service list with a ServiceBrowser,  you provide the user with a list of the service names, they then click a service and you then run the ServiceResolver to get the IP and other TXT details — to then connect to it.  Some applications will also run a ServiceResolver on every service because they need the TXT data to show extra information to the user.
The reason these are split is that it saves unnecessary network traffic if the application did not want to resolve the service.  This can be a big issue in large networks, so you want to avoid every application resolving all services if possible.  Or at least, not all the time.


The “Record Browser”  is a more low level tool for browsing a specific DNS record over mDNS.  It is not normally used by most applications,  as they use the ServiceBrowser/ServiceResolver which queries multiple records for you and does extra logic to handle service discovery.  But if you wanted to watch a specific record, this is the tool to use.  For example perhaps you want to see if there is an entry for “my-computer.local” with an A record (IPv4 Address).  
This might actually be ideal for this use case, since you want to know over time if a specific device is on the network or not - regardless of what services it is advertising.

Hope that helps!
- Trent

On 26 Nov 2014, at 6:24 am, Jon Fitt <***@yahoo.com> wrote:
In the avahi-client C-API there is the concept of a Service Browser and a Record Browser. Service Browser sounds like what you are using now:

| AvahiServiceBrowser* avahi_service_browser_new | ( | AvahiClient *  | client, |
| | | AvahiIfIndex  | interface, |
| | | AvahiProtocol  | protocol, |
| | | const char *  | type, |
| | | const char *  | domain, |
| | | AvahiLookupFlags  | flags, |
| | | AvahiServiceBrowserCallback  | callback, |
| | | void *  | userdata  |
| | ) |


The type being for example _http._tcp. Whereas a Record Browser looks like this:

| AvahiRecordBrowser* avahi_record_browser_new | ( | AvahiClient *  | client, |
| | | AvahiIfIndex  | interface, |
| | | AvahiProtocol  | protocol, |
| | | const char *  | name, |
| | | uint16_t  | clazz, |
| | | uint16_t  | type, |
| | | AvahiLookupFlags  | flags, |
| | | AvahiRecordBrowserCallback  | callback, |
| | | void *  | userdata  |
| | ) |


I wonder if that is a more generic mDNS browser? Unfortunately the parameters, and what a "record" is, is not explained in the online documentation. I'll have a look in the source to see if I can find out more.
Regards,Jonathan

On Tuesday, 25 November 2014, 13:17, Michael Jones <***@jonesmz.com> wrote:





Hi Michael,
I'm looking at your ZConfBrowserWidget and I see that it needs a service type. Technically I believe from what I've been reading the mDNS host announcements are different to an DNS-SD service, although they are both announced in a similar way.Is there a "service type" that catches the mDNS hostname announcements?
Regards,
Jonathan

     On Friday, 21 November 2014, 15:08, Jonathan Fitt <***@yahoo.com> wrote:


 Thanks! I'll give that a go and let you know how it goes. 
Jonathan
On Nov 21, 2014, at 1:25 PM, Michael Jones <***@jonesmz.com> wrote:




Hello,I am looking for a way for a Linux machine to tell when I return home. My idea is that my iPhone will always do an mDNS announcement when it joins my home wifi. So I'm looking for a way to watch for mDNS announcements and perform and action if the right one is seen. Obviously the avahi-daemon is watching these all the time and updating its cache, so I was thinking that there might be a good place to start. However the only command line way I can see to get to the avahi-daemon cache is to send a SIGUSR1 to get it to dump to /var/log/syslog. Then I can look at the timestamp to determine the last time it registered and compare with now. That seems quite ugly though, and I don't like the idea of continually dumping to syslog.
So is there a way to make it more event driven with the avahi-daemon? I think from looking at the D-Bus API that might be the way to go?If it is the right approach, I would appreciate it if someone knew of a related chunk of source that I could use as a starting point.
Thanks!Jonathan



Write a small program that uses the Avahi API. A very high level wrapper for the Avahi API is: https://github.com/johanneshilden/qtzeroconf

Using that, you can detect your phone joining your home network in under 10 lines of code.
Create the service browser object
Connect that new object to a qt slot that'll respond to the new service joining your network, Tell the service browser object which services to listen for.
From there, you can do whatever you want with the information. Perhaps you would want to send some kind of DBus signal to let other programs know.
I'm afraid I haven't investigated the DBus API, so I'm not certain I can give you any advice in that direction, but I have written apps using the high level Qt API that I linked above, and I've never had any trouble with it.

--Michael Jone


Hi Jonathan


That's a good question. I actually don't know. The qtzeroconf library isn't actually mine, originally. I made a lot of modifications to it (Here: https://github.com/jonesmz/qtzeroconf) that take advantage of Qt5 and C++11, but those changes aren't compatible with older versions of Qt, so I didn't want to recommend it to you.

If you feel like poking around at the Avahi C API and can demonstrate how to get mDNS host announcements out of the Avahi C api, I'd be willing to add support for that to my version of the qtzeroconf library (though, it'll still not be compatible with Qt4 or older versions of C++, so you might end up needing to backport the changes to the original authors github project.)

If you want to work just with what the current qtzeroconf library can do, you can just make your phone advertise an avahi service. Perhaps give the protocol name something like "_phone._tcp" or something.

Another thing to keep in mind, I don't know whether Avahi will automatically detect your phone on the local network unless your phone's operating system automatically sends that announcement. As far as I know, Android doesn't do that. I don't know about the other phone OS's.

Best of luck, and let me know if you want to investigate the host announcement support in qtzeroconf.

--Michael Jones

_______________________________________________
avahi mailing list
***@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/avahi


_______________________________________________
avahi mailing list
***@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/avahi
Jonathan Bagg
2016-01-11 20:49:20 UTC
Permalink
My Qt zeroconf / avahi wrapper keeps a list of discovered / resolved
services...

https://github.com/jbagg/QtZeroConf

QMap<QString, QZeroConfService *> services; is private, but you could
move it to the public part of the class for your project.
Post by Jon Fitt
Hi Trent, or any other interested parties,
I don't know if you're watching this mailing list any more, but I'm
trying to pick this up again.
What I'm looking to do is query the avahi service to get it to tell me
all hosts that it has seen make any service announcements, and ideally
when. I'd like to have my Raspberry Pi keep a passive list of all
hosts it has seen and when they were last seen.
I'm ultimately looking for it to be able to tell when I have returned
home because my iphone will make service announcements as soon as it
rejoins the wifi.
I'd guess I can use a service browser to look for "ANY" service and
then use a service resolver to resolve all of them to their
hostname/IP, but that seems inefficient.
Is there a way to query the avahi service based on hostname, instead of service type?
Regards,
Jonathan
A quick Avahi primer,
A “browser” is a long running process to watch for records coming and going,
A “resolver” is a short running process to resolve a record and get a
final result.
Avahi is also a combination of two technologies, first “multicast dns”
which implements DNS with special considerations for a shared
multicast network — and then “DNS-SD” or DNS based service discovery.
This is a set of DNS records that can be used to discover a service,
it can be used over multicast dns, or in fact can also be used over
normal DNS.
Generally you “browse” for some set of records, then if you are
interested in one, you “resolve” it.
So generally in most Avahi applications, the “Service Browser” queries
a list of services over time, e.g. get a list of all _http._tcp
services. It then returns a list of such services, which you can then
(optionally) resolve with the “Service Resolver”, that will then fetch
the service and resolve it’s additional TXT records, the IP address
for the hostname, etc.
A typically use case in an application is that you browse the service
list with a ServiceBrowser, you provide the user with a list of the
service names, they then click a service and you then run the
ServiceResolver to get the IP and other TXT details — to then connect
to it. Some applications will also run a ServiceResolver on every
service because they need the TXT data to show extra information to
the user.
The reason these are split is that it saves unnecessary network
traffic if the application did not want to resolve the service. This
can be a big issue in large networks, so you want to avoid every
application resolving all services if possible. Or at least, not all
the time.
The “Record Browser” is a more low level tool for browsing a specific
DNS record over mDNS. It is not normally used by most applications,
as they use the ServiceBrowser/ServiceResolver which queries multiple
records for you and does extra logic to handle service discovery. But
if you wanted to watch a specific record, this is the tool to use.
For example perhaps you want to see if there is an entry for
“my-computer.local” with an A record (IPv4 Address).
This might actually be ideal for this use case, since you want to know
over time if a specific device is on the network or not - regardless
of what services it is advertising.
Hope that helps!
- Trent
Post by Jon Fitt
In the avahi-client C-API there is the concept of a Service Browser
AvahiServiceBrowser
<http://avahi.org/download/doxygen/lookup_8h.html#ade1392a93ff4d0407c1735374bc0ff7b>*
avahi_service_browser_new
<http://avahi.org/download/doxygen/lookup_8h.html#a52d55a5156a7943012d03e6700880d2b>
( AvahiClient
<http://avahi.org/download/doxygen/client_8h.html#a3d65e9ea7182c44fa8df04a72f1a56bb> *
client,
AvahiIfIndex
<http://avahi.org/download/doxygen/address_8h.html#a2fda397a8f430cb537e37bbca0afb535>
interface,
AvahiProtocol
<http://avahi.org/download/doxygen/address_8h.html#a5342ada86ff1566a7fc6e855b3d46c3d>
protocol,
const char * type,
const char * domain,
AvahiLookupFlags
<http://avahi.org/download/doxygen/defs_8h.html#afa669747c3ff55190d86673dff960e50>
flags,
AvahiServiceBrowserCallback
<http://avahi.org/download/doxygen/lookup_8h.html#a666e712e840c612ba24d9e41673a94df>
callback,
void * userdata
)
AvahiRecordBrowser
<http://avahi.org/download/doxygen/lookup_8h.html#ad0a38359b6c52d4272acd831410186f2>*
avahi_record_browser_new
<http://avahi.org/download/doxygen/lookup_8h.html#a21ac2275126fb9e5eaaae8afe3b75532>
( AvahiClient
<http://avahi.org/download/doxygen/client_8h.html#a3d65e9ea7182c44fa8df04a72f1a56bb> *
client,
AvahiIfIndex
<http://avahi.org/download/doxygen/address_8h.html#a2fda397a8f430cb537e37bbca0afb535>
interface,
AvahiProtocol
<http://avahi.org/download/doxygen/address_8h.html#a5342ada86ff1566a7fc6e855b3d46c3d>
protocol,
const char * name,
uint16_t clazz,
uint16_t type,
AvahiLookupFlags
<http://avahi.org/download/doxygen/defs_8h.html#afa669747c3ff55190d86673dff960e50>
flags,
AvahiRecordBrowserCallback
<http://avahi.org/download/doxygen/lookup_8h.html#a867a24784f27539ed34291e0db8b51b8>
callback,
void * userdata
)
I wonder if that is a more generic mDNS browser? Unfortunately the
parameters, and what a "record" is, is not explained in the online
documentation. I'll have a look in the source to see if I can find
out more.
Regards,
Jonathan
Hi Michael,
I'm looking at your ZConfBrowserWidget and I see that it needs a
service type. Technically I believe from what I've been reading
the mDNS host announcements are different to an DNS-SD service,
although they are both announced in a similar way.Is there a
"service type" that catches the mDNS hostname announcements?
Regards,
Jonathan
On Friday, 21 November 2014, 15:08, Jonathan Fitt
Thanks! I'll give that a go and let you know how it goes.
Jonathan
Hello,I am looking for a way for a Linux machine to tell when I
return home. My idea is that my iPhone will always do an mDNS
announcement when it joins my home wifi. So I'm looking for a way
to watch for mDNS announcements and perform and action if the
right one is seen. Obviously the avahi-daemon is watching these
all the time and updating its cache, so I was thinking that there
might be a good place to start. However the only command line way
I can see to get to the avahi-daemon cache is to send a SIGUSR1
to get it to dump to /var/log/syslog. Then I can look at the
timestamp to determine the last time it registered and compare
with now. That seems quite ugly though, and I don't like the idea
of continually dumping to syslog.
So is there a way to make it more event driven with the
avahi-daemon? I think from looking at the D-Bus API that might be
the way to go?If it is the right approach, I would appreciate it
if someone knew of a related chunk of source that I could use as
a starting point.
Thanks!Jonathan
Write a small program that uses the Avahi API. A very high level
https://github.com/johanneshilden/qtzeroconf
Using that, you can detect your phone joining your home network
in under 10 lines of code.
Create the service browser object
Connect that new object to a qt slot that'll respond to the new
service joining your network, Tell the service browser object
which services to listen for.
From there, you can do whatever you want with the information.
Perhaps you would want to send some kind of DBus signal to let
other programs know.
I'm afraid I haven't investigated the DBus API, so I'm not
certain I can give you any advice in that direction, but I have
written apps using the high level Qt API that I linked above, and
I've never had any trouble with it.
--Michael Jone
Hi Jonathan
That's a good question. I actually don't know. The qtzeroconf library
isn't actually mine, originally. I made a lot of modifications to it
(Here: https://github.com/jonesmz/qtzeroconf) that take advantage of
Qt5 and C++11, but those changes aren't compatible with older
versions of Qt, so I didn't want to recommend it to you.
If you feel like poking around at the Avahi C API and can demonstrate
how to get mDNS host announcements out of the Avahi C api, I'd be
willing to add support for that to my version of the qtzeroconf
library (though, it'll still not be compatible with Qt4 or older
versions of C++, so you might end up needing to backport the changes
to the original authors github project.)
If you want to work just with what the current qtzeroconf library can
do, you can just make your phone advertise an avahi service. Perhaps
give the protocol name something like "_phone._tcp" or something.
Another thing to keep in mind, I don't know whether Avahi will
automatically detect your phone on the local network unless your
phone's operating system automatically sends that announcement. As
far as I know, Android doesn't do that. I don't know about the other
phone OS's.
Best of luck, and let me know if you want to investigate the host
announcement support in qtzeroconf.
--Michael Jones
_______________________________________________
avahi mailing list
http://lists.freedesktop.org/mailman/listinfo/avahi
_______________________________________________
avahi mailing list
http://lists.freedesktop.org/mailman/listinfo/avahi
_______________________________________________
avahi mailing list
http://lists.freedesktop.org/mailman/listinfo/avahi
_______________________________________________
avahi mailing list
http://lists.freedesktop.org/mailman/listinfo/avahi
--
Jonathan Bagg
Embedded Systems Developer
NAD Electronics | Lenbrook Industries Limited
633 Granite Court, Pickering, Ontario, Canada L1W 3K1 | 905-831-0799 ext 4478 | http://www.nadelectronics.com
Jon Fitt
2014-11-26 18:48:40 UTC
Permalink
I'm not able to get a record browser doing what I want. I have modified client-browse-services.c to make a record browser instead of a service browser. 
avahi_record_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "BRN30055C232008.local", AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_A, 0, browse_callback, client)

I know my printer BRN30055C232008.local is making DNS A announcements because I can see them in Wireshark. However I just get CACHE_EXHAUSTED then seg fault. I've tried different host names with and without the domain and sometimes that will get CACHE_EXHAUSTED, ALL_FOR_NOW instead of seg fault. I've also tried the hostnames with and without the domain of various Apple devices I know are making DNS A announcements.
I know that my printer is also making _http._tcp service announcements as "Brother DCP-8011DN". If I pass "Brother DCP-8011DN" as the host name then I get:CACHE_EXHAUSTEDDNS failure: NXDOMAIN
That's the closest I get to an outcome. It's worrying because I don't only want to get the DNS A records of hosts that also advertise services, I just want to grab (preferably all) DNS A records that the daemon has in memory.
Regards,
Jonathan

On Tuesday, 25 November 2014, 16:38, Michael Jones <***@jonesmz.com> wrote:





In the avahi-client C-API there is the concept of a Service Browser and a Record Browser. Service Browser sounds like what you are using now:

| AvahiServiceBrowser* avahi_service_browser_new | ( | AvahiClient *  | client, |
|  |  | AvahiIfIndex  | interface, |
|  |  | AvahiProtocol  | protocol, |
|  |  | const char *  | type, |
|  |  | const char *  | domain, |
|  |  | AvahiLookupFlags  | flags, |
|  |  | AvahiServiceBrowserCallback  | callback, |
|  |  | void *  | userdata  |
|  | ) |


The type being for example _http._tcp. Whereas a Record Browser looks like this:

| AvahiRecordBrowser* avahi_record_browser_new | ( | AvahiClient *  | client, |
|  |  | AvahiIfIndex  | interface, |
|  |  | AvahiProtocol  | protocol, |
|  |  | const char *  | name, |
|  |  | uint16_t  | clazz, |
|  |  | uint16_t  | type, |
|  |  | AvahiLookupFlags  | flags, |
|  |  | AvahiRecordBrowserCallback  | callback, |
|  |  | void *  | userdata  |
|  | ) |



Hi Jonathan,

    Yea, that looks familiar. As far as I remember, the qtzeroconf (either the original, or my fork) doesn't use the avahi_record_browser api.

    I'd be happy to collaborate with you on building support for that.

    Should be pretty straight forward. Mostly we'll just need to copy and modify the ServiceBrowser class, I think.

--Mike
Loading...