MDNS and DNS Service Discovery library

Hi,

I’ve been working on a multicast DNS and DNS service discovery library for a few weeks now and I’ve just published this in the Web IDE (MDNS v1.0.0).

There was an existing library ported from Adafruit that allowed you to register your core on the local network, however this didn’t support DNS service discovery (RFC6763 - http://tools.ietf.org/pdf/rfc6763.pdf). My library allows you to assign your core an MDNS name and then register a service which can be automatically discovered via zero conf / Bonjour.

You can also find the source on my github page https://github.com/mrhornsby/spark-core-mdns.

I hope people might find it useful and would be interested if anyone has any feedback.

Thanks

Mark

8 Likes

This is great work! If all I wanted to do was register my hostname ( i.e. have it show up in the dhcp server hostname field), could you post a stripped-down minimal example to achieve that? I don’t want to unnecessarily bloat my code with the full library if possible.

Hi mtnbrit,

I’m afraid MDNS won’t make the name show up on your DHCP server - it is a means for hosts to identify each other via multicast (i.e. in the absence of any DNS server if necessary) - registering a name via DHCP is slightly different - in this case your router (assuming that is the DHCP server) is responsible for telling other hosts about your core - with my library the core can tell other hosts directly what it’s hostname is.

The below is all that is required to register your host name. You should then be able to resolve “core-1.local” to your cores IP address.

// This #include statement was automatically added by the Spark IDE.
#include "MDNS.h"

MDNS mdns;

void setup() {
    bool success = mdns.setHostname("core-1");

    if (success) {
        success = mdns.begin();
    }
}

void loop() {
    mdns.processQueries();
}

First off, great work @mrhornsby - thanks!

I tried the library referenced here but couldn't get it to compile on the Photon (yet)

In any case, yours seems closer to what I'm looking for.
I'd like to use zeroconf so that a Photon can be discovered as an OSC [1] device, e.g. by TouchOsc.
The code compiles fine and I've modified the example slightly for my purposes - changing the service to:
mdns.setService("udp", "osc", 8000, "OSM");

However it's not showing up as a service (I use Bonjour Browser on a Mac) although TouchOSC on my smartphone is (same network).
I tried as well with the example code but no joy. Is it known to work on Photon?
I understand that some routers can drop or not propagate zeroconf messages, but I can see other devices.

Another question, have you thought about how the library could support more than one service entry? At the moment, the number of labels is fixed at 3 and only one of them can be a service.

[1] http://opensoundcontrol.org/topic/110

Hi,

I hadn’t played with the library in a while and it appears it was broken by some changes in the 0.45 firmware around multicast addresses. I’ve just tinkered with it and got it working locally on a Photon - I’ll commit these changes to the library and publish a new version shortly.

Glad that you might find it useful!

Mark

1 Like

Hi,

v1.1.0 should now be available in the IDE. Give it a go. The MDNS / DNS-SD code seems to be working fine, my example has a basic http server which seems to be causing TCP re-transmissions - going to investigate that, but it should be working now for your purposes.

Mark

1 Like

awesome, thanks @mrhornsby - I’ll check it out

I can verify this works with registering an osc service. Beware there’s a few potential memory leaks, but shouldn’t be a problem in normal use (initialised once). Still interested in adding several services though!

Thanks mars.

Feel free to point out any memory leaks and I’ll look at fixing them up (afraid c is not one of my strengths!). I’ll also take a look at registering multiple services (or feel free to fork on GitHub and send me a pull request :wink:)

Mark

Hi mars,

Just to let you know I’ve published v1.3.0 of the library to the web IDE and this now supports registering multiple services.

Mark

Hi Mark. Thanks for your library.

I have a question considering the mdns.processQueries(); call. I see that it takes about 1000 us. Since I’m running time critical code (LED animations) I want this time as short as possible.

What does this line actually do? And how often do I have to call it?

In the MDNS.cpp I see that it parses some UDP packet, and gets and write responses. What are the responses it gets and what does it write out.

Does this happen the moment I connect with the Bonjour Discovery app?

I hope you can explain this a bit (or point me to information where I can read about that). Thanks in advance!

Hi @kasper

mDNS is a cooperative standard, with no central authority, so that every host has to listen for messages that say things like "Hi, I am new here and I want to be called Particle1" so they can say "No, I already have that name, try again." If any host is not listening for these messages, the whole thing doesn't really work.

It is expected that these messages do not come in at a very high rate and are short so they should not take a lot of time to process. But still it is an unavoidable overhead in mDNS.

Just one other point: there is another mDNS library based on the Adafruit library that is described in the link below, but I don't know if it has been ported to Photon yet.

@bko Does this mean that my Photon also keeps track of all the names on the network? I can imagine that this uses some memory. Is the Photon not running out of memory in case you have a lot of mDNS devices in your network?

I came across that other library, but it's not yet ported (although I think that won't be to difficult).

I don't think this library does that from my casual reading. I think this library is built to answer queries from others, not to do queries and discover and remember other hosts.

The protocol is meant to be very lightweight so that printers and other peripherals on the local net can tell full computers/phones what they can handle; discovery is certainly the goal of Bonjour/mDNS: to find hosts on the networks and learn about their capabilities. You see that in the example code for this library where the Particle device announces the two HTTP ports that it has a server on.

Hi,

bko is correct - this library just responds to queries from other devices, allowing your photon to be addressed by name and advertise services on the network without a central DNS server. The Adafruit library is similar, but only does name resolution, not service discovery. It is likely to be a lot faster as it’s responses are pre-canned, but obviously it doesn’t have the same level of flexibility (I’d previously used this myself, but developed my own library to support the service discovery as well).

Mark

1 Like

Ok. What does service discovery actually do? I suppose it relates to this line in your example subServices.push_back("printer");

Actually the only thing I want is to publish my IP address in some way. So I suppose I can use the minimal example that you’ve posted in the thread above. However I’m curious what the services are and what the benefit could be.

Considering the time it takes. Maybe it related to the Udp firmware as well. Since I found this time also when I tried to parse messages. See this topic: setTimeOut function for UDP?

@mrhornsby

Is it possible to resolve the hostname from another photon using WiFi.resolve(“1stPhotonHostname.local”). I did try this on Redbear Duo. But it does not seem to work.

Hi @preetam,

MDNS hostnames won’t resolve using WiFi.resolve as that will only resolve DNS names. It would be possible to add a resolve method to the MDNS library (re-using a lot of the code that is there) but it would be a reasonable amount of work.

Regards

Mark

Please no double posting

So just to clarify, there’s no current method to do service discovery from the Photon/Redbear Duo? Would implementing an mdns resolve be the best method?

My situation is I have the Redbear being a client to TCP server on a mobile device, and I need to discover the mobile devices IP.

A workaround I’m thinking about is having my server temporarily be a client, the redbear a server, and do mdns from the redbear, then communicate the mobile devices IP via that connection, close connection and re-open in the reverse direction. I don’t like it at all, so I’d prefer an implementation of resolve. Willing to work on it if someone can point me in the right direction!