summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/connectivity/NetworkMonitor.java50
1 files changed, 40 insertions, 10 deletions
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index 0c86ad8e8551..56859e68e34f 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -29,6 +29,7 @@ import android.content.IntentFilter;
import android.net.CaptivePortal;
import android.net.ConnectivityManager;
import android.net.ICaptivePortal;
+import android.net.Network;
import android.net.NetworkRequest;
import android.net.ProxyInfo;
import android.net.TrafficStats;
@@ -71,6 +72,9 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.net.UnknownHostException;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Random;
import java.util.concurrent.CountDownLatch;
@@ -228,6 +232,7 @@ public class NetworkMonitor extends StateMachine {
private final Context mContext;
private final Handler mConnectivityServiceHandler;
private final NetworkAgentInfo mNetworkAgentInfo;
+ private final Network mNetwork;
private final int mNetId;
private final TelephonyManager mTelephonyManager;
private final WifiManager mWifiManager;
@@ -286,7 +291,8 @@ public class NetworkMonitor extends StateMachine {
mMetricsLog = logger;
mConnectivityServiceHandler = handler;
mNetworkAgentInfo = networkAgentInfo;
- mNetId = mNetworkAgentInfo.network.netId;
+ mNetwork = new OneAddressPerFamilyNetwork(networkAgentInfo.network);
+ mNetId = mNetwork.netId;
mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
@@ -415,7 +421,7 @@ public class NetworkMonitor extends StateMachine {
maybeLogEvaluationResult(
networkEventType(validationStage(), EvaluationResult.VALIDATED));
mConnectivityServiceHandler.sendMessage(obtainMessage(EVENT_NETWORK_TESTED,
- NETWORK_TEST_RESULT_VALID, mNetworkAgentInfo.network.netId, null));
+ NETWORK_TEST_RESULT_VALID, mNetId, null));
mValidations++;
}
@@ -440,7 +446,8 @@ public class NetworkMonitor extends StateMachine {
case CMD_LAUNCH_CAPTIVE_PORTAL_APP:
final Intent intent = new Intent(
ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN);
- intent.putExtra(ConnectivityManager.EXTRA_NETWORK, mNetworkAgentInfo.network);
+ // OneAddressPerFamilyNetwork is not parcelable across processes.
+ intent.putExtra(ConnectivityManager.EXTRA_NETWORK, new Network(mNetwork));
intent.putExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL,
new CaptivePortal(new ICaptivePortal.Stub() {
@Override
@@ -468,8 +475,7 @@ public class NetworkMonitor extends StateMachine {
@Override
public void exit() {
- Message message = obtainMessage(EVENT_PROVISIONING_NOTIFICATION, 0,
- mNetworkAgentInfo.network.netId, null);
+ Message message = obtainMessage(EVENT_PROVISIONING_NOTIFICATION, 0, mNetId, null);
mConnectivityServiceHandler.sendMessage(message);
}
}
@@ -623,7 +629,7 @@ public class NetworkMonitor extends StateMachine {
CustomIntentReceiver(String action, int token, int what) {
mToken = token;
mWhat = what;
- mAction = action + "_" + mNetworkAgentInfo.network.netId + "_" + token;
+ mAction = action + "_" + mNetId + "_" + token;
mContext.registerReceiver(this, new IntentFilter(mAction));
}
public PendingIntent getPendingIntent() {
@@ -659,8 +665,7 @@ public class NetworkMonitor extends StateMachine {
CMD_LAUNCH_CAPTIVE_PORTAL_APP);
}
// Display the sign in notification.
- Message message = obtainMessage(EVENT_PROVISIONING_NOTIFICATION, 1,
- mNetworkAgentInfo.network.netId,
+ Message message = obtainMessage(EVENT_PROVISIONING_NOTIFICATION, 1, mNetId,
mLaunchCaptivePortalAppBroadcastReceiver.getPendingIntent());
mConnectivityServiceHandler.sendMessage(message);
// Retest for captive portal occasionally.
@@ -675,6 +680,31 @@ public class NetworkMonitor extends StateMachine {
}
}
+ // Limits the list of IP addresses returned by getAllByName or tried by openConnection to at
+ // most one per address family. This ensures we only wait up to 20 seconds for TCP connections
+ // to complete, regardless of how many IP addresses a host has.
+ private static class OneAddressPerFamilyNetwork extends Network {
+ public OneAddressPerFamilyNetwork(Network network) {
+ super(network);
+ }
+
+ @Override
+ public InetAddress[] getAllByName(String host) throws UnknownHostException {
+ List<InetAddress> addrs = Arrays.asList(super.getAllByName(host));
+
+ // Ensure the address family of the first address is tried first.
+ LinkedHashMap<Class, InetAddress> addressByFamily = new LinkedHashMap<>();
+ addressByFamily.put(addrs.get(0).getClass(), addrs.get(0));
+ Collections.shuffle(addrs);
+
+ for (InetAddress addr : addrs) {
+ addressByFamily.put(addr.getClass(), addr);
+ }
+
+ return addressByFamily.values().toArray(new InetAddress[addressByFamily.size()]);
+ }
+ }
+
private static String getCaptivePortalServerHttpsUrl(Context context) {
return getSetting(context, Settings.Global.CAPTIVE_PORTAL_HTTPS_URL, DEFAULT_HTTPS_URL);
}
@@ -805,7 +835,7 @@ public class NetworkMonitor extends StateMachine {
int result;
String connectInfo;
try {
- InetAddress[] addresses = mNetworkAgentInfo.network.getAllByName(host);
+ InetAddress[] addresses = mNetwork.getAllByName(host);
StringBuffer buffer = new StringBuffer();
for (InetAddress address : addresses) {
buffer.append(',').append(address.getHostAddress());
@@ -833,7 +863,7 @@ public class NetworkMonitor extends StateMachine {
String redirectUrl = null;
final Stopwatch probeTimer = new Stopwatch().start();
try {
- urlConnection = (HttpURLConnection) mNetworkAgentInfo.network.openConnection(url);
+ urlConnection = (HttpURLConnection) mNetwork.openConnection(url);
urlConnection.setInstanceFollowRedirects(probeType == ValidationProbeEvent.PROBE_PAC);
urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS);