Introduction

One of the things I needed to complete my self-written spam-stopper, which acts like an SMTP proxy, is resolving DNS queries, reading SPF1 records, doing reversed lookups, etc. On the .NET (2.0) framework, there is a simple implementation of a DNS component. But it is far from complete. The other project on DNS resolving on CodeProject, C# .NET DNS query component, by Rob Philpott is old, buggy, incomplete, and not supported anymore. It was time to take the official RFCs on DNS and build the application from ground up. I must admit, the influence of Rob's project is there, but the code is definitely not the same.

Background

As mentioned before, the basics of DNS is explained in RFCs. (Request For Comments). These are the RFCs I used for the initial project:

Using the Code

The main core of DNS resolving is the 'resolver'. This class wraps queries into DNS packets and sends them to any DNS server. The response is then decoded into some useful information (at least for programmers, or for me in special ). All my DNS stuff uses the namespace Heijden.DNS. Don't change it in your applications, it gives me some comfort knowing my name is stored in some nice other projects. Don't forget to let me know.

Because I don't want to go immediately into details in this article, I only show the usage of the resolver component to warm you up. As the best way to do this, I have built a Dig class which acts like the good-old-Unix-style dig. Its acts like dig, but it is not a complete dig implementation. It does, however, do everything you want it to, presenting the output in more or less the same format.

The resolver uses the default DNS servers which are used on your Windows machine. A good alternative is to use Resolve.DefaultDnsServers which are the two servers from www.opendns.com and are free to use. The resolver accepts any DNS server, or servers. You can add as many as you need, specifying any IP and/or port number.

The main method to do queries to DNS servers is Query. In the dig example, I used a stopwatch to measure the total roundtrip time.

Give Me More Details

Okay, Dig is good. But, the workhorse is the Resolver class. It has got so many secrets. I will try to reveal all of them.

The resolver uses two main classes to do its work. It uses a Query class and delivers a Response class. Querying a DNS server can be done by the TCP or UDP transport protocols. The main DNS methods can be used synchronously and asynchronously. This took me really much typing work. Some headaches and no sleep to do it right. All responses can be stored in a real-time response cache. It uses the Time-To-Live properties of the response records which can be viewed in the Dig application by doing the same queries over and over again (it counts down the TTL values). The caching of records speeds up applications tremendously.

Public constants, constructors, properties, and methods which can be used on the resolver:

That's about it. The classes in the project are more or less well documented. So, programming must not be so difficult.

Points of Interest

Nowadays, networks have started using the IPv6 range more and more. In this project, IPv6 is 100% supported. An example of this is when doing lookups for the AAAA record or PTR lookups, like this one (PTR on 2001:0610:0000:800a:b192:0087 .5.0.152):

In the Dig example, the translation of the phone-number is done automatically when using NAPTR lookups (can be switched off by the checkbox). The example ANSWER output is edited to protect some data, shown as .... ---- and ++++ , but it works in real-life

History

As of writing, the version of this project is 1.0.0.0:

April 4, 2008: Thanks to Martin G C Davies for fixing the GetDNSServers routine to take only the 'OperationalStatus.Up' interfaces.

April 4, 2008: Thanks to 'gbonnet' for pointing me to the 'NAPTR' records, it is added to the project.

May 20, 2008: Jon Webster has fixed the duplicate entries in DNS servers.

July 18, 2008: Added some handy code to do NAPTR lookups.

Version: 1.0.0.1

May 20, 2008: The source code / demo code is much newer than this article. Almost any possible DNS record is added to the project. But implementation is not complete. Anyone is invited to implement the 'empty' DNS record types.

Share

About the Author

I'm Alphons van der Heijden, living in Lelystad, Netherlands, Europa, Earth. And currently I'm retiring from hard working ( ;- ), owning my own company. Because I'm full of energy, and a little to young to relax ...., I don't sit down, but create and recreate software solutions, that I like. Reinventing the wheel is my second nature. My interest is in the area of Internet technologies, .NET etc. I was there in 1992 when Mosaic came out, and from that point, my life changed dramatically, and so did the world, in fact. (Y)

Hi
First of all, i would like to thank the author for writing such a great article and library

I am using the code in this article for fetching the TXT records o a domain, but they are not being retrieved in any particular order, I mean i am having more than one TXT record for a domain, but when retrieving these records using they are not being retrieved in any particular order.

I've been using it with IPv4 server addresses without any problems, however when I try a IPv6 DNS server address the command times out.

I am able to ping the IPv6 address of the DNS server from the command prompt (this is on WinXP), but attempts to use my app, or the demo app both fail. Any thoughts on known IPv6 issues/workarounds would be appreciated!

i m using your tool in my project. i need to get
WWW A RECORD
for example for yahoo.com
WWW A record is as follows.
www.yahoo.com -> fp.wg1.b.yahoo.com -> eu-fp.wa1.b.yahoo.com -> [ 87.248.112.181 87.248.122.122 ]
i hope you will help me.
regards

Please if someone can help me with getting answer from root server. The following code returns List of name servers for certain domain (addr) queried by some DNS server (dns). This is perfectly working code for any DNS server (my ISP or any ISP in my country). But when i try use k.root-server.net (137.39.1.3) or any root i don't get record NS or A, better I don't know how to get anything. Please help

Root name servers only points to "Top Level Domains" (TLD).
So, you can ask k.root-server.net where the TLD .nl (Netherlands) lives...

Because root nameservers are part of the chicken-egg problem,
the list of worldwide root nameservers are kept in text file.
This is not part of this project, but maybe sometime somebody would include it.
Best place to get this list is:

Make sure you use the 'E164.org' as a DNS server to do the lookups.
When using the phonenumber in the example (+1 800-555-5555) it should work.
I have tried the phonenumber you specified, but it seems there is no record of it in the E164.org database, therefore no answers are returned.
Or maybe to many tries on the nameserver, put you out of business.

Hi have developed a ftp append code in VB.net (.net1.1).
I am creating a TCP socket on port 21 using server hostname.The code work fine in my laptop but when i test in a device with WindowsXPe , i am getting a Dns.Resolve error as "The type initilizer for system.Net.Dns threm exception"
at Dns.Resolve(remoteHost)
Please help me !!!!