RoBlog - Refactoring reality

Wednesday, January 12, 2005

Name resolution in .Net - arrrrrggghhhh!

Current Status: Red

What could be simpler than resolving a name using System.Net.Dns.Resolve?

The documentation states:

"The Resolve method queries a DNS server for the IP address associated with a host name or IP address."

"When hostName is a DNS-style host name associated with multiple IP addresses, only the first IP address that resolves to that host name is returned."

Pretty simple stuff eh? After all, the process of name resolution via DNS is hardly a black art. It is well understood and easily learnt with the help of a tool like nslookup.

Except one thing; both the assertions given in the documentation quoted above are incorrect.

The second assertion is quite clearly wrong. This method returns an IPHostEntry instance, which has an AddressList property. This property is an array of IPAddress instances. A quick test of this method reveals that this list will conatin more than one item if the name resolves to more than one IP address. Black mark number one.

Now to the first assertion. I have a box which has two network adapters. One of these adapters is to a network with private non-routable ip addresses and no routing/bridging is allowed between the networks; the ip address of this NIC is 10.0.0.5. The private network has no DNS server, and there are no host file entries for hosts on this private network. The other network card connects to my main subnet which has all the usual infrastructure such as DNS; the ip address of this NIC is 192.168.0.2

My machine is called 'terminus'. Terminus has one single entry in the DNS, which resolves to 192.168.0.2. A quick test with nslookup confirms that this hostname has a single A record to point to this ip address.

Why then, when I call
System.Net.Dns.Resolve ( "terminus" )
do I get both IP addresses returned? If this method did what it said, I would only get the 192.168 address returned. I even get them in a perverse, reverse order where the 10.0.0.5 comes first. The fact of the matter is that this method does *not* do what it says; or perhaps it does what it says and then does some other things too.

Using
nbtstat -a terminus
reveals that the NetBIOS name cache contains both these IP addresses, and in the order the Resolve call returns them.


I used a reflector to look into how the Resolve method works, and it just appears to call the Windows Sockets function gethostbyname. Firstly, this method is quite clearly marked as deprecated in the documentation (so why is the .Net Framework 1.1 using it), and secondly even the documentation for this call does not detail what it actually does!

My feeling is that this function harks back to the NetBT days of NT when it was preferable to try and resolve names via WINS or NetBIOS broadcasts as well as IP. However, this is not what the documentation says the function does, and there appears no way of actually doing a basic DNS lookup with nothing else.

I have wasted a few days debugging problems that are directly attributable to this and am pretty cross about it! Have I missed something obvious, or is this function as misleading as it seems?

Is there a way of only doing a DNS lookup from within the .Net framework (akin to using nslookup)?

1 Comments:

  • At 10:15 PM, Anonymous Anonymous said…

    yup, the documentation's a bit buggered. one tip though, reflector is good but there's also the Mono source code available. it's not going to be an identical implementation but the end result should be the same so it'll offer you some more insight

     

Post a Comment

<< Home