Rely more on the C library level DNS caching.

This change:

1. decreases the size of the libcore cache (to 16 hostnames).
2. brings the positive and negative TTLs way down (to 2s).
3. removes the dead code for the broken TTL-setting system properties.

Bug: 5841178
Bug: http://code.google.com/p/android/issues/detail?id=23878
Change-Id: Ib989c72bf3046300b4d59fa5ae49b8fe3ae6c2dc
diff --git a/luni/src/main/java/java/net/AddressCache.java b/luni/src/main/java/java/net/AddressCache.java
index 08f5d81..194761a 100644
--- a/luni/src/main/java/java/net/AddressCache.java
+++ b/luni/src/main/java/java/net/AddressCache.java
@@ -21,18 +21,20 @@
 /**
  * Implements caching for {@code InetAddress}. We use a unified cache for both positive and negative
  * cache entries.
+ *
+ * TODO: benchmark and optimize InetAddress until we get to the point where we can just rely on
+ * the C library level caching. The main thing caching at this level buys us is avoiding repeated
+ * conversions from 'struct sockaddr's to InetAddress[].
  */
 class AddressCache {
     /**
      * When the cache contains more entries than this, we start dropping the oldest ones.
      * This should be a power of two to avoid wasted space in our custom map.
      */
-    private static final int MAX_ENTRIES = 512;
+    private static final int MAX_ENTRIES = 16;
 
-    // Default time-to-live for positive cache entries. 600 seconds (10 minutes).
-    private static final long DEFAULT_POSITIVE_TTL_NANOS = 600 * 1000000000L;
-    // Default time-to-live for negative cache entries. 10 seconds.
-    private static final long DEFAULT_NEGATIVE_TTL_NANOS = 10 * 1000000000L;
+    // The TTL for the Java-level cache is short, just 2s.
+    private static final long TTL_NANOS = 2 * 1000000000L;
 
     // The actual cache.
     private final BasicLruCache<String, AddressCacheEntry> cache
@@ -47,13 +49,13 @@
          * The absolute expiry time in nanoseconds. Nanoseconds from System.nanoTime is ideal
          * because -- unlike System.currentTimeMillis -- it can never go backwards.
          *
-         * Unless we need to cope with DNS TTLs of 292 years, we don't need to worry about overflow.
+         * We don't need to worry about overflow with a TTL_NANOS of 2s.
          */
         final long expiryNanos;
 
-        AddressCacheEntry(Object value, long expiryNanos) {
+        AddressCacheEntry(Object value) {
             this.value = value;
-            this.expiryNanos = expiryNanos;
+            this.expiryNanos = System.nanoTime() + TTL_NANOS;
         }
     }
 
@@ -85,28 +87,7 @@
      * certain length of time.
      */
     public void put(String hostname, InetAddress[] addresses) {
-        put(hostname, addresses, true);
-    }
-
-    /**
-     * Associates the given 'detailMessage' with 'hostname'. The association will expire after a
-     * certain length of time.
-     */
-    public void put(String hostname, String detailMessage) {
-        put(hostname, detailMessage, false);
-    }
-
-    /**
-     * Associates the given 'addresses' with 'hostname'. The association will expire after a
-     * certain length of time.
-     */
-    public void put(String hostname, Object value, boolean isPositive) {
-        // Calculate the expiry time.
-        String propertyName = isPositive ? "networkaddress.cache.ttl" : "networkaddress.cache.negative.ttl";
-        long defaultTtlNanos = isPositive ? DEFAULT_POSITIVE_TTL_NANOS : DEFAULT_NEGATIVE_TTL_NANOS;
-        long expiryNanos = System.nanoTime() + defaultTtlNanos;
-        // Update the cache.
-        cache.put(hostname, new AddressCacheEntry(value, expiryNanos));
+        cache.put(hostname, new AddressCacheEntry(addresses));
     }
 
     /**
@@ -114,26 +95,6 @@
      * negative cache entry.)
      */
     public void putUnknownHost(String hostname, String detailMessage) {
-        put(hostname, detailMessage);
-    }
-
-    private long customTtl(String propertyName, long defaultTtlNanos) {
-        String ttlString = System.getProperty(propertyName, null);
-        if (ttlString == null) {
-            return System.nanoTime() + defaultTtlNanos;
-        }
-        try {
-            long ttlS = Long.parseLong(ttlString);
-            // For the system properties, -1 means "cache forever" and 0 means "don't cache".
-            if (ttlS == -1) {
-                return Long.MAX_VALUE;
-            } else if (ttlS == 0) {
-                return Long.MIN_VALUE;
-            } else {
-                return System.nanoTime() + ttlS * 1000000000L;
-            }
-        } catch (NumberFormatException ex) {
-            return System.nanoTime() + defaultTtlNanos;
-        }
+        cache.put(hostname, new AddressCacheEntry(detailMessage));
     }
 }
diff --git a/luni/src/main/java/java/net/InetAddress.java b/luni/src/main/java/java/net/InetAddress.java
index cada6bd..49029c6 100644
--- a/luni/src/main/java/java/net/InetAddress.java
+++ b/luni/src/main/java/java/net/InetAddress.java
@@ -116,15 +116,9 @@
  * brackets.
  *
  * <h4>DNS caching</h4>
- * <p>On Android, addresses are cached for 600 seconds (10 minutes) by default. Failed lookups are
- * cached for 10 seconds. The underlying C library or OS may cache for longer, but you can control
- * the Java-level caching with the usual {@code "networkaddress.cache.ttl"} and
- * {@code "networkaddress.cache.negative.ttl"} system properties. These are parsed as integer
- * numbers of seconds, where the special value 0 means "don't cache" and -1 means "cache forever".
- *
- * <p>Note also that on Android &ndash; unlike the RI &ndash; the cache is not unbounded. The
- * current implementation caches around 512 entries, removed on a least-recently-used basis.
- * (Obviously, you should not rely on these details.)
+ * <p>In Android 4.0 (Ice Cream Sandwich) and earlier, DNS caching was performed both by
+ * InetAddress and by the C library, which meant that DNS TTLs could not be honored correctly.
+ * In later releases, caching is done solely by the C library and DNS TTLs are honored.
  *
  * @see Inet4Address
  * @see Inet6Address