Java DNS cache viewer

前端 未结 4 1467
离开以前
离开以前 2020-12-13 14:46

Is there a way to view/dump DNS cached used by java.net api?

4条回答
  •  温柔的废话
    2020-12-13 15:19

    The above answer does not work with Java 11. In Java 11, both positive and negative cache entries can be retrieved using the 'cache' instance variable. Here are new adaptations:

    import java.net.InetAddress;
    import java.net.UnknownHostException;
    import java.lang.reflect.Field;
    import java.net.InetAddress;
    import java.net.UnknownHostException;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    import java.time.Instant;
    import java.time.temporal.ChronoUnit;
    
    public class DnsCacheFetcher {
    static long startTimeinNano = System.nanoTime();
    
    public static void main(String[] args) throws Exception {
    
        System.out.println("SecurityManager: " + System.getSecurityManager());
    
        InetAddress.getByName("stackoverflow.com");
        InetAddress.getByName("www.google.com");
        InetAddress.getByName("www.yahoo.com");
        InetAddress.getByName("www.ankit.com");
    
        try {
            InetAddress.getByName("nowhere.example.com");
        } catch (UnknownHostException e) {
            System.out.println("Unknown host: " + e);
        }
    
        String addressCache = "cache";
        System.out.println(">>>>" + addressCache);
        printDNSCache(addressCache);
        /*
         * String negativeCache = "negativeCache"; System.out.println(">>>>" +
         * negativeCache); printDNSCache(negativeCache);
         */
    }
    
    private static void printDNSCache(String cacheName) throws Exception {
        Class klass = InetAddress.class;
        Field[] fields = klass.getDeclaredFields();
    
        /*
         * for (Field field : fields) { System.out.println(field.getName()); }
         */
    
        Field acf = klass.getDeclaredField(cacheName);
        acf.setAccessible(true);
        Object addressCache = acf.get(null);
        Class cacheKlass = addressCache.getClass();
    
        Map cache = (Map) acf.get(addressCache);
        for (Map.Entry hi : cache.entrySet()) {
            /* System.out.println("Fetching cache for: " + hi.getKey()); */
            Object cacheEntry = hi.getValue();
            Class cacheEntryKlass = cacheEntry.getClass();
            Field expf = cacheEntryKlass.getDeclaredField("expiryTime");
            expf.setAccessible(true);
            long expires = (Long) expf.get(cacheEntry);
    
            Field af = cacheEntryKlass.getDeclaredField("inetAddresses");
            af.setAccessible(true);
            InetAddress[] addresses = (InetAddress[]) af.get(cacheEntry);
            List ads = null;
            if (addresses != null) {
                ads = new ArrayList(addresses.length);
                for (InetAddress address : addresses) {
                    ads.add(address.getHostAddress());
                }
            }
    
            /*
             * System.out.println(hi.getKey() + " expires in " +
             * (Instant.now().until(Instant.ofEpochMilli(expires), ChronoUnit.SECONDS)) +
             * " seconds. inetAddresses: " + ads);
             */
    
            /*
             * System.nanoTime() + 1000_000_000L * cachePolicy : this how java 11 set
             * expiryTime
             */
            System.out.println(hi.getKey() + " expires in approx " + (expires - startTimeinNano) / 1000_000_000L
                    + " seconds. inetAddresses: " + ads);
    
    
        }
    }
    

    }

提交回复
热议问题