Yet another stab at zeroconf on Haiku

DISCLAIMER: I have pretty limited knowledge of network management, avahi/zeroconf/Bonjour/mdns/dns-sd usage, and even less so about networking code, on Haiku or elsewhere, so… expect mistakes ahead :slight_smile:

Hello folks.

Yesterday I tried porting mDNSResponder (Apple’s “Bonjour”) into Haiku, and after much cursing and sweating (I suck at this)… managed to get parts of it working. And even if the work is by no means complete, I thought that maybe some of you might find it interesting enough.

Also… I better write down what I managed to understand, before I forget it all. :slight_smile:

This post is kinda too long… if you’re already familiar with zeroconf/avahi/bonjour… you might want to just jump to the screenshots.

What’s this “Bonjour” thing?

To put it in simple terms… “Bonjour” allows computers in a local network to find each other, without the need to know their IP addresses. Specially useful, if your network uses dynamic IP addresses, and/or to connect to “headless” computers.

For that to work each computer has to be able to (again, I’m simplifying a lot):

  • “Advertise” any services it provides (think… sshd, ftp, barrier/synapse, etc).
  • Be able to “resolve” hostnames into the actual IP addresses (as DNS do for the rest of the internet).

(If there was no DHCP server on the network… the machines would also need to have working Link-Local addressing… not sure if Haiku supports that, BTW).

The Apple’s Bonjour project provides fairly portable source code (at least on its “posix” form) for the first of the items above, and Linux specific code for the second (as far as I managed to understand it). It also provides Windows and MacOS specific code for both, and more, but we don’t care about all that.

It consists of:

  • An mDNSResponder, a.k.a.: multicast-dns daemon/server (/bin/mdnsd).
    you “register” services to this daemon, and it “advertise” them on the network, so other machines can find them.
  • A /bin/dns-sd CLI util that lets you interact with the above server. You can browse for services, or use it to register services, among other things.
  • Some “stand-alone” utilities, aimed at use in embedded, or otherwise more constrained, systems.
    Useful during testing, too! :slight_smile:

For the “other part” (the hostname->IP address resolution), we need something more integrated with the networking stack of the OS.

On Linux it seems that this is accomplished via a “plugin” module system, that lets you alter how that resolution is performed.

The mechanism, seems to be Name Service Switch, which allows you to “hook” different modules/libraries via dlopen(). Apple’s Bonjour provides libnss_mdns-0.2.so for Linux.

On Haiku… the host name resolution is handled (AFAICT), by libnetwork.so, with some code for “netresolv” coming from NetBSD, and as it seems to me that it supports a similar mechanism to load modules (eg: libnss_mdnsd.so.0 in our case)…

I went ahead and stole NetBSD’s nss_mdnsd.c file, and “shoe-horned” it into Apple’s Bonjour makefiles (replacing the Linux code, without looking much into it after it gave its first compile-error).

So… what works?

All builds relatively fine, after some minor patching (had to disable IPv6, and code related to detection of network interfaces changes). Mind you… I barely know what I’m doing, so expect the patch to look… less than ideal :wink:

All the utilities seem to work well enough. No crashes or KDLs at least :stuck_out_tongue:

The “advertise services” part of the equation seems functional enough… I was able to connect to my Haiku machines via ssh from Linux and Win10, using the hostname instead of IPs: ssh OscarL@A760G.local.

What I didn’t manage to get working was being able to resolve “.local” hostnames from within Haiku.

Not even sure if that libnss_mdns.so module is being loaded at all, if it fails to talk to the running mdnd server, or where the problem might actually be.

“Pics, or didn’t happen”

First screenshot shows:

  • Connecting a Haiku PC (hostname: A760G), via ssh, to a Linux netbook (hostname: exo-x355), using IP address.
  • Attempting to connect back via ssh to the Haiku PC, using hostname. Failed.
  • Using dns-sd to browse for machines advertising ssh services. Shows the one running Haiku (A760G), and two netbooks running Linux (exo-x355, suma-c10). This is on Linux side, mind you.
  • Successful ssh connection to Haiku, using ssh <user>@<hostname>.local (instead of the IP).

Second screenshot shows Bonjour Browser running on Windows 10, showing the ssh service from Haiku, with a custom message :slight_smile:

This was accomplished by using the /bin/mDNSResponderPosix, for simplicity, as it makes it easy to test advertising a single service via the command line. I have yet to learn how /bin/mdnsd config files work :smiley:

Issues:

When running Haiku on a VM (VBox), only the host OS was able to resolve the “A760G.local” hostname, other machines on the network… saw nothing.

When running the same Haiku install on bare-metal… I did managed to see “A760G.local” from all the machines eventually… but seemingly, only one at a time? LOL! Might be due to the use of /bin/mDNSResponderPosix, though. We’ll see when I get to properly configure services for /bin/mdnsd.

Final words.

All in all, not a bad outcome for a day’s work… the difficult part was actually learning about all this, and working around my limited skills. At least I’ll be able to connect to my Haiku’s installs by hostname from now on :slight_smile:

I plan to do some patch clean up, and push my changes back to github, later on today/tomorrow. Will update this post/thread with the link to that when its ready.

I’ll start to work on a HaikuPorts .recipe as well, and maybe even provide an mdnsresponder-0.0.0-1.hpkg package to play with.

It also might be worth to see if NetBSD’s version of mDNSResponder can be used as “upstream” instead of Apple’s repo?

Regarding the libnetwork.so / /etc/nssswitch.conf / libnss_mdnsd.so thing… being able to browse “Bonjour” FROM Haiku… we will a proper developer to look at it (or at least an aspiring one, with better skills than mine… it can’t be too hard to find such person :crazy_face:)

Thanks for reading.

18 Likes

Here’s the “haiku” branch of my fork: GitHub - OscarL/mDNSResponder at haiku.

I had to copy some headers from the Haiku repo (as they are not public) and, as I’m still running beta4, I had to use older versions of those, otherwise I got many type errors.

The “haiku-posix-code-only” branch is the same, but with the MacOS/Windows related code removed, to speed up my TextSearch experience :smiley:

7 Likes

A bit of technical background, the support for this builds ontop of two specifications. DNS-SD (Dns Service Discovery) and mDNS (Multicast DNS)

Multicast DNS is a kind of DNS service that runs locally in a LAN network, in it each computer can publish DNS records for itself local to that network, in effect this is a bit like a decentralized DNS directory.

Ontop of this builds DNS-SD, it specifies names and content for records to use to find services on the local network. This can be for example a printer, a http server, a ssh server. etc. there is a really a long list. Games can even publish their local game servers this way if they want to.

Now from the OS side you have two goals you want, one is to have an api for applications that need a certain service. The best example would be the print server on Haiku: it wants to discover remote printers to show them prominently to the user.

The second case is allowing applications to publish records easily, for example a usb connected printer can be advertised to the network so it can be used remotely. Another example would be a http server.

The whole casting architecture apple uses for example also builds on this concept.

These projects are easier to understand code, than mDNSResponder, to understand the concepts:

Using the NetBSD version of mDNSResponder to be used as an “upstream” version needs to be tested and compared with the Apple version.

Hi, nice to see progress on this!

Regarding link local addressing: yes, thisis fully supported. On ipv4, after a while of getting no dhcp replies, you will getan address in the dedicated range for this (starting in 169…). On ipv6 you also automatically get a link local address.

2 Likes

Thanks for the work and the great article about it, will try it

1 Like

First of all, very good article, informative and clear to understand.

Regarding this part where you mention that you were able to see other Hostnames *.local from Haiku… Have you been able to check if could the same patch work for discover and connect to other network interfaces apart from Ethernet?

I am referring to those virtual USB Networking interfaces, that some devices create on UART or FTDI chip channels like ESP32 ESP-IDF
Webserver over USB (RNDIS/ECM/NCM) Or this example closer to what I’m trying to implement from Haiku:

https://learn.bela.io/using-bela/technical-explainers/ip-addresses/

Hi again folks, thanks for the positive reactions, and sorry for the delayed reply. I had no internet for the last few days.

@PulkoMandy, re: link-local. Cool! Will have to try it soon! (guess I wasn’t patient enough to see ifconfig show me the 169.54.x.x address, heh :smiley:).

BTW, while my internet was down, I spend some time trying to integrate Jie Ma’s ZeroConf (GSoC 2009) work.

(thanks to @ilzu for digging up that link on the previous “avahi” thread!).

Jie Ma’s code included:

  • A “Haiku API style” wrapper around mDNSResponder’s libdns-sd.so.
  • ZeroConfBrowser and ZeroConfNotifier apps.
  • Patches to PoorMan to make it advertise it’s http service via Bonjour. (this took the most work to merge)
  • Some patches to Haiku’s network code (that seems to have been already integrated).
  • Minor patches for an unknown old version of mDNSResponder (superseded by my newer patches).

Doubt I got everything right, but… I figured it would be better to have that code in a git repo, instead of as an archive of .diff files against 2009 Haiku code :slight_smile:. Will push that to github to get early feedback, and maybe send it for review to Gerrit (even if only for archival purposes).

@marcoapc, thanks for the links, as usual. My idea of looking closer to NetBSD “version”, is because it might, perhaps, align/integrate better with Haiku’s netresolv code (as it comes from NetBSD). Will of course need to at least run some diffs!

@BetaMadMax. while I haven’t tested anything other than ethernet, mDNSResponder (via /bin/dns-sd -i <interface>) allows you to select which interface you want to use, so I guess as long as your devices appear properly setup on ifconfig’s output, there’s a change it will work? I might be able to test using USB-RNDIS via some old Android tablet/phone.


Did another try at cleaning my patches a bit more. Will push that code tomorrow. It should make it easier to just run cd mDNSPosix && make -j N without much issues.


Edit: Uploaded a hand-made package https://github.com/OscarL/mDNSResponder/releases/download/v0.0.0-dev-haiku/mdnsresponder-0.0.0.dev-1.hpkg for willing guinea pigs early testers (for x86_64 bits).

2 Likes

Quick and dirty instructions for using the package above:

To “advertise” Haiku’s sshd service, using the standalone mDNSResponder tool (make sure /bin/mdnsd is NOT running)

mDNSResponder -v 2 -n `hostname` -t '_ssh._tcp.' -p 22

To do the same, but using /bin/dns-sd:

mdnsd #if its not running already
dns-sd -R `hostname` _ssh "" 22

Note: all the /bin/dns-sd commands expect/require the mdnsd “deamon” to be running already. Kill it and restart it if things seems stuck, or something :smiley:.

To browse for local (as in… the one above) ssh services:

dns-sd -lo -B _ssh

To browse for any services in the network (doens’t works on Haiku yet, try it on your linux/bsd of choice, should detect the services advertised from Haiku, thou):

dns-sd -B _services._dns-sd._udp.

Same, but only for local maching:

dns-sd -lo -B _services._dns-sd._udp.

Basic local testing workflow:

On Terminal, open 3 tabs or 3 windows:

On the first one, run /bin/mdnsd -debug. If you ommit the “-debug” parameter, it will run in the background (“daemon” mode).

On the second, start browsing for any local services:

dns-sd -lo -B _services._dns-sd._udp.

On the third, register the ssh service:

dns-sd -R `hostname` _ssh "" 22

You should see an “Add” event appear on the shell running the “browse” command.

When hitting Ctrl+C on the third tab/window… we should see a “Rmv” event on the one second one… but that seems to be failing right now on my VM.

From other machines in your local network:

Use whatever “bonjour browser” you have available (one for Windows linked on the first post on this thread, avahi-browse should be available on most Linux distros, and mDNSResponder is availabe on at least VoidLinux and NetBSD).

2 Likes

Ahoy Oscar,

I downloaded and installed the package.
I am on 64 bit Haiku R1B4.

If you confirm : I am capable to test it - I mean no need to be on nightly to do so-, then I’m a tester.

Please instrue me, what should I check -
Do I need a reboot ?

I checked Preferences, the net settings panel and applications also.
What should I see ?

Actually my router is not used - I am on net provider’s device that is actually a WiFi repeater only.
A more serious router shares the net among the four flats via wireless devices.

I bought recently a mobile router again, actually I still had not configured and tested but within some days I take some time to tailor it to my settings as I like it SSID and so on.

I have a usb thumbdrive plugged in my personal router, that may be discovered - if needed.

Added some basic documentation on my previous post. No need for reboots. Beta4 is fine, it is what I use.

Only command line apps for now, and no integration with the OS. This is all pretty early stuff, just to show what works already (without folks having to clone/compile).

You are right, sorry -
I jumped at the end, this way I avoided incidentally your explanations/instructions.

EDIT - TAB01 :

~/Desktop> pkgman install ./mdnsresponder-0.0.0.dev-1.hpkg
100% repochecksum-1 [65 bájt]
Ellenőrzőkód érvényesítése a tárolóhoz (BeSly Software Solutions)…done.
100% repochecksum-1 [65 bájt]
Ellenőrzőkód érvényesítése a tárolóhoz (FatElk_64)…done.
100% repochecksum-1 [65 bájt]
Ellenőrzőkód érvényesítése a tárolóhoz (Haiku)…done.
100% repochecksum-1 [64 bájt]
Ellenőrzőkód érvényesítése a tárolóhoz (HaikuPorts)…done.
100% repochecksum-1 [65 bájt]
Ellenőrzőkód érvényesítése a tárolóhoz (KapiX’s Depot)…done.
100% repochecksum-1 [71 bájt]
Ellenőrzőkód érvényesítése a tárolóhoz (LOTE)…done.
The following changes will be made:
in system:
install package mdnsresponder-0.0.0~dev-1 from local file
Continue? [yes/no] (yes) :
[system] Applying changes …
[system] Changes applied. Old activation state backed up in “state_2024-06-20_03:30:05”
[system] Cleaning up …
[system] Done.
~/Desktop>
~/Desktop>
~/Desktop> cd
~>
~>
~> ps | grep mdns
/bin/grep --color=auto mdns 3348 1 0 0
~> mDNSResponder -v 2 -n `hostname`` -t ‘_ssh._tcp.’ -p 22

ps | grep mdns

ls -l /boot/system/packages/mdns*
-rw------- 1 user root 1263851 jún. 20 03:24 /boot/system/packages/mdnsresponder-0.0.0~dev-1-x86_64.hpkg
~>
~>
~> mdnsd
~> dns-sd -R hostname _ssh “” 22
Registering Service HiQ_R1Beta_INSTALL.szabadpart.net._ssh._tcp port 22
DATE: —Thu 20 Jun 2024—
4:14:09.363 …STARTING…
4:14:10.040 Got a reply for service HiQ_R1Beta_INSTALL.szabadpart.net._ssh._tcp.local.: Name now registered and active

CTRL +C


~> ps | grep mdns
/bin/mdnsd 3463 1 0 0
/bin/grep --color=auto mdns 3785 1 0 0
~> ps | grep -E -i mdns
/bin/mdnsd 3463 1 0 0
/bin/grep --color=auto -E -i mdns 3790 1 0 0
~>

EDIT - TAB02 :

Welcome to the Haiku shell.

~> dns-sd -lo -B _ssh
Using LocalOnly
Using interface -1
Browsing for _ssh._tcp
DATE: —Thu 20 Jun 2024—
4:16:06.861 …STARTING…
Timestamp A/R Flags if Domain Service Type Instance Name
4:16:06.880 Add 2 0 local. _ssh._tcp. HiQ_R1Beta_INSTALL.szabadpart.net

CTRL +C


~> dns-sd -lo -B _ssh
Using LocalOnly
Using interface -1
Browsing for _ssh._tcp
DATE: —Thu 20 Jun 2024—
4:21:49.579 …STARTING…
Timestamp A/R Flags if Domain Service Type Instance Name
4:21:49.604 Add 2 0 local. _ssh._tcp. HiQ_R1Beta_INSTALL.szabadpart.net
4:21:57.177 Rmv 0 0 local. _ssh._tcp. HiQ_R1Beta_INSTALL.szabadpart.net

CTRL +C


~>

EDIT - TAB03

Welcome to the Haiku shell.

~> dns-sd -lo -B _services._dns-sd._udp.
Using LocalOnly
Using interface -1
Browsing for _services._dns-sd._udp.
DATE: —Thu 20 Jun 2024—
4:18:30.707 …STARTING…
Timestamp A/R Flags if Domain Service Type Instance Name
4:18:30.727 Add 2 0 . _tcp.local. _ssh

CTRL +C


~> dns-sd -lo -B _services._dns-sd._udp.
Using LocalOnly
Using interface -1
Browsing for _services._dns-sd._udp.
DATE: —Thu 20 Jun 2024—
4:21:39.458 …STARTING…
Timestamp A/R Flags if Domain Service Type Instance Name
4:21:39.476 Add 2 0 . _tcp.local. _ssh

CTRL +C


~>

Unfortunately actually I have no another device or install on my local network.

Otherwise all happened as you described, after I issued the commands.