Apple Bonjour for .Net Core

As part of my work on building a .Net implementation of Apple Homekit protocol, I want to have it run on a Raspberry Pi. My plan is to accomplish this using Windows 10 for IoT. This is basically a cut down version of Windows 10, designed to run .Net Core and UWP apps. I haven’t really explored it very much, but it seems to suit my needs. I can deploy my Homekit service and put the Raspberry Pi in the cupboard.

The first piece of functionality I need for my Homekit implementation is the broadcasting of the accessories using Bonjour. Bonjour is apple’s zero configuration protocol implementation. It is available on Windows, via Apple’s SDK, but unfortunately, it’s a COM component, so running it on Raspberry Pi is a non-starter. I searched around on the internet for a few hours and discovered, to my immense disappointment, that there are no Nuget packages for advertising services over Bonjour. Lots of ones for browsing and searching, but none for advertising.

These kind of situations, whilst annoying, do provide an opportunity to learn something new. What would it take to create a simple implementation of Bonjour that would run on .Net Core, on a Raspberry Pi. Let’s find out 🙂

To get the ball rolling, I created a .Net Core console application in Visual Studio. This doesn’t achieve anything in and of itself, but makes me feel like I’m making progress 🙂

A read through a few articles on Bonjour;

and I was ready to start. General searching around the web, led me to RFC-6762 (https://tools.ietf.org/html/rfc6762), which describes Multicast DNS or mDNS. This is used by Bonjour. I do love a good RFC.

After reading the first few pages, I established the following facts; mDNS, in essence, works by resolving .local addresses e.g. computer.local or hap.local. It does this by sending requests over multicast to the group 224.0.0.251 on the port 5353. I had come across the multicast technology (my router didn’t support it) a few years ago, so I was familiar with the main concepts.

Converting this into code, I came up with

public void Start()
{
 try
 {
 UdpClient udpClient = new UdpClient();

udpClient.ExclusiveAddressUse = false;
 IPEndPoint localEndpoint = new IPEndPoint(IPAddress.Any, 5353);

udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
 udpClient.ExclusiveAddressUse = false;

udpClient.Client.Bind(localEndpoint);

IPAddress multicastaddress = IPAddress.Parse("224.0.0.251");
 udpClient.JoinMulticastGroup(multicastaddress);

while (true)
 {
 Byte[] data = udpClient.Receive(ref localEndpoint);
 string dataAsString = Encoding.UTF8.GetString(data);
 Console.WriteLine(dataAsString);
 }
 }
 catch (Exception exp)
 {
 Console.WriteLine(exp.Message);
 }
 }

This code essentially listens on port 5353 for broadcasts to the group 224.0.0.251.

When I fire up the console app, I just see this

Console

Not much to see. In order to generate some Bonjour traffic, I use an app called Bonjour Browser

I launch this and again, I don’t see much:

Bonjour

However, a few lines appear in my console app:

Console with data

Right now I don’t have a clue what these are, but I can see what might be dns requests.

More detail to follow!

 

Advertisement