Click here to Skip to main content
Click here to Skip to main content

Test Your DNS Response Times with DNS Tester

, 27 Mar 2007
Rate this:
Please Sign up or sign in to vote.
Check the response times of your DNS and compare with other servers.

DNS Tester Screenshot

Introduction

This article discusses a tool that can be used to analyse your DNS performance. It checks the timing of DNS requests between two DNS servers, and displays the results. Download the tool and enter your DNS. I suggest testing it against 4.2.2.1 which I have found to be a very good public DNS. Enter your proxy if needed, and click Test. A few seconds later, you can compare your DNS with 4.2.2.1.

Background

Recently, I had problems with web pages not displaying the first time they were used. If I refreshed the web page, it would then display. I suspected problems with DNS, and seemed to resolve the problem by interchanging the primary and secondary DNS that my provider assigned. Although this seemed to work, I didn't really know why, and then decided to create an analysis tool to check the DNS performance. (For a review of DNS fundamentals - see the CodeProject article by Pawan Bangar titled "Know How DNS Works".)

When a web page is displayed, the first request is a DNS query to resolve the domain name, such as www.google.com, into an IP address. If this name resolution is slow, then web pages may be slow to load, or timeout. Normally, you have two DNS servers assigned so that if the primary DNS server fails to respond, then the secondary is used.. The sequence of queries is:

  • Ask the primary DNS to resolve the name.
  • If times out after 1 second with no response, ask the secondary DNS.
  • If times out after 2 seconds, ask the primary DNS and ask the secondary DNS.
  • If times out after 4 seconds, ask the primary DNS and ask the secondary DNS.

Normally, there will be a response with a name resolution for the first question, so the escalation sequence is not required. The DNS server will respond with the name resolution if known, or else, it will pass the request to another DNS server (higher in the chain - so to speak) for resolution. When the DNS server is required to ask for another DNS server to resolve the name, then it caches this name and IP resolution so that if the same name resolution is required later, then it is known. (This name resolution is also cached by your own router.)

There are quite a few DNS response tools on the internet such as www.dnsstuff.com, but all the DNS requests that are made by these tools are from their location, and so timings may be different. In addition, many providers have closed their DNS servers so that they can only be used by their customers.

Using the code

When a DNS request is made, the returned answer is cached by the DNS server so that the second time a DNS request is made, then another request will return the result immediately because of local caching. In order to find out the real DNS performance, I use Google to compile a list of random web sites.

First, make a random three character alphabetic string. (I can imagine that some people will cringe at this blatant misuse of a function, but it was quick!)

RNGCryptoServiceProvider rng = 
        new RNGCryptoServiceProvider();
rng.GetBytes(random); 
// The array is now filled with random bytes.
for (i=1;i<256;i++)
{
   // Just take the first three letters
   if (random[i] > 0x40 && random[i] < 0x5b)
       Letters=Letters+Convert.ToChar(random[i]);
   if (Letters.Length == 3) break;
}

Then, use this random string to make a Google search:

WebRequest GoogleRequest = 
  WebRequest.Create("http://www.google.com" + 
                    "/search?num=100&q="+Letters);
WebResponse GoogleResponse = GoogleRequest.GetResponse();
Application.DoEvents();
// Get the response stream.
Stream GoogleStream = GoogleResponse.GetResponseStream();
StatusBoxPrint("Google response received");
// Use a StreamReader to read the entire response
StreamReader GoogleReader = new 
   StreamReader(GoogleStream, Encoding.ASCII);
string GoogleString = GoogleReader.ReadToEnd();
// Close the response stream
// and response to free resources.
GoogleStream.Close();
GoogleResponse.Close();

Now, parse this received web page for web addresses ending in ".???.com":

Regex Dotcom = new Regex("[.]([A-Za-z]*)[.]com"); 
// Use the Matches method to find
// all matches in the input string.
HostNames = Dotcom.Matches(GoogleString);

Then, duplicate names are removed and the domain names are used for the DNS requests. A socket is created for UDP, and DNS requests are made to the two DNS servers at the same time. The current time is saved before the DNS requests are sent so that the delta time can be calculated. A DNS packet contains two bytes at the beginning to enable the requester to keep track of the answers, called transactionID. These bytes are set to "Q1" or "Q2" for the request. This is a little unorthodox, but when an answer is received, this allows easy checking of whether the received packet is relevant to this program and determines the DNS server that has responded.

Socket DNSsocket = new Socket(AddressFamily.InterNetwork, 
       SocketType.Dgram, ProtocolType.Udp);
DNSsocket.SetSocketOption(SocketOptionLevel.Socket, 
       SocketOptionName.ReceiveTimeout, DNSReceiveTimeout);
IPEndPoint dnsEP1 = new 
   IPEndPoint(IPAddress.Parse(DNSAddress1),IPPort);
IPEndPoint dnsEP2 = new 
   IPEndPoint(IPAddress.Parse(DNSAddress2),IPPort);

// Start the clock
StartTime=DateTime.Now.Ticks;

for (i=0;i<URLNamescount;i++)
{
   URLNameStart = 
     URLNames[i].Substring(0,URLNames[i].IndexOf("."));
   DomainName = 
     URLNames[i].Substring(URLNames[i].IndexOf(".")+1, 
     URLNames[i].Length - URLNames[i].IndexOf(".")-1);
   // Build the query 
   QueryString = TransactionID1 + TypeString + 
                (char)URLNameStart.Length + 
                 URLNameStart + (char)DomainName.Length + 
                 DomainName + TrailerString;
   Sendbytes = Encoding.ASCII.GetBytes(QueryString);
   DNSsocket.SendTo(Sendbytes, Sendbytes.Length, 
                    SocketFlags.None, dnsEP1);

   // send the same message to both DNS servers
   // except for the transaction ID
   QueryString = TransactionID2 + TypeString + 
                (char)URLNameStart.Length + 
                 URLNameStart + (char)DomainName.Length + 
                 DomainName + TrailerString;
   Sendbytes = Encoding.ASCII.GetBytes(QueryString);
   DNSsocket.SendTo(Sendbytes, Sendbytes.Length, 
                    SocketFlags.None, dnsEP2);
}

When answers are received, they are checked as valid "Q1" or "Q2" and decoded. The request made is added to the listview and displayed. If no more answers arrive after timeout, then we can analyse the data and test again.

Points of interest

An excellent CodeProject article "C#.NET Query Component" by Rob Philpot formed the starting point for the DNS requests. At first look, these methods looked too difficult for me, so I tried a few other ways of checking DNS. I started by trying the Dns.Resolve method, and also tried Dns.GetHostByName. This method was able to get DNS answers, but I ran into a brick wall when I needed to get the DNS from a different server. The Dns.Resolve method uses the computer defined DNS. I experimented with using netsh to change the DNS, but I found that this seemed to take several seconds. Then, I got a hint on the net from Eric Meyers on www.dotnet247.com to use nslookup and call it using Start.Process. This seemed to be a way around the inability of Dns.Resolve to use multiple DNS servers, but I found that I could not call this with window minimized for some reason. At this time, I also saw that using these ideas to check the DNS of 30 or 40 names would be very time consuming at several seconds per check. I moved over to the UdpClient class. The UdpClient.Send method worked okay for sending multiple DNS requests, but the UdpClient.Receive would not work for me. There seemed to be no way to stop listening! I saw several references on websites that this class should be avoided like the plague, and I can agree with this.

I finally came back to the socket class, and got it working for me. One tool that I found extremely helpful was Ethereal. It is an open source Ethernet protocol analyser which is available for download here. For examining just the UDP DNS packets, set the filter to "port 53".

One thing that really opened my eyes was how my ISP provider DNS drops requests. I have found that the best public DNS is 4.2.2.1. Comparing this public DNS against my DNS shows that my DNS drops about half the requests! UDP packets used by DNS can be lost and, unlike TCP, is not a guaranteed delivery protocol. In this program, I only ask the DNS for the A record once. If it does not answer, I consider this a failure. The DNS 4.2.2.1 seems to almost always answer. Based on my results so far, I think that this tool can show you the best DNS to use. There is some blocking while the DNS results are received, and so my next projects with the socket will try asynchronous sockets.

History

28 Mar 2007 - Updated source download

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Charles Putney

Ireland Ireland
My first experiences with computing was with a Bendix G15 drum computer at Carnegie Mellon. More followed with CDC G20, IBM 360, Univac 1108, Apple II, and 386XXX. I have done microprocessor programming and design for 6502, Z80, and 8051. I have moved to C# now and am still struggling to understand this. My career has been in engineering starting with Texas Instruments and continuing with Becton Dickinson, Dataproducts, Hitachi Printing Solutions and now retired from Ricoh Printing Systems Europe.

Comments and Discussions

 
QuestionKeeping it Simple Pinmemberxkxhx118-Dec-12 23:17 
GeneralExcel Analysis Pinmemberebloch16-Jul-09 10:06 
GeneralRe: Excel Analysis PinmemberCharles Putney17-Jul-09 7:59 
GeneralRe: Excel Analysis Pinmemberebloch17-Jul-09 11:48 
GeneralRe: Excel Analysis Pinmemberdbjohnson212-Dec-09 15:39 
GeneralRe: Excel Analysis PinmemberCharles Putney12-Dec-09 23:30 
GeneralRe: Excel Analysis Pinmemberdbjohnson213-Dec-09 6:21 
GeneralA great tool - thank you PinmemberMark Dods13-Jul-09 17:02 
QuestionCan you change the 5 second timeout? PinmemberMikeBlyth18-Dec-08 4:04 
AnswerRe: Can you change the 5 second timeout? PinmemberCharles Putney24-Dec-08 3:57 
GeneralGreat tool, something i've been looking for but never found. Pinmemberasdkasd12-Jul-08 4:40 
QuestionDNStester +NT4? Yes or No? PinmemberShawn McClelland16-Jun-08 10:47 
AnswerRe: DNStester +NT4? Yes or No? PinmemberCharles Putney16-Jun-08 22:21 
QuestionHow to resolve subdomains Pinmemberbas0070117-Oct-07 6:30 
QuestionWere can i find the defined DNS Server? PinmemberFan Feng3-Sep-07 21:16 
AnswerRe: Were can i find the defined DNS Server? PinmemberCharles Putney6-Sep-07 22:18 
GeneralRe: Were can i find the defined DNS Server? PinmemberFan Feng6-Sep-07 23:22 
Generalgracias :) Pinmemberfgonzaro72-May-07 13:08 
GeneralRe: gracias :) PinmemberCharles Putney3-May-07 11:47 
Generaltesting domains other than .com PinmemberPaul Betteridge26-Apr-07 1:36 
AnswerRe: testing domains other than .com PinmemberCharles Putney3-May-07 11:37 
GeneralRe: testing domains other than .com PinmemberPaul Betteridge3-May-07 23:06 
GeneralRe: testing domains other than .com PinmemberCharles Putney4-May-07 2:46 
Generalbuild error Pinmemberipsection27-Mar-07 4:19 
AnswerRe: build error PinmemberCharles Putney27-Mar-07 12:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141220.1 | Last Updated 28 Mar 2007
Article Copyright 2006 by Charles Putney
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid