How to use mDNS / Bonjour to resolve a host name?

I am doing some work on a binding, and I need resolve a local mDNS host name (like) something.local into a dotted ip address (like) 192.168.0.123.

Can someone (e.g. @Kai) point me to a code example how to do this?

I know that the OH core harnesses mDNS for general for service discovery, so can I hook into that in some way to do a specific host name resolution?

PS I have looked at JmDNS on GitHub, but the example in the readme is very sparse.

Does https://www.openhab.org/docs/developer/bindings/#mdns-discovery help you?
That’s the standard mechanism in openHAB to use mDNS discovery.

HI @Kai many thanks for responding, but no, that page does not help me.

I have created a class that implements MDNSDiscoveryParticipant but it is only half working…

My implementation does successfully discover ServiceInfo instances for devices having an mDNS name like VELUX_KLF_LAN_3C24._http._tcp.local.. However I also need to know their IP address, and unfortunately the ServiceInfo.getHostAddresses() method returns an empty list. *)

*) I think this might be a bug in JmDNS. Or at least a lacking feature. I can see from WireShark that the Velux bridges do not include their IP address explicitly in their mDNS query response datagram. (I guess that’s at least a bug on the part of Velux). But I think that JmDNS could still recover from such errors implicitly by including the source IP address of the reply datagram in its ServiceInfo.getHostAddresses() list.

Nevertheless, my current workaround is to force a mDNS name resolution on the hostname VELUX_KLF_LAN_3C24.local to get its respective IP address, by using the following code…

@Override
public @Nullable DiscoveryResult createResult(ServiceInfo serviceInfo) {
    if (serviceInfo.getName().startsWith("VELUX_KLF_LAN")) {
        try {
            String ipString = InetAddress.getByName(serviceInfo.getName() + "." + serviceInfo.getDomain()).getHostAddress();
            .. discover device with ipString ..
        } catch (UnknownHostException e) {
            // fall through
        }
    }

This does seem to work (on openHabian), but I am worried that InetAddress.getByName() might not work on all operating systems for mDNS host names on the .local domain. => So I am wondering if there is a JmDNS.getByName() equivalent that I should use?

In the mDNS discovery service I wrote, I ended up calling serviceInfo.getInetAddresses() rather than getHostAddresses(). Here it is, if you want to take a look at it. I wouldn’t exactly hold it up as an example of superior coding, but it does generally seem to work. :slight_smile:

Sounds like a feasible option to me, but if the device indeed does not provide any IP address, I wonder whether this info is available in @AndrewFG’s case?

@AndrewFG, if the device sends a hostname instead of an IP address, I would also claim that this is a bug on their side. But why do you actually require the IP address? Couldn’t you simply use the hostname in that case and simply assume that the host can resolve that through DNS? If it can’t InetAddress.getByName() would anyhow fail as well for sure, so I wouldn’t even try it.

It is not. (Unfortunately)…

The binding bridge has a Config Parameter = ipAddress; and I don’t want to recode the whole thing to (try to) work with Host names…

@Kai, that is exactly my point. I don’t trust InetAddress.getByName() either. That is why I am asking if there is some way to force the resolution via mDNS rather than via DNS. The former must theoretically have (had) the information, since it received the datagram from the device having the respective source IP address.