DnDns - A .NET DNS Client Library (Resolver)UPDATE: Also see this post on DnDns update.
I've been sitting on the source code for a DNS resolver library I wrote for a few years now, wondering what to do with it - and too busy to really think much about it anyway. Finally I've decided to release it on CodePlex under the new BSD License for others to learn from and use.
It was originally done using .NET 1.1 - I've ported it to .NET 2.0 - though there is no real differences between the two versions. It is a fully managed implementation written in C# - I suspect it will run just fine on Mono since there's no specific MS Windows namespaces required...but I haven't had time to try it out yet - if anyone has a chance to try it out, let me know how it goes.
The project on CodePlex is located here:
DnDns - A .NET DNS Client Library
Doing a standard 'nslookup' on www.google.com would be done like this in code:
To do a normal Host (A) lookup:
1 DnsQueryRequest request = new DnsQueryRequest();2 DnsQueryResponse response = 3 request.Resolve(dnsServer, "www.google.com",4 NsType.A, NsClass.INET, ProtocolType.Udp);
1 DnsQueryRequest request = new DnsQueryRequest();2 DnsQueryResponse response = 3 request.Resolve(dnsServer, "gmail.com" 4 NsType.MX, NsClass.INET, ProtocolType.Udp);
I enjoy implementing protocols. My first network protocol I implemented was a Quake 2 server browser in Java - you could find Quake servers on the Internet and also check out the score of a game that was in-process from a particular server (very similar to early versions of GameSpy Arcade). After that I was hooked - leaning the internals of how the Internet functions is fascinating to me.
I went on to implement a FTP client, a native SMTP mailer (the main reason being that .NET 1.1 required Outlook/CDONTS installed to handle SMTP which was overkill of a requirement), a Syslog listener for keeping tabs on my Firewalls, FreeBSD Servers, and routers - which I'm also working to release soon as a part of another project I'm working on (stay tuned), and the protocol of this discussion, DNS.
In retrospect, the DNS client was probably the most interesting protocol to implement. It's clear the goal in the DNS protocol was to be very light weight and to utilize very little bandwidth. I enjoyed seeing how these efficiencies were implemented in the protocol back when a bandwidth was not as available as it is today.
It's not simply because they choose originally to use datagrams (UDP) that makes the DNS protocol light weight - though that's part if it - it's how the data is packaged for transmission. If that sort of thing interests you, check out section 4.1.4 titled "Message Compression" in RFC 1035. It is an incredibly simplistic type of compression...to reduce repetition of domain names in the message, they stored pointers throughout the message that point to previous occurrence of the same name so names are never duplicated within a message. It's surprising how little space this seems to save, but I suspect every little bit of savings were important back when the system was originally created.
Below is a list of the RFC's I used to implement the DNS client library (as well as Ethereal which was indispensable of course):
Again, here's the link to the DnDns project on CodePlex:
DnDns - A .NET DNS Client Library
Samples are provided on the CodePlex site. Feedback, problems, and suggestions are welcome.