This article covers the details and explanation of my mDNS library in PHP. If you just want to go straight to the library, it’s available on github here.
For more information and principles, read on…
What is DNS?
Most internet addresses have a friendly name and an actual address. Take this website – the friendly name of www.chrisridings.com points to the actual address 188.8.131.52 . The first name is easy for humans to work with, the second name is easy for computers to work with.
So, when you type the friendly name into your web browser then your computer adjusts it behind the scenes. The friendly name is known as a domain name, so it does this by communicating with a “Domain Name Server”. Although this can get quite complicated, it’s easier to just view a “Domain Name Server” as a directory between domain names and the actual addresses (known as IP addresses).
This whole system of servers running directories and conversion process is known as the Domain Name System (DNS for short).
What is mDNS?
Now imagine I have devices on my home network. These also have friendly names and actual addresses. There’s two problems with having DNS servers. The first is obvious – we’d have to have a server and that seems overkill for a home network. The second is that the actual addresses of devices change quite a lot behind the scenes. We’d be constantly updating the server!
Enter mDNS. With mDNS the approach is slightly different. Say your computer wants to convert a friendly name to an actual address that it can use. Perhaps it’s looking for the Chromecast attached to your television and it knows the friendly name. Instead of contacting a particular server, it sends a message to every device on the network asking if they know what the address of it is.
If one does, and it is quite often the device itself, then it replies.
Essentially mDNS replaces having a particular server for the job with shouting across the network “Who knows this”. Which is inefficient, but more practical for smaller networks.
What is DNS Discovery?
DNS discovery is a manipulation of the DNS system. In short, instead of just being able to ask the questions “What is the actual address for this domain name/friendly name?” or “What is the domain name/friendly name for this actual address?”, we can ask things like “What devices provide this service?”. Given we often know what services particular devices provide, this is also often another way of saying what devices are available. (e.g. what Chromecasts are on the network).
When we combine this with mDNS, we have a method of asking everything on the network what devices support, for example, Chromecast services. (e.g. a way of discovering Chromecasts).
Why a library and why PHP?
PHP is a popular language for writing web apps. Traditionally mDNS isn’t done by web apps. But because mDNS is used by many popular modern devices (Chromecasts, Apple devices, etc) it could be useful to develop web apps that can discover these. Local hobbyist servers are also often running web servers and running web apps, so that a PHP library could also be used to discover and control your local devices.
It’s also an interesting challenge to see if PHP can do it.
Square peg, round hole
PHP isn’t really the best choice for this task, or designed for it. Like most web languages it’s rather functional/linear in nature and any form of DNS is a parallel task with unknown timings (we do not know how long it will take a device to answer, or even if it will answer at all). This means we have to introduce time delays for responses, do various tricks, and hope that things work.
Further, whilst PHP has networking functions. To make a DNS client means we have to work at quite a low level. For the timings mentioned in the previous paragraph, we’re already hoping that the buffers in the operating system will help out and this low level work makes it even hard because we want to work on all operating systems and at a reasonable speed.
Essentially, that’s trying to put a square peg in a round hole. If you bash hard enough, it eventually goes through and it seems to work.
State of Development
At the moment I’ve only implemented the main queries a DNS client will want to perform. This is enough to discover devices and get their addresses. Whilst I’ll apply bugfixes, it’s unlikely that I’ll personally code it further unless a project I have needs it.
People are, of course, welcome to contribute any enhancements or fixes on github on the project page here.