Reverse DNS lookup and Java

by Dejan Bosanac

Recently as a part of the larger Java project, I had to write the code that will convert IP address into the appropriate host name.
The first obvious solution was to use java.net.InetAddress object and its getHostByName() method. For example:
InetAddress addr = InetAddress.getByName("208.201.239.36");
System.out.println(addr.getHostName());
should print
www.oreillynet.com
which is all fine.
The problem starts when you encounter an IP address for which there is no host name that could be found.
To demonstrate this, we will rewrite the previous example in the following manner
long before = System.currentTimeMillis();
InetAddress addr = InetAddress.getByName("192.168.4.1");
System.out.println(addr.getHostName());
long after = System.currentTimeMillis();
System.out.println((after - before) + " ms");
Now, let's suppose that there is no such address defined in your local network and that there is no reverse DNS properly set. The code snippet from above will print something like this
192.168.4.1
4737 ms
What is important here is that it took nearly 5 seconds to resolve this address, which is practically unacceptable for most of the applications. This behaviour could be easily encountered if you are using the Windows platform.
There are various sources on the Internet that suggests that this problem could be solved by adding a reverse DNS entry for the specified host.
For example, the following line
192.168.4.1	192.168.4.1
in the
%WINDIR%\System32\Drivers\etc
on the WinXp host will make the previous code to execute in 90 ms insted of 5 seconds.
But in my case, I need to deal with any IP address and program needs to work fast enough on any machine. So I looked up for the library that could help me.

dnsjava project is much more than I needed, it's an implementation of DNS in Java, but it solved my problem.
Since I didn't find any example of how to issue reverse DNS queries with dnsjava, I'll post it here. The point is to create the replacement for the getHostName() method.
import org.xbill.DNS.*;
import java.io.IOException;

public class ReverseDnsTest {
public static String reverseDns(String hostIp) throws IOException {
Record opt = null;
Resolver res = new ExtendedResolver();

Name name = ReverseMap.fromAddress(hostIp);
int type = Type.PTR;
int dclass = DClass.IN;
Record rec = Record.newRecord(name, type, dclass);
Message query = Message.newQuery(rec);
Message response = res.send(query);

Record[] answers = response.getSectionArray(Section.ANSWER);
if (answers.length == 0)
return hostIp;
else
return answers[0].rdataToString();
}
public static void main(String args[]) throws IOException {
long now = System.currentTimeMillis();
System.out.println(reverseDns("192.222.1.13"));
System.out.println(reverseDns("208.201.239.36"));
long after = System.currentTimeMillis();
System.out.println((after - now) + " ms");
}
}
This program will print
192.168.4.1
www.oreillynet.com.
781 ms

As you can see, in this way we have both positive and negative query executed in less than one second. This is of course the result on the WinXP machine where the standard getHostName() method does the same job in 5 seconds.

Hopefully, the bug related to the java.net.InetAddress will be fixed in the Mustang release (6.0).



3 Comments

anjanb
2005-11-16 12:52:18
mustang, windows, etc
hi there,


thanks for the post.


We recently had an issue with one of our client deployments where the appserver(RedHat Linux) was taking more than 10 seconds to send a packet to the Integration Server(for lack of a better term). After our support guys added a /etc/hosts entry, it improved a lot.


So, the issue is not localised to Win XP or java 1.5.


I tested(on XP) your solution using the latest mustang build but I did NOT find any difference between 1.5 and mustang.


I'm not sure a ruby/python/C# version would do any better -- any takers ?


BR,

~A

anjanb
2005-11-16 12:53:11
code snippet fix
the last line should be :-)
System.out.println((after - before) + " ms");
dejanb
2005-11-17 00:04:36
mustang, windows, etc
I fixed that line. Thanks.
I didn't say that it is localised on Win XP, but that it is easily spotted in such an environment. As far as I have managed to dig it, this issue is introduced in 1.4 and not fixed in 1.5. So I hope that it will be fixed in 1.6 :)


Thnaks,
Dejan