jdomnitz / net-mdns

Simple Multicast DNS (MDNS) Client/Server
MIT License
23 stars 6 forks source link

QueryUnicastServiceInstances() doesn't work since version 0.33 #50

Closed martinzwirner closed 1 week ago

martinzwirner commented 1 week ago

I'm starting two instances of the same program on my local machine and expect them to discover each other. I found that only one instance discovers the other one. I was able to replicate it with this program:

using System.Net;
using Makaretu.Dns;

namespace MdnsDebugging;

class Program
{
    static void Main(string[] args)
    {
        var instanceIndex = ushort.Parse(args[0]);
        var instanceName = "instance" + instanceIndex;
        var port = 3620 + instanceIndex;

        var serviceProfile = new ServiceProfile(new DomainName(instanceName),
            new DomainName("foobar"),
            (ushort)port,
            [IPAddress.Parse("127.0.0.1")]);
        var mdns = new MulticastService();
        var sd = new ServiceDiscovery(mdns);

        mdns.NetworkInterfaceDiscovered += (_, _) =>
        {
            Console.WriteLine("querying for service " + serviceProfile.QualifiedServiceName);
            sd.QueryUnicastServiceInstances(serviceProfile.ServiceName);
            //sd.QueryServiceInstances(serviceProfile.ServiceName); // workaround for version >= 0.33
        };

        sd.ServiceInstanceDiscovered += (_, e) =>
        {
            Console.WriteLine($"discovered instance '{e.ServiceInstanceName}'");
        };

        mdns.Start();

        if (!sd.Probe(serviceProfile))
        {
            sd.Advertise(serviceProfile);
            sd.Announce(serviceProfile);
        }

        Console.ReadKey();
    }
}

This works with version 0.32, where both instances discover the other one. It stopped working in version 0.33. I found the workaround in line 25.

Is this a bug in the lib or am I using it wrong?

Thank you!

jdomnitz commented 1 week ago

I believe it's actually a fixed bug in the library and a use case problem.

Prior to .33 unicast responses weren't sent in many of the cases they should be. It was actually sending a multicast query response in .32. When two services run on the same port, on the same system, unicast will not work. That holds true for any socket application on Linux or Windows (although with some slight differences between the two).

Can you try setting MulticastService.EnableUnicastAnswers = false and see if that fixes your issue? If so, the library is working correctly.

I don't know your use case but in most cases you don't want to query the service instances asking for a unicast response. In most cases a multicast query response is correct per the specification. That reduces network traffic by preventing other clients from duplicating your query.

martinzwirner commented 1 week ago

Thank you for the explanation.

MulticastService.EnableUnicastAnswers = false fixes the issue. But querying for unicast answers and at the same time disabling unicast answers doesn't feel right. So I'm going to use multicast for now.