Search code examples
javadnsnslookup

DNS query freezes with DnsContextFactory in java


The program below performs a DNS lookup. It works good except for one particular combination of host name and dns:

import javax.naming.directory.InitialDirContext;
import javax.naming.NamingException;
import java.util.Hashtable;

public final class StackOverflow {
 public static void main(String args[]) throws NamingException {
  Hashtable<String, Object> env = new Hashtable<String, Object>();
  env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory");
  env.put("java.naming.provider.url", "dns://ns.dnssek.org");
  System.out.println(new InitialDirContext(env).getAttributes("dnsseccert.us", new String[]{"NS","A"}));
 }
}

I tried to set timeout:

env.put("com.sun.jndi.dns.timeout.initial", "220");

however it behaves strange. It works sometimes for small values when it throws:

DNS error [Root exception is java.net.SocketTimeoutException: Receive timed out];

but for most of the times the program just freezes and hangs in the memory.

Have someone else had the same problem and solved it? Are there any other settings I could try to prevent it? Is there some other alternative java.naming.factory.initial which I could try?


Solution

  • It took me a few hours but I finally found an acceptable solution. I downloaded sources of the package com.sun.jndi.dns and added one line into the class DnsClient:

    ...
    Tcp(InetAddress server, int port, int timeout) throws IOException {
        sock = new Socket(server, port);
        sock.setSoTimeout(timeout);  // <-- missing timeout
        sock.setTcpNoDelay(true);
        out = new java.io.BufferedOutputStream(sock.getOutputStream());
        in = new java.io.BufferedInputStream(sock.getInputStream());
    }
    ...
    

    I set timout of the socket. I actually also added a parameter into the Tcp constructor and modified its calls so it is now initialized by the value from com.sun.jndi.dns.timeout.initial.