summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorOscar Shu <xshu@google.com>2019-11-21 23:00:36 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2019-11-21 23:00:36 +0000
commitd868dc640012bcc174fd075b59f5584519193af4 (patch)
tree60be935bff92f824e1881f3b71cdb8282e39b064 /service
parentabe066cef0c0d72469288cb7471e9a1278ad9d25 (diff)
parent622b812139bdeb88a675d6126f94b15ed1ff4336 (diff)
Merge "Add exponential backoff to Bssid blocklist time"
Diffstat (limited to 'service')
-rw-r--r--service/java/com/android/server/wifi/BssidBlocklistMonitor.java69
-rw-r--r--service/java/com/android/server/wifi/ClientModeImpl.java10
-rw-r--r--service/java/com/android/server/wifi/WifiInjector.java2
-rw-r--r--service/java/com/android/server/wifi/WifiScoreCard.java29
4 files changed, 88 insertions, 22 deletions
diff --git a/service/java/com/android/server/wifi/BssidBlocklistMonitor.java b/service/java/com/android/server/wifi/BssidBlocklistMonitor.java
index 2921729ca..7aab09cc5 100644
--- a/service/java/com/android/server/wifi/BssidBlocklistMonitor.java
+++ b/service/java/com/android/server/wifi/BssidBlocklistMonitor.java
@@ -31,6 +31,7 @@ import java.util.ArrayList;
import java.util.Calendar;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -55,8 +56,8 @@ public class BssidBlocklistMonitor {
public static final int REASON_AUTHENTICATION_FAILURE = 6;
// DHCP failures
public static final int REASON_DHCP_FAILURE = 7;
- // Local constant being used to keep track of how many failure reasons there are.
- private static final int NUMBER_REASON_CODES = 8;
+ // Constant being used to keep track of how many failure reasons there are.
+ public static final int NUMBER_REASON_CODES = 8;
@IntDef(prefix = { "REASON_" }, value = {
REASON_AP_UNABLE_TO_HANDLE_NEW_STA,
@@ -69,7 +70,7 @@ public class BssidBlocklistMonitor {
REASON_DHCP_FAILURE
})
@Retention(RetentionPolicy.SOURCE)
- public @interface BssidBlocklistMonitorFailureReason {}
+ public @interface FailureReason {}
public static final int[] FAILURE_COUNT_DISABLE_THRESHOLD = {
1, // threshold for REASON_AP_UNABLE_TO_HANDLE_NEW_STA
@@ -83,7 +84,9 @@ public class BssidBlocklistMonitor {
};
private static final int FAILURE_COUNTER_THRESHOLD = 3;
- private static final long BASE_BLOCKLIST_DURATION = 5 * 60 * 1000; // 5 minutes
+ private static final long BASE_BLOCKLIST_DURATION = TimeUnit.MINUTES.toMillis(5); // 5 minutes
+ private static final long MAX_BLOCKLIST_DURATION = TimeUnit.HOURS.toMillis(18); // 18 hours
+ private static final int FAILURE_STREAK_CAP = 7;
private static final String TAG = "BssidBlocklistMonitor";
private final WifiLastResortWatchdog mWifiLastResortWatchdog;
@@ -91,6 +94,7 @@ public class BssidBlocklistMonitor {
private final Clock mClock;
private final LocalLog mLocalLog;
private final Calendar mCalendar;
+ private final WifiScoreCard mWifiScoreCard;
// Map of bssid to BssidStatus
private Map<String, BssidStatus> mBssidStatusMap = new ArrayMap<>();
@@ -99,12 +103,14 @@ public class BssidBlocklistMonitor {
* Create a new instance of BssidBlocklistMonitor
*/
BssidBlocklistMonitor(WifiConnectivityHelper connectivityHelper,
- WifiLastResortWatchdog wifiLastResortWatchdog, Clock clock, LocalLog localLog) {
+ WifiLastResortWatchdog wifiLastResortWatchdog, Clock clock, LocalLog localLog,
+ WifiScoreCard wifiScoreCard) {
mConnectivityHelper = connectivityHelper;
mWifiLastResortWatchdog = wifiLastResortWatchdog;
mClock = clock;
mLocalLog = localLog;
mCalendar = Calendar.getInstance();
+ mWifiScoreCard = wifiScoreCard;
}
// A helper to log debugging information in the local log buffer, which can
@@ -113,10 +119,21 @@ public class BssidBlocklistMonitor {
mLocalLog.log(log);
}
- private long getBlocklistDurationWithExponentialBackoff(String bssid) {
- // TODO: b/139287182 implement exponential backoff to extend the blocklist duration for
- // BSSIDs that continue to fail.
- return BASE_BLOCKLIST_DURATION;
+ /**
+ * calculates the blocklist duration based on the current failure streak with exponential
+ * backoff.
+ * @param failureStreak should be greater or equal to 0.
+ * @return duration to block the BSSID in milliseconds
+ */
+ private long getBlocklistDurationWithExponentialBackoff(int failureStreak) {
+ if (failureStreak > FAILURE_STREAK_CAP) {
+ return MAX_BLOCKLIST_DURATION;
+ }
+ if (failureStreak < 1) {
+ return BASE_BLOCKLIST_DURATION;
+ }
+ long duration = (long) (Math.pow(2.0, (double) failureStreak) * BASE_BLOCKLIST_DURATION);
+ return Math.min(MAX_BLOCKLIST_DURATION, duration);
}
/**
@@ -129,14 +146,14 @@ public class BssidBlocklistMonitor {
pw.println("BssidBlocklistMonitor - Bssid blocklist End ----");
}
- private boolean addToBlocklist(@NonNull BssidStatus entry) {
+ private boolean addToBlocklist(@NonNull BssidStatus entry, int failureStreak) {
// Call mWifiLastResortWatchdog.shouldIgnoreBssidUpdate to give watchdog a chance to
// trigger before blocklisting the bssid.
String bssid = entry.bssid;
if (mWifiLastResortWatchdog.shouldIgnoreBssidUpdate(bssid)) {
return false;
}
- long durationMs = getBlocklistDurationWithExponentialBackoff(bssid);
+ long durationMs = getBlocklistDurationWithExponentialBackoff(failureStreak);
entry.addToBlocklist(durationMs);
localLog(TAG + " addToBlocklist: bssid=" + bssid + ", ssid=" + entry.ssid
+ ", durationMs=" + durationMs);
@@ -168,7 +185,7 @@ public class BssidBlocklistMonitor {
* @return True if the blocklist has been modified.
*/
public boolean handleBssidConnectionFailure(String bssid, String ssid,
- @BssidBlocklistMonitorFailureReason int reasonCode) {
+ @FailureReason int reasonCode) {
if (bssid == null || ssid == null || WifiManager.UNKNOWN_SSID.equals(ssid)
|| bssid.equals(ClientModeImpl.SUPPLICANT_BSSID_ANY)
|| reasonCode < 0 || reasonCode >= NUMBER_REASON_CODES) {
@@ -178,8 +195,12 @@ public class BssidBlocklistMonitor {
}
boolean result = false;
BssidStatus entry = incrementFailureCountForBssid(bssid, ssid, reasonCode);
- if (entry.failureCount[reasonCode] >= FAILURE_COUNT_DISABLE_THRESHOLD[reasonCode]) {
- result = addToBlocklist(entry);
+
+ int currentStreak = mWifiScoreCard.getBssidBlocklistStreak(ssid, bssid, reasonCode);
+ if (currentStreak > 0
+ || entry.failureCount[reasonCode] >= FAILURE_COUNT_DISABLE_THRESHOLD[reasonCode]) {
+ result = addToBlocklist(entry, currentStreak);
+ mWifiScoreCard.incrementBssidBlocklistStreak(ssid, bssid, reasonCode);
}
return result;
}
@@ -187,7 +208,19 @@ public class BssidBlocklistMonitor {
/**
* Note a connection success event on a bssid and clear appropriate failure counters.
*/
- public void handleBssidConnectionSuccess(@NonNull String bssid) {
+ public void handleBssidConnectionSuccess(@NonNull String bssid, @NonNull String ssid) {
+ /**
+ * First reset the blocklist streak.
+ * This needs to be done even if a BssidStatus is not found, since the BssidStatus may
+ * have been removed due to blocklist timeout.
+ */
+ mWifiScoreCard.resetBssidBlocklistStreak(ssid, bssid, REASON_AP_UNABLE_TO_HANDLE_NEW_STA);
+ mWifiScoreCard.resetBssidBlocklistStreak(ssid, bssid, REASON_WRONG_PASSWORD);
+ mWifiScoreCard.resetBssidBlocklistStreak(ssid, bssid, REASON_EAP_FAILURE);
+ mWifiScoreCard.resetBssidBlocklistStreak(ssid, bssid, REASON_ASSOCIATION_REJECTION);
+ mWifiScoreCard.resetBssidBlocklistStreak(ssid, bssid, REASON_ASSOCIATION_TIMEOUT);
+ mWifiScoreCard.resetBssidBlocklistStreak(ssid, bssid, REASON_AUTHENTICATION_FAILURE);
+
BssidStatus status = mBssidStatusMap.get(bssid);
if (status == null) {
return;
@@ -204,7 +237,8 @@ public class BssidBlocklistMonitor {
/**
* Note a successful network validation on a BSSID and clear appropriate failure counters.
*/
- public void handleNetworkValidationSuccess(@NonNull String bssid) {
+ public void handleNetworkValidationSuccess(@NonNull String bssid, @NonNull String ssid) {
+ mWifiScoreCard.resetBssidBlocklistStreak(ssid, bssid, REASON_NETWORK_VALIDATION_FAILURE);
BssidStatus status = mBssidStatusMap.get(bssid);
if (status == null) {
return;
@@ -215,7 +249,8 @@ public class BssidBlocklistMonitor {
/**
* Note a successful DHCP provisioning and clear appropriate faliure counters.
*/
- public void handleDhcpProvisioningSuccess(@NonNull String bssid) {
+ public void handleDhcpProvisioningSuccess(@NonNull String bssid, @NonNull String ssid) {
+ mWifiScoreCard.resetBssidBlocklistStreak(ssid, bssid, REASON_DHCP_FAILURE);
BssidStatus status = mBssidStatusMap.get(bssid);
if (status == null) {
return;
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java
index dfd92d3e2..d95f6e8be 100644
--- a/service/java/com/android/server/wifi/ClientModeImpl.java
+++ b/service/java/com/android/server/wifi/ClientModeImpl.java
@@ -2818,7 +2818,7 @@ public class ClientModeImpl extends StateMachine {
mWifiInfo.setTrusted(config.trusted);
mWifiConfigManager.updateRandomizedMacExpireTime(config,
dhcpResults.getLeaseDuration());
- mBssidBlocklistMonitor.handleDhcpProvisioningSuccess(mLastBssid);
+ mBssidBlocklistMonitor.handleDhcpProvisioningSuccess(mLastBssid, mWifiInfo.getSSID());
}
// Set meteredHint if DHCP result says network is metered
@@ -4275,7 +4275,7 @@ public class ClientModeImpl extends StateMachine {
mCountryCode.setReadyForChange(false);
mWifiMetrics.setWifiState(WifiMetricsProto.WifiLog.WIFI_ASSOCIATED);
mWifiScoreCard.noteNetworkAgentCreated(mWifiInfo, mNetworkAgent.netId);
- mBssidBlocklistMonitor.handleBssidConnectionSuccess(mLastBssid);
+ mBssidBlocklistMonitor.handleBssidConnectionSuccess(mLastBssid, mWifiInfo.getSSID());
}
@Override
@@ -4868,7 +4868,8 @@ public class ClientModeImpl extends StateMachine {
sendNetworkStateChangeBroadcast(mLastBssid);
// Successful framework roam! (probably)
- mBssidBlocklistMonitor.handleBssidConnectionSuccess(mLastBssid);
+ mBssidBlocklistMonitor.handleBssidConnectionSuccess(mLastBssid,
+ mWifiInfo.getSSID());
reportConnectionAttemptEnd(
WifiMetrics.ConnectionEvent.FAILURE_NONE,
WifiMetricsProto.ConnectionEvent.HLF_NONE,
@@ -5014,7 +5015,8 @@ public class ClientModeImpl extends StateMachine {
mWifiDiagnostics.reportConnectionEvent(
WifiDiagnostics.CONNECTION_EVENT_SUCCEEDED);
mWifiScoreCard.noteValidationSuccess(mWifiInfo);
- mBssidBlocklistMonitor.handleNetworkValidationSuccess(mLastBssid);
+ mBssidBlocklistMonitor.handleNetworkValidationSuccess(mLastBssid,
+ mWifiInfo.getSSID());
config = getCurrentWifiConfiguration();
if (config != null) {
// re-enable autojoin
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index 646b7a014..3c77c09f7 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -603,7 +603,7 @@ public class WifiInjector {
mWifiMetrics, clientModeImpl, mWifiHandlerThread.getLooper(), mDeviceConfigFacade,
mWifiThreadRunner);
mBssidBlocklistMonitor = new BssidBlocklistMonitor(mWifiConnectivityHelper,
- mWifiLastResortWatchdog, mClock, mConnectivityLocalLog);
+ mWifiLastResortWatchdog, mClock, mConnectivityLocalLog, mWifiScoreCard);
mWifiChannelUtilization = new WifiChannelUtilization(mClock);
return new WifiConnectivityManager(mContext, getScoringParams(),
clientModeImpl, this,
diff --git a/service/java/com/android/server/wifi/WifiScoreCard.java b/service/java/com/android/server/wifi/WifiScoreCard.java
index 87d9c3403..19f74d0f2 100644
--- a/service/java/com/android/server/wifi/WifiScoreCard.java
+++ b/service/java/com/android/server/wifi/WifiScoreCard.java
@@ -379,11 +379,40 @@ public class WifiScoreCard {
doWrites();
}
+ /**
+ * Increment the blocklist streak count for a failure reason on an AP.
+ * @return the updated count
+ */
+ public int incrementBssidBlocklistStreak(String ssid, String bssid,
+ @BssidBlocklistMonitor.FailureReason int reason) {
+ PerBssid perBssid = lookupBssid(ssid, bssid);
+ return ++perBssid.blocklistStreakCount[reason];
+ }
+
+ /**
+ * Get the blocklist streak count for a failure reason on an AP.
+ * @return the blocklist streak count
+ */
+ public int getBssidBlocklistStreak(String ssid, String bssid,
+ @BssidBlocklistMonitor.FailureReason int reason) {
+ return lookupBssid(ssid, bssid).blocklistStreakCount[reason];
+ }
+
+ /**
+ * Clear the blocklist streak count for a failure reason on an AP.
+ */
+ public void resetBssidBlocklistStreak(String ssid, String bssid,
+ @BssidBlocklistMonitor.FailureReason int reason) {
+ lookupBssid(ssid, bssid).blocklistStreakCount[reason] = 0;
+ }
+
final class PerBssid {
public int id;
public final String l2Key;
public final String ssid;
public final MacAddress bssid;
+ public final int[] blocklistStreakCount =
+ new int[BssidBlocklistMonitor.NUMBER_REASON_CODES];
public boolean changed;
public boolean referenced;