Tell the resolver what protocols to use.

Stop guessing based on the connectivity of the default route and use the correct
v4/v6 proto for your pid.

bug:5284168
Change-Id: Ife82a8d8e54c0ace2bc9e8a624b11d29a4e285e2
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index e0a2adc..7711a12 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -1955,7 +1955,8 @@
                     Integer pid = (Integer)pids.get(j);
                     if (pid.intValue() == myPid) {
                         Collection<InetAddress> dnses = p.getDnses();
-                        writePidDns(dnses, myPid);
+                        String proto = determineProto(p);
+                        writePidDns(dnses, myPid, proto);
                         if (doBump) {
                             bumpDns();
                         }
@@ -1965,6 +1966,9 @@
            }
         }
         // nothing found - delete
+        if (SystemProperties.get("net.dnsproto." + myPid).length() != 0) {
+            SystemProperties.set("net.dnsproto." + myPid, "");
+        }
         for (int i = 1; ; i++) {
             String prop = "net.dns" + i + "." + myPid;
             if (SystemProperties.get(prop).length() == 0) {
@@ -1978,7 +1982,7 @@
     }
 
     // return true if results in a change
-    private boolean writePidDns(Collection <InetAddress> dnses, int pid) {
+    private boolean writePidDns(Collection <InetAddress> dnses, int pid, String proto) {
         int j = 1;
         boolean changed = false;
         for (InetAddress dns : dnses) {
@@ -1988,6 +1992,11 @@
                 SystemProperties.set("net.dns" + j++ + "." + pid, dns.getHostAddress());
             }
         }
+        if (dnses.size() > 0 && (changed || !proto.equals(SystemProperties.get("net.dnsproto." +
+                pid)))) {
+            changed = true;
+            SystemProperties.set("net.dnsproto." + pid, proto);
+        }
         return changed;
     }
 
@@ -2018,7 +2027,7 @@
 
     // Caller must grab mDnsLock.
     private boolean updateDns(String network, String iface,
-            Collection<InetAddress> dnses, String domains) {
+            Collection<InetAddress> dnses, String domains, String proto) {
         boolean changed = false;
         int last = 0;
         if (dnses.size() == 0 && mDefaultDns != null) {
@@ -2054,6 +2063,11 @@
         }
         mNumDnsEntries = last;
 
+        if (changed || !proto.equals(SystemProperties.get("net.dnsproto"))) {
+            changed = true;
+            SystemProperties.set("net.dnsproto", proto);
+        }
+
         if (changed) {
             try {
                 mNetd.setDnsServersForInterface(iface, NetworkUtils.makeStrings(dnses));
@@ -2077,11 +2091,14 @@
             if (p == null) return;
             Collection<InetAddress> dnses = p.getDnses();
             boolean changed = false;
+            String proto = determineProto(p);
+
             if (mNetConfigs[netType].isDefault()) {
                 String network = nt.getNetworkInfo().getTypeName();
                 synchronized (mDnsLock) {
                     if (!mDnsOverridden) {
-                        changed = updateDns(network, p.getInterfaceName(), dnses, "");
+                        changed = updateDns(network, p.getInterfaceName(), dnses, "",
+                                proto);
                     }
                 }
             } else {
@@ -2095,13 +2112,35 @@
                 List pids = mNetRequestersPids[netType];
                 for (int y=0; y< pids.size(); y++) {
                     Integer pid = (Integer)pids.get(y);
-                    changed = writePidDns(dnses, pid.intValue());
+                    changed = writePidDns(dnses, pid.intValue(), proto);
                 }
             }
             if (changed) bumpDns();
         }
     }
 
+    private String determineProto(LinkProperties p) {
+        boolean v4 = false;
+        boolean v6 = false;
+        for (RouteInfo r : p.getRoutes()) {
+            if (r.getDestination().getAddress() instanceof Inet6Address) {
+                v6 = true;
+            } else {
+                v4 = true;
+            }
+        }
+        // secondary connections often don't have routes and we infer routes
+        // to the dns servers.  Look at the dns addrs too
+        for (InetAddress i : p.getDnses()) {
+            if (i instanceof Inet6Address) {
+                v6 = true;
+            } else {
+                v4 = true;
+            }
+        }
+        return (v4 ? "v4" : "") + (v6 ? "v6" : "");
+    }
+
     private int getRestoreDefaultNetworkDelay(int networkType) {
         String restoreDefaultNetworkDelayStr = SystemProperties.get(
                 NETWORK_RESTORE_DELAY_PROP_NAME);
@@ -2819,7 +2858,7 @@
             // Apply DNS changes.
             boolean changed = false;
             synchronized (mDnsLock) {
-                changed = updateDns("VPN", "VPN", addresses, domains);
+                changed = updateDns("VPN", "VPN", addresses, domains, "v4");
                 mDnsOverridden = true;
             }
             if (changed) {