Merge "Support bypassing TLS in the framework" am: aef9956de2
am: f12b9edf24

Change-Id: I0994b53d24ed25a2eb9e65429c61cf6fa87c7513
diff --git a/packages/CaptivePortalLogin/Android.mk b/packages/CaptivePortalLogin/Android.mk
index 7dc23ff..8a96b16 100644
--- a/packages/CaptivePortalLogin/Android.mk
+++ b/packages/CaptivePortalLogin/Android.mk
@@ -2,7 +2,7 @@
 include $(CLEAR_VARS)
 
 LOCAL_MODULE_TAGS := optional
-LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4 services.net
 
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
index dbdf5e16..cdc3867 100644
--- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
+++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java
@@ -30,6 +30,7 @@
 import android.net.NetworkRequest;
 import android.net.Proxy;
 import android.net.Uri;
+import android.net.dns.ResolvUtil;
 import android.net.http.SslError;
 import android.os.Build;
 import android.os.Bundle;
@@ -119,6 +120,8 @@
 
         // Also initializes proxy system properties.
         mCm.bindProcessToNetwork(mNetwork);
+        mCm.setProcessDefaultNetworkForHostResolution(
+                ResolvUtil.getNetworkWithUseLocalNameserversFlag(mNetwork));
 
         // Proxy system properties must be initialized before setContentView is called because
         // setContentView initializes the WebView logic which in turn reads the system properties.
diff --git a/packages/CarrierDefaultApp/Android.mk b/packages/CarrierDefaultApp/Android.mk
index df88afd..5068b3b 100644
--- a/packages/CarrierDefaultApp/Android.mk
+++ b/packages/CarrierDefaultApp/Android.mk
@@ -9,6 +9,8 @@
 LOCAL_PRIVATE_PLATFORM_APIS := true
 LOCAL_CERTIFICATE := platform
 
+LOCAL_STATIC_JAVA_LIBRARIES := services.net
+
 include $(BUILD_PACKAGE)
 
 # This finds and builds the test apk as well, so a single make does both.
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
index 95ec83d..7479d9a 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
@@ -32,6 +32,7 @@
 import android.net.Proxy;
 import android.net.TrafficStats;
 import android.net.Uri;
+import android.net.dns.ResolvUtil;
 import android.net.http.SslError;
 import android.os.Bundle;
 import android.telephony.CarrierConfigManager;
@@ -115,6 +116,8 @@
             requestNetworkForCaptivePortal();
         } else {
             mCm.bindProcessToNetwork(mNetwork);
+            mCm.setProcessDefaultNetworkForHostResolution(
+                    ResolvUtil.getNetworkWithUseLocalNameserversFlag(mNetwork));
             // Start initial page load so WebView finishes loading proxy settings.
             // Actual load of mUrl is initiated by MyWebViewClient.
             mWebView.loadData("", "text/html", null);
diff --git a/services/core/java/com/android/server/connectivity/DnsManager.java b/services/core/java/com/android/server/connectivity/DnsManager.java
index 36f5a6c..5579849 100644
--- a/services/core/java/com/android/server/connectivity/DnsManager.java
+++ b/services/core/java/com/android/server/connectivity/DnsManager.java
@@ -34,22 +34,19 @@
 import android.net.Network;
 import android.net.NetworkUtils;
 import android.net.Uri;
+import android.net.dns.ResolvUtil;
 import android.os.Binder;
 import android.os.INetworkManagementService;
 import android.os.Handler;
 import android.os.UserHandle;
 import android.provider.Settings;
-import android.system.GaiException;
-import android.system.OsConstants;
-import android.system.StructAddrinfo;
 import android.text.TextUtils;
 import android.util.Slog;
 
 import com.android.server.connectivity.MockableSystemProperties;
 
-import libcore.io.Libcore;
-
 import java.net.InetAddress;
+import java.net.UnknownHostException;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
@@ -126,28 +123,19 @@
     }
 
     public static PrivateDnsConfig tryBlockingResolveOf(Network network, String name) {
-        final StructAddrinfo hints = new StructAddrinfo();
-        // Unnecessary, but expressly no AI_ADDRCONFIG.
-        hints.ai_flags = 0;
-        // Fetch all IP addresses at once to minimize re-resolution.
-        hints.ai_family = OsConstants.AF_UNSPEC;
-        hints.ai_socktype = OsConstants.SOCK_DGRAM;
-
         try {
-            final InetAddress[] ips = Libcore.os.android_getaddrinfo(name, hints, network.netId);
-            if (ips != null && ips.length > 0) {
-                return new PrivateDnsConfig(name, ips);
-            }
-        } catch (GaiException ignored) {}
-
-        return null;
+            final InetAddress[] ips = ResolvUtil.blockingResolveAllLocally(network, name);
+            return new PrivateDnsConfig(name, ips);
+        } catch (UnknownHostException uhe) {
+            return new PrivateDnsConfig(name, null);
+        }
     }
 
     public static Uri[] getPrivateDnsSettingsUris() {
-        final Uri[] uris = new Uri[2];
-        uris[0] = Settings.Global.getUriFor(PRIVATE_DNS_MODE);
-        uris[1] = Settings.Global.getUriFor(PRIVATE_DNS_SPECIFIER);
-        return uris;
+        return new Uri[]{
+            Settings.Global.getUriFor(PRIVATE_DNS_MODE),
+            Settings.Global.getUriFor(PRIVATE_DNS_SPECIFIER),
+        };
     }
 
     private final Context mContext;
@@ -203,7 +191,7 @@
         // NetworkMonitor to decide which networks need validation and runs the
         // blocking calls to resolve Private DNS strict mode hostnames.
         //
-        // At this time we do attempt to enable Private DNS on non-Internet
+        // At this time we do not attempt to enable Private DNS on non-Internet
         // networks like IMS.
         final PrivateDnsConfig privateDnsCfg = mPrivateDnsMap.get(netId);
 
diff --git a/services/net/java/android/net/dns/ResolvUtil.java b/services/net/java/android/net/dns/ResolvUtil.java
new file mode 100644
index 0000000..97d20f4
--- /dev/null
+++ b/services/net/java/android/net/dns/ResolvUtil.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.dns;
+
+import android.net.Network;
+import android.net.NetworkUtils;
+import android.system.GaiException;
+import android.system.OsConstants;
+import android.system.StructAddrinfo;
+
+import libcore.io.Libcore;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+
+/**
+ * DNS resolution utility class.
+ *
+ * @hide
+ */
+public class ResolvUtil {
+    // Non-portable DNS resolution flag.
+    private static final long NETID_USE_LOCAL_NAMESERVERS = 0x80000000L;
+
+    private ResolvUtil() {}
+
+    public static InetAddress[] blockingResolveAllLocally(Network network, String name)
+            throws UnknownHostException {
+        final StructAddrinfo hints = new StructAddrinfo();
+        // Unnecessary, but expressly no AI_ADDRCONFIG.
+        hints.ai_flags = 0;
+        // Fetch all IP addresses at once to minimize re-resolution.
+        hints.ai_family = OsConstants.AF_UNSPEC;
+        hints.ai_socktype = OsConstants.SOCK_DGRAM;
+
+        final Network networkForResolv = getNetworkWithUseLocalNameserversFlag(network);
+
+        try {
+            return Libcore.os.android_getaddrinfo(name, hints, (int) networkForResolv.netId);
+        } catch (GaiException gai) {
+            gai.rethrowAsUnknownHostException(name + ": TLS-bypass resolution failed");
+            return null;  // keep compiler quiet
+        }
+    }
+
+    public static Network getNetworkWithUseLocalNameserversFlag(Network network) {
+        final long netidForResolv = NETID_USE_LOCAL_NAMESERVERS | (long) network.netId;
+        return new Network((int) netidForResolv);
+    }
+}