Over the last week, I have written a tool to compare the response times of different DNS Servers. This came around after I was dissatisfied with the available tools.
It all started when I set up PiHole for my home network. Wanting to check its performance, particularly as it was serving as a cache for my home network, I looked around for a suitable tool. Most of the tools I found were to check propagation or were web based, and thus were unsuitable. Of those which were suitable there were GRC’s benchmark and namebench. GRC’s benchmark was made for windows and thus wasn’t a great option, as I’ve had problems working with wine. Namebench, which has linux compatibility, is in the process of a rewrite and the old versions rely on old go modules, resulting in difficulty when compiling. This led me to want to write my own program.
My requirements for such a benchmarking program were simple. I wanted it to be simple, fast and have some longevity. I wrote it in C, trying to keep to universal POSIX system calls. After looking around for a bit, I found some code to make DNS requests, which I copied across and modified to suit my needs. Once this was implemented, code to time the requests was added. Some scaffolding to add the testing of different hostnames and servers was added, with the hosts and servers sitting in an easily extensible header file. Finally multithreaded testing of the servers was added, to speed up the process as well as a basic progress meter.
The final program is fairly short, coming in at about 600 lines, including some functions left in for testing DNS requests. It is reasonably easy to add more servers in the future, being only a single file that needs to be changed. Although, I do think there was a trade off in not having a run-time configuration file, there is the ability to add servers through command line options. Additionally, there are command line options to change the number of hostnames used and times each hostname is tested. This is in order to gauge the effectiveness of any potential cache.
In the future, it would be nice to enable the ability to pipe a list of servers and hostnames in addition to specifying them on the command line. Additionally, the program currently only uses Berkeley/UNIX sockets, it would be good to add compatibility with windows sockets for more cross platform compatibility. At the moment it works on Linux and Mac, would be nice to work on all major operating systems. I may end up doing this by changing to an external DNS library, rather than managing this myself. That would probably also make the project more robust, but its work for the future.
I have open sourced the project under an MIT licence. It is available on Github and I would welcome any contributions. Additionally it is available on the AUR.