From 3a1cb9d615e06f0e438ebcd44dfe7787acccbe40 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Wed, 30 Jan 2019 23:04:54 +0900 Subject: [PATCH 1/2] Allow bypassing private DNS via bindProcessToNetwork. Currently, bypassing private DNS requires calling the deprecated setProcessDefaultNetworkForHostResolution. Allow apps to do this via the non-deprecated binProcessForNetwork as well. This has fewer backwards compatibility concerns than the alternative approach of having setProcessDefaultNetwork call setProcessDefaultNetworkForHostResolution. That approach would have been problematic, for example, if an app did: cm.bindProcessToNetwork(network); ... cm.bindProcessToNetwork(null); In this case, it would be difficult to know whether to clear the resolver mapping as well: what if an app had also called setProcessDefaultNetworkForHostResolution? Similarly, it would be difficult to know what to do if an app did: cm.setProcessDefaultNetworkForHostResolution(network); cm.bindProcessToNetwork(null); This approach does not have these concerns, and has no effect on apps that don't call Network.getPrivateDnsBypassingCopy, which regular apps don't have permission to use. It also provides a path to deprecate setProcessDefaultNetworkForHostResolution. Bug: 112869080 Test: atest android.net.cts.ConnectivityManagerTest android.net.cts.MultinetworkApiTest Change-Id: I4158a37b6ed87a9a9b2677c526dcfee8af48e483 --- core/java/android/net/ConnectivityManager.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 3bae12e937..41a32a1df9 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -3973,6 +3973,9 @@ public class ConnectivityManager { if (netId == NetworkUtils.getBoundNetworkForProcess()) { return true; } + if (netId != NETID_UNSET) { + netId = network.getNetIdForResolv(); + } if (NetworkUtils.bindProcessToNetwork(netId)) { // Set HTTP proxy system properties to match network. // TODO: Deprecate this static method and replace it with a non-static version. From 3c766ebc4d59c47a0de02afc6596e4eefdb86f5d Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Thu, 31 Jan 2019 13:08:24 +0900 Subject: [PATCH 2/2] Allow use of bindProcessToNetwork only to change private DNS bypass. Currently it is not possible to change private DNS bypass by doing: setProcessDefaultNetwork(network.getPrivateDnsBypassingCopy()); setProcessDefaultNetwork(network); because the code will ignore the change. Fix this by ensuring that we always call bindProcessToNetwork (which does not have side effects) and then only performing the expensive operations (flushing DNS cache, upating socket pools) if the netId changed. Bug: 112869080 Test: None Change-Id: I5e8999cb11d8b8c1e9eb583fa8b3932f212accff --- core/java/android/net/ConnectivityManager.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 41a32a1df9..160157771b 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -3970,13 +3970,17 @@ public class ConnectivityManager { @Deprecated public static boolean setProcessDefaultNetwork(@Nullable Network network) { int netId = (network == null) ? NETID_UNSET : network.netId; - if (netId == NetworkUtils.getBoundNetworkForProcess()) { - return true; - } + boolean isSameNetId = (netId == NetworkUtils.getBoundNetworkForProcess()); + if (netId != NETID_UNSET) { netId = network.getNetIdForResolv(); } - if (NetworkUtils.bindProcessToNetwork(netId)) { + + if (!NetworkUtils.bindProcessToNetwork(netId)) { + return false; + } + + if (!isSameNetId) { // Set HTTP proxy system properties to match network. // TODO: Deprecate this static method and replace it with a non-static version. try { @@ -3990,10 +3994,9 @@ public class ConnectivityManager { // Must flush socket pool as idle sockets will be bound to previous network and may // cause subsequent fetches to be performed on old network. NetworkEventDispatcher.getInstance().onNetworkConfigurationChanged(); - return true; - } else { - return false; } + + return true; } /**