MDNS and DNS Service Discovery library

Is it possible to subscribe for services or it can still only create services? As I cannot resolve the host IP, I was planning on creating a service on my host which will transmit it’s IP address and the photon could subscribe to that service and get the host IP

Hi @moz,

Locating services (DNS-SD) uses the same resolve functionality as resolving hostnames so is not supported right now.

Mark

So that would mean there is currently no way to resolve the host IP from a particle photon using the mDNS. Is there any other way to accomplish something similar in a dynamic network system? The ultimate purpose of introducing the mDNS was to solve this issue but it is sad to see it is not available on the particle yet.

Can you point me to exactly what all will be needed to add this functionality as I want to do it. As far as I understand, it would require to form a QTYPE A packet and transmit it on the group. After which it waits for a response. It takes in the response, parse them and take out the IP address of the sender/host.
Is there any hints or tips you would want to give? What are the specific functions in your library that will help me in this?

Hi @moz,

Correct, you can re-use some of the existing classes to build a query packet, send it out over UDP and then wait for responses. You’d need to consider how long you want to block waiting for responses or whether you can successfully poll for a response every so often.

Mark

Hey. I was testing your example function and after some time the core-1.local/ seems to stop working. I am guessing it is disconnecting from the mDNS group. Any ideas on why this is happening?

Hi @moz,

I’ve seen issues with this in the past, but not for a while. What hardware are you using and which version of firmware? Have you modified the sample code at all?

I’ll try to replicate if you can give me the above details.

Thanks

Mark

I was using a particle photon with base OS as 1.2.0 and the code was target at 1.1.0-rc.2
I was using your base code without any modifications

Hi @moz,

I’ve just tried to replicate your issue and I’m not having any luck. I’m using the web ide so could only target 1.2.1, but my Photon has been up and responding to continual connections to it’s http service for over 40 minutes. I’ve seen one or two closed connections and a pause of a few seconds here and there, but it always continues shortly afterwards.

When you say it stops working what exactly is happening? Is it failing to respond to MDNS requests or failing to respond to HTTP (on port 80 or 8080?)

Mark

So what was happening was I was not ale to access the core-1.local/ from my browser after some time.

Hi @mrhornsby,

Funny that just today you committed something to the library again after 2 years!
I have been using your library for a long time now, but some things where nagging me about it. I just never found time to address them before. Well, the last couple of days I took a deep dive into MDNS and refactored the library to address the issues I had. It turned out to be a huge rewrite.

My biggest concern with the implementation was memory use. Memory is sparse on the photon and this library was one of the biggest users. I disliked the use of std::map to hold just a few entries. I also thought having the map for the labels, pointing to entries that hold the exact same labels but in a slightly different form was a bit wasteful. Records referring to labels and labels referring back to records, sometimes directly, sometimes through the map index, it made the code hard to follow.

Another big discovery was that I could use the buffer of the UDP class directly, which saves 512 bytes of RAM and unnecessary copying.

My app, implements just 2 services as shown below.
Compared to your original implementation, I was able to reduce RAM memory use by 1194 bytes. Code size is 418 bytes smaller.

MDNS&
theMdns()
{
    static MDNS* theStaticMDNS = new MDNS(deviceIdString());
    return *theStaticMDNS;
}

void
initMdns()
{
    MDNS& mdns = theMdns();
    mdns.addService(MDNS::Protocol::TCP, "_http", deviceIdString(), 80);

    std::string hwEntry("HW=Spark ");
    switch (getSparkVersion()) {
    case SparkVersion::V1:
        hwEntry += "1";
        break;
    case SparkVersion::V2:
        hwEntry += "2";
        break;
    case SparkVersion::V3:
        hwEntry += "3";
        break;
    }

    mdns.addService(MDNS::Protocol::TCP, "_brewblox", deviceIdString(), 8332,
                    {"VERSION=" stringify(GIT_VERSION),
                     std::string("ID=") + deviceIdString(),
                     "PLATFORM=" stringify(PLATFORM_ID),
                     hwEntry});
}

I have pushed my implementation to GitHub here. The readme also describes the changes in more detail.

Check the develop branch, or the PR between master and develop to see changes.

I look forward to your view on these changes. I was a novice in MDNS before I started refactoring this and have gone through many RFCs during this refactor. I checked the packages with Wireshark and they seem (nearly) identical.

I didn’t send you a PR yet, because it is such a major refactor. I’d like to hear your thoughts about it first.

2 Likes

Hi @Elco,

Awesome work. It looks to be a really valuable set of improvements and I’m sure the reduced memory requirements will benefit a lot of people.

I’m not actively developing the library, I only did a quick fix to namespace and avoid the clash with the NFC Record class, but I’d be happy to look at a PR. Are you testing on the latest generation of devices or just Photon P1? (Not sure how much time I have to test)

Mark

I don’t have any gen3 devices.

Any particular reason that you are not using a namespace block in cpp files?

namespace mdns {
void function(){}
}

vs

void mdns::function(){
}

Lack of CPP skills :grin: