Provide a custom implementation for DNS lookups in the java.net.URL class

I was wondering if it is possible to provide a custom DNS lookup implementation on java.net.URL - my DNS hosting provider becomes unstable at certain times of the day, and then DNS queries do not work for several minutes, but if I manually configure the corresponding domains in file of my hosts, they work fine, so I want your DNS level to have some kind of DNS cache, if the DNS lookup is complete, refresh the cache if it failed, go back to the cached IP address and open URLConnection on this IP address

This is my implementation of the url connection:

URL endpoint = new URL(null, url, new URLStreamHandler() { @Override protected URLConnection openConnection(URL url) throws IOException { URL target = new URL(url.toString()); URLConnection connection = target.openConnection(); // Connection settings connection.setConnectTimeout(connectionTimeout); connection.setReadTimeout(readTimeout); return (connection); } }); 

I looked at Oracle proxies, but could not see any direct way to do my own DNS lookups at the software level.

Limitations :

1: it should work in Java6 (maybe Java7, but the client will not switch to Java8 any time soon)

2: Unable to add JVM arguments

3: I do not own these endpoints, so replacing the host name with an IP address is not a solution, as load balancers will serve different contents / APIs depending on whether you come from the host name or IP address. For example: mail.google.com is allowed until 216.58.223.37, going to this IP address will serve google.com content, not mail.google.com content, since both services are sitting on the same load balancer using the same IP -address.

4: I do not know how many DNS DNS permissions I will need to cache, but I know that it will be no more than 1000. The ideal solution is to have DNS permissions in a static hashmap, if any DNS resolution is successful, update the hash map if it failed, use the DNS resolution in hashmap.

5: If there is a native Java solution, I would prefer using JNI - Understanding host name resolution and DNS behavior in Java

+5
source share
2 answers

You can simply create another url:

 URL target = new URL( url.getProtocol(), customDns.resolve(url.getHost()), url.getFile()); 

You can implement customDns.resolve(String) using any strategy you need.

0
source

You can create a custom method to check if the host permits IP. Before opening a connection, if the host does not allow it, search and use the IP address directly to create the URL:

At class level:

 private Map<String,InetAddress> cacheMap = new HashMap<String,InetAddress>(); 

.... then a few methods to create your URL:

 private URL buildUrl (String host) throws MalformedURLException { InetAddress ia = resolveHostToIp(host); URL url = null; if (ia != null) { url = new URL(ia.getHostAddress()); } else { // Does not resolve and is not in cache....dunno } return url; } private InetAddress resolveHostToIp(String host) { InetAddress ia = null; try { ia = InetAddress.getByName(host); // Update your cache cacheMap.put(host, ia); } catch (UnknownHostException uhe) { System.out.println("\"" + host + "\" does not resolve to an IP! Looking for it in the cacheMap...."); // Head off to your cache and return the InetAddress from there..... ia = cacheMap.get(host); } return ia; } 
0
source

Source: https://habr.com/ru/post/1212775/


All Articles