Recent

Author Topic: mDNS name resolution with Lazarus (hostname.local)  (Read 4497 times)

MementoMojito

  • Jr. Member
  • **
  • Posts: 63
mDNS name resolution with Lazarus (hostname.local)
« on: September 27, 2016, 10:48:08 pm »
Hi,

Sorry to ask a bit of a general question but I couldn't find much information about it.
Is it possible to resolve mDNS domain with Lazarus in a cross-platform way (so without calling avahi-resolve as I believe it's only *NIX compatible)?
So far I have tried TIdStack.ResolveHost() but unfortunately I have hard times using it it for some reasons it just keep crashing with an "Abstract method called" error:

Code: Pascal  [Select][+][-]
  1. uses IdStack;
  2. procedure ResolveHostName;
  3. var
  4. GStack : TIdStack;
  5. begin
  6. GStack := TIdStack.Create;
  7. GStack.ResolveHost('www.google.com'); //Crash here
  8. GStack.free;
  9. end;
  10.  

I have also tried to use netdb and ResolveHostbyName() but if it works for fully qualified domains it seems to fail to resolve mDNS domains...
If anyone know if IdStack is capable to resolve it and how to use it?
Or any other method that works on both Linux and Windows ; it would be really helpful as for now I am doomed to scan my LAN network to find one of my server from my Laz project.
Thanks!

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: mDNS name resolution with Lazarus (hostname.local)
« Reply #1 on: September 28, 2016, 01:00:47 am »
Try creating an instance of GStackClass instead of TIdStack.

MementoMojito

  • Jr. Member
  • **
  • Posts: 63
Re: mDNS name resolution with Lazarus (hostname.local)
« Reply #2 on: September 28, 2016, 01:25:05 am »
Thanks so much engkin.
I could find how to use IdStack on doing a search on GStackClass.
The following code works to resolve FQDN:

Code: Pascal  [Select][+][-]
  1. var
  2. GStack:TidStack;
  3. begin
  4.    GStack := IdStackFactory;
  5.    showmessage(Gstack.ResolveHost('www.google.com'));
  6.    GStack.Free;
  7. end;
  8.  

No sure f it's the correct way to create an instance of GStackClass, please let me know if it's wrong.
However I have the same problem to resolve my domain raspberrypi.local ; it doesn't return anything. Which is quite annoying as it works really well with Python (not tested on Win tho) :

Code: Pascal  [Select][+][-]
  1. $ python -c 'import socket; print socket.gethostbyname("raspberrypi.local")'
  2. 192.168.1.248
  3.  

I can live without it and/or implement a solution for *nix platform but it would have been great to have a multi-platform solution. Even if I understand that mDNS is not quite like DNS and MS implemention is really different from Bonjour/avahi.
But if anyone has a suggestion I am really up to hear it.

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: mDNS name resolution with Lazarus (hostname.local)
« Reply #3 on: September 28, 2016, 06:47:35 am »
Guessing based on what I just read. mDNS packets are sent to:
Quote
IPv4 address 224.0.0.251 or IPv6 address FF02::FB
Quote
UDP port 5353

Indy has a constant for the IPv4 address 224.0.0.251: Id_IPMC_mDNS.

I assume the host (raspberrypi.local) would respond using multicast address 224.0.0.1 (Id_IPMC_All_Systems) to notify every host on the network.

Using Indy, you can send the request through TIdIPMCastServer (set the group to Id_IPMC_mDNS, and the port to 5353), and receive the answer using TIdIPMCastClient (the group is Id_IPMC_All_Systems).

MementoMojito

  • Jr. Member
  • **
  • Posts: 63
Re: mDNS name resolution with Lazarus (hostname.local)
« Reply #4 on: September 28, 2016, 11:49:36 am »
Thaks again engkins for your really helpful answer.
It looks like TidIPMCast could be a really good solution. However I have just tried to play with TidIPMCastServer and just got a "Error reading IdIPMCastServer1.BoundPort: Unknown property: "BoundPort"." error...
I will try to install the latest Indy version and see if it still happens even if I have the feeling it will as it looks this compo hasn't been touched since 2004.


 

TinyPortal © 2005-2018