summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxshu <xshu@google.com>2020-09-10 19:46:04 -0700
committerxshu <xshu@google.com>2020-09-15 17:04:20 -0700
commit80d0986ea4ec6d2bff2af02a9e1a31593c200540 (patch)
tree98043d9a8dddf490de8e364bd0bf7e69531aebdd
parent21130f070cd84f847b2efd59c099b86068733347 (diff)
Exponential backoff for external score blocklist
(cherry-picked from 89ab95af87eff69a5865124fc4bc529e1f6efb52) Changes: 1. When the external scorer marks a network as unacceptable, block the BSSID for 0.5/1/2/... up to 64 minutes instead of the previous fixed 30 seconds. 2. Modified test cases to increase coverage. Bug: 158695052 Test: atest com.android.server.wifi Change-Id: I0f1413563530c8e66ea6a061c78bc49bffd61091
-rw-r--r--service/java/com/android/server/wifi/BssidBlocklistMonitor.java16
-rw-r--r--service/java/com/android/server/wifi/WifiScoreReport.java4
-rw-r--r--service/res/values/config.xml7
-rw-r--r--service/res/values/overlayable.xml1
-rw-r--r--tests/wifitests/src/com/android/server/wifi/BssidBlocklistMonitorTest.java104
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java15
6 files changed, 102 insertions, 45 deletions
diff --git a/service/java/com/android/server/wifi/BssidBlocklistMonitor.java b/service/java/com/android/server/wifi/BssidBlocklistMonitor.java
index d96fdb39e..e3fe32ab7 100644
--- a/service/java/com/android/server/wifi/BssidBlocklistMonitor.java
+++ b/service/java/com/android/server/wifi/BssidBlocklistMonitor.java
@@ -330,8 +330,7 @@ public class BssidBlocklistMonitor {
if (shouldWaitForWatchdogToTriggerFirst(bssid, reasonCode)) {
return false;
}
- int baseBlockDurationMs = mContext.getResources().getInteger(
- R.integer.config_wifiBssidBlocklistMonitorBaseBlockDurationMs);
+ int baseBlockDurationMs = getBaseBlockDurationForReason(reasonCode);
addToBlocklist(entry,
getBlocklistDurationWithExponentialBackoff(currentStreak, baseBlockDurationMs),
reasonCode, rssi);
@@ -341,6 +340,17 @@ public class BssidBlocklistMonitor {
return false;
}
+ private int getBaseBlockDurationForReason(int blockReason) {
+ switch (blockReason) {
+ case REASON_FRAMEWORK_DISCONNECT_CONNECTED_SCORE:
+ return mContext.getResources().getInteger(R.integer
+ .config_wifiBssidBlocklistMonitorConnectedScoreBaseBlockDurationMs);
+ default:
+ return mContext.getResources().getInteger(
+ R.integer.config_wifiBssidBlocklistMonitorBaseBlockDurationMs);
+ }
+ }
+
/**
* Note a failure event on a bssid and perform appropriate actions.
* @return True if the blocklist has been modified.
@@ -383,6 +393,8 @@ public class BssidBlocklistMonitor {
ssid, bssid, connectionTime);
if (connectionTime - prevConnectionTime > ABNORMAL_DISCONNECT_RESET_TIME_MS) {
mWifiScoreCard.resetBssidBlocklistStreak(ssid, bssid, REASON_ABNORMAL_DISCONNECT);
+ mWifiScoreCard.resetBssidBlocklistStreak(ssid, bssid,
+ REASON_FRAMEWORK_DISCONNECT_CONNECTED_SCORE);
}
BssidStatus status = mBssidStatusMap.get(bssid);
diff --git a/service/java/com/android/server/wifi/WifiScoreReport.java b/service/java/com/android/server/wifi/WifiScoreReport.java
index 80a561d05..bd92c6dac 100644
--- a/service/java/com/android/server/wifi/WifiScoreReport.java
+++ b/service/java/com/android/server/wifi/WifiScoreReport.java
@@ -60,7 +60,6 @@ public class WifiScoreReport {
private static final int WIFI_CONNECTED_NETWORK_SCORER_IDENTIFIER = 0;
private static final int INVALID_SESSION_ID = -1;
private static final long MIN_TIME_TO_WAIT_BEFORE_BLOCKLIST_BSSID_MILLIS = 29000;
- private static final long DURATION_TO_BLOCKLIST_BSSID_AFTER_FIRST_EXITING_MILLIS = 30000;
private static final long INVALID_WALL_CLOCK_MILLIS = -1;
/**
@@ -751,9 +750,8 @@ public class WifiScoreReport {
if ((mLastScoreBreachLowTimeMillis != INVALID_WALL_CLOCK_MILLIS)
&& ((millis - mLastScoreBreachLowTimeMillis)
>= MIN_TIME_TO_WAIT_BEFORE_BLOCKLIST_BSSID_MILLIS)) {
- mBssidBlocklistMonitor.blockBssidForDurationMs(mWifiInfo.getBSSID(),
+ mBssidBlocklistMonitor.handleBssidConnectionFailure(mWifiInfo.getBSSID(),
mWifiInfo.getSSID(),
- DURATION_TO_BLOCKLIST_BSSID_AFTER_FIRST_EXITING_MILLIS,
BssidBlocklistMonitor.REASON_FRAMEWORK_DISCONNECT_CONNECTED_SCORE,
mWifiInfo.getRssi());
mLastScoreBreachLowTimeMillis = INVALID_WALL_CLOCK_MILLIS;
diff --git a/service/res/values/config.xml b/service/res/values/config.xml
index 1220c260a..0264c3eae 100644
--- a/service/res/values/config.xml
+++ b/service/res/values/config.xml
@@ -355,6 +355,13 @@
config_wifiBssidBlocklistMonitorFailureStreakCap is set to 7-->
<integer translatable="false" name="config_wifiBssidBlocklistMonitorBaseBlockDurationMs"> 300000 </integer>
+ <!-- Base duration to block a BSSID after the external connected scorer sets wifi as unusable.
+ The block duration is increased exponentially if the same BSSID is repeated marked as unusable.
+ ie. 0.5/1/2/4/8/16/32/64 minutes - capped at 64 minutes because the default for
+ config_wifiBssidBlocklistMonitorFailureStreakCap is set to 7. The block duration is reset to
+ the base value 3 hours after the latest connection to this BSSID. -->
+ <integer translatable="false" name="config_wifiBssidBlocklistMonitorConnectedScoreBaseBlockDurationMs"> 30000 </integer>
+
<!-- The failure streak is the number of times a BSSID consecutively gets blocked without ever
successfully connecting in between, and is used to calculate the exponentially growing blocklist time.
The config_wifiBssidBlocklistMonitorFailureStreakCap controls how many times the block duration
diff --git a/service/res/values/overlayable.xml b/service/res/values/overlayable.xml
index 56c94246d..60764ba6e 100644
--- a/service/res/values/overlayable.xml
+++ b/service/res/values/overlayable.xml
@@ -114,6 +114,7 @@
<item type="integer" name="config_wifiBssidBlocklistMonitorDhcpFailureThreshold" />
<item type="integer" name="config_wifiBssidBlocklistMonitorAbnormalDisconnectThreshold" />
<item type="integer" name="config_wifiBssidBlocklistMonitorBaseBlockDurationMs" />
+ <item type="integer" name="config_wifiBssidBlocklistMonitorConnectedScoreBaseBlockDurationMs" />
<item type="integer" name="config_wifiBssidBlocklistMonitorFailureStreakCap" />
<item type="integer" name="config_wifiBssidBlocklistAbnormalDisconnectTimeWindowMs" />
<item type="bool" name="config_wifiScanHiddenNetworksScanOnlyMode" />
diff --git a/tests/wifitests/src/com/android/server/wifi/BssidBlocklistMonitorTest.java b/tests/wifitests/src/com/android/server/wifi/BssidBlocklistMonitorTest.java
index d6333b363..1007391e3 100644
--- a/tests/wifitests/src/com/android/server/wifi/BssidBlocklistMonitorTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/BssidBlocklistMonitorTest.java
@@ -18,6 +18,7 @@ package com.android.server.wifi;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.times;
import android.content.Context;
import android.net.wifi.ScanResult;
@@ -34,6 +35,7 @@ import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@@ -57,23 +59,28 @@ public class BssidBlocklistMonitorTest {
private static final int TEST_L2_FAILURE = BssidBlocklistMonitor.REASON_ASSOCIATION_REJECTION;
private static final int TEST_DHCP_FAILURE = BssidBlocklistMonitor.REASON_DHCP_FAILURE;
private static final long BASE_BLOCKLIST_DURATION = TimeUnit.MINUTES.toMillis(5); // 5 minutes
+ private static final long BASE_CONNECTED_SCORE_BLOCKLIST_DURATION =
+ TimeUnit.SECONDS.toMillis(30);
private static final long ABNORMAL_DISCONNECT_TIME_WINDOW_MS = TimeUnit.SECONDS.toMillis(30);
private static final long ABNORMAL_DISCONNECT_RESET_TIME_MS = TimeUnit.HOURS.toMillis(3);
private static final int FAILURE_STREAK_CAP = 7;
- private static final int[] FAILURE_COUNT_DISABLE_THRESHOLD = {
- 1, // threshold for REASON_AP_UNABLE_TO_HANDLE_NEW_STA
- 1, // threshold for REASON_NETWORK_VALIDATION_FAILURE
- 1, // threshold for REASON_WRONG_PASSWORD
- 1, // threshold for REASON_EAP_FAILURE
- 3, // threshold for REASON_ASSOCIATION_REJECTION
- 3, // threshold for REASON_ASSOCIATION_TIMEOUT
- 3, // threshold for REASON_AUTHENTICATION_FAILURE
- 3, // threshold for REASON_DHCP_FAILURE
- 3 // threshold for REASON_ABNORMAL_DISCONNECT
- };
+ private static final Map<Integer, Integer> BLOCK_REASON_TO_DISABLE_THRESHOLD_MAP =
+ Map.ofEntries(
+ Map.entry(BssidBlocklistMonitor.REASON_AP_UNABLE_TO_HANDLE_NEW_STA, 1),
+ Map.entry(BssidBlocklistMonitor.REASON_NETWORK_VALIDATION_FAILURE, 1),
+ Map.entry(BssidBlocklistMonitor.REASON_WRONG_PASSWORD, 1),
+ Map.entry(BssidBlocklistMonitor.REASON_EAP_FAILURE, 1),
+ Map.entry(BssidBlocklistMonitor.REASON_ASSOCIATION_REJECTION, 3),
+ Map.entry(BssidBlocklistMonitor.REASON_ASSOCIATION_TIMEOUT, 3),
+ Map.entry(BssidBlocklistMonitor.REASON_AUTHENTICATION_FAILURE, 3),
+ Map.entry(BssidBlocklistMonitor.REASON_DHCP_FAILURE, 3),
+ Map.entry(BssidBlocklistMonitor.REASON_ABNORMAL_DISCONNECT, 3),
+ Map.entry(BssidBlocklistMonitor.REASON_FRAMEWORK_DISCONNECT_MBO_OCE, 1),
+ Map.entry(BssidBlocklistMonitor.REASON_FRAMEWORK_DISCONNECT_FAST_RECONNECT, 1),
+ Map.entry(BssidBlocklistMonitor.REASON_FRAMEWORK_DISCONNECT_CONNECTED_SCORE, 1)
+ );
private static final int NUM_FAILURES_TO_BLOCKLIST =
- FAILURE_COUNT_DISABLE_THRESHOLD[TEST_L2_FAILURE];
-
+ BLOCK_REASON_TO_DISABLE_THRESHOLD_MAP.get(TEST_L2_FAILURE);
@Mock private Context mContext;
@Mock private WifiConnectivityHelper mWifiConnectivityHelper;
@@ -97,34 +104,46 @@ public class BssidBlocklistMonitorTest {
mResources = new MockResources();
mResources.setInteger(R.integer.config_wifiBssidBlocklistMonitorBaseBlockDurationMs,
(int) BASE_BLOCKLIST_DURATION);
+ mResources.setInteger(
+ R.integer.config_wifiBssidBlocklistMonitorConnectedScoreBaseBlockDurationMs,
+ (int) BASE_CONNECTED_SCORE_BLOCKLIST_DURATION);
mResources.setInteger(R.integer.config_wifiBssidBlocklistMonitorFailureStreakCap,
FAILURE_STREAK_CAP);
mResources.setInteger(R.integer.config_wifiBssidBlocklistAbnormalDisconnectTimeWindowMs,
(int) ABNORMAL_DISCONNECT_TIME_WINDOW_MS);
mResources.setInteger(
R.integer.config_wifiBssidBlocklistMonitorApUnableToHandleNewStaThreshold,
- FAILURE_COUNT_DISABLE_THRESHOLD[0]);
+ BLOCK_REASON_TO_DISABLE_THRESHOLD_MAP.get(
+ BssidBlocklistMonitor.REASON_AP_UNABLE_TO_HANDLE_NEW_STA));
mResources.setInteger(
R.integer.config_wifiBssidBlocklistMonitorNetworkValidationFailureThreshold,
- FAILURE_COUNT_DISABLE_THRESHOLD[1]);
+ BLOCK_REASON_TO_DISABLE_THRESHOLD_MAP.get(
+ BssidBlocklistMonitor.REASON_NETWORK_VALIDATION_FAILURE));
mResources.setInteger(R.integer.config_wifiBssidBlocklistMonitorWrongPasswordThreshold,
- FAILURE_COUNT_DISABLE_THRESHOLD[2]);
+ BLOCK_REASON_TO_DISABLE_THRESHOLD_MAP.get(
+ BssidBlocklistMonitor.REASON_WRONG_PASSWORD));
mResources.setInteger(R.integer.config_wifiBssidBlocklistMonitorEapFailureThreshold,
- FAILURE_COUNT_DISABLE_THRESHOLD[3]);
+ BLOCK_REASON_TO_DISABLE_THRESHOLD_MAP.get(
+ BssidBlocklistMonitor.REASON_EAP_FAILURE));
mResources.setInteger(
R.integer.config_wifiBssidBlocklistMonitorAssociationRejectionThreshold,
- FAILURE_COUNT_DISABLE_THRESHOLD[4]);
+ BLOCK_REASON_TO_DISABLE_THRESHOLD_MAP.get(
+ BssidBlocklistMonitor.REASON_ASSOCIATION_REJECTION));
mResources.setInteger(
R.integer.config_wifiBssidBlocklistMonitorAssociationTimeoutThreshold,
- FAILURE_COUNT_DISABLE_THRESHOLD[5]);
+ BLOCK_REASON_TO_DISABLE_THRESHOLD_MAP.get(
+ BssidBlocklistMonitor.REASON_ASSOCIATION_TIMEOUT));
mResources.setInteger(
R.integer.config_wifiBssidBlocklistMonitorAuthenticationFailureThreshold,
- FAILURE_COUNT_DISABLE_THRESHOLD[6]);
+ BLOCK_REASON_TO_DISABLE_THRESHOLD_MAP.get(
+ BssidBlocklistMonitor.REASON_AUTHENTICATION_FAILURE));
mResources.setInteger(R.integer.config_wifiBssidBlocklistMonitorDhcpFailureThreshold,
- FAILURE_COUNT_DISABLE_THRESHOLD[7]);
+ BLOCK_REASON_TO_DISABLE_THRESHOLD_MAP.get(
+ BssidBlocklistMonitor.REASON_DHCP_FAILURE));
mResources.setInteger(
R.integer.config_wifiBssidBlocklistMonitorAbnormalDisconnectThreshold,
- FAILURE_COUNT_DISABLE_THRESHOLD[8]);
+ BLOCK_REASON_TO_DISABLE_THRESHOLD_MAP.get(
+ BssidBlocklistMonitor.REASON_ABNORMAL_DISCONNECT));
when(mContext.getResources()).thenReturn(mResources);
mBssidBlocklistMonitor = new BssidBlocklistMonitor(mContext, mWifiConnectivityHelper,
@@ -394,6 +413,8 @@ public class BssidBlocklistMonitorTest {
ABNORMAL_DISCONNECT_RESET_TIME_MS + 1);
verify(mWifiScoreCard).resetBssidBlocklistStreak(TEST_SSID_1, TEST_BSSID_1,
BssidBlocklistMonitor.REASON_ABNORMAL_DISCONNECT);
+ verify(mWifiScoreCard).resetBssidBlocklistStreak(TEST_SSID_1, TEST_BSSID_1,
+ BssidBlocklistMonitor.REASON_FRAMEWORK_DISCONNECT_CONNECTED_SCORE);
}
/**
@@ -410,6 +431,20 @@ public class BssidBlocklistMonitorTest {
}
/**
+ * Verify that the streak count for REASON_FRAMEWORK_DISCONNECT_CONNECTED_SCORE is not reset
+ * if insufficient time has passed.
+ */
+ @Test
+ public void testNetworkConnectionNotResetConnectedScoreStreak() {
+ when(mClock.getWallClockMillis()).thenReturn(ABNORMAL_DISCONNECT_RESET_TIME_MS);
+ mBssidBlocklistMonitor.handleBssidConnectionSuccess(TEST_BSSID_1, TEST_SSID_1);
+ verify(mWifiScoreCard).setBssidConnectionTimestampMs(TEST_SSID_1, TEST_BSSID_1,
+ ABNORMAL_DISCONNECT_RESET_TIME_MS);
+ verify(mWifiScoreCard, never()).resetBssidBlocklistStreak(TEST_SSID_1, TEST_BSSID_1,
+ BssidBlocklistMonitor.REASON_FRAMEWORK_DISCONNECT_CONNECTED_SCORE);
+ }
+
+ /**
* Verify that handleDhcpProvisioningSuccess resets appropriate blocklist streak counts.
*/
@Test
@@ -454,18 +489,23 @@ public class BssidBlocklistMonitorTest {
*/
@Test
public void testIncrementingBlocklistStreakCount() {
- verifyAddTestBssidToBlocklist();
- // verify that the blocklist streak is incremented
- verify(mWifiScoreCard).incrementBssidBlocklistStreak(TEST_SSID_1, TEST_BSSID_1,
- BssidBlocklistMonitor.REASON_AP_UNABLE_TO_HANDLE_NEW_STA);
+ for (Map.Entry<Integer, Integer> entry : BLOCK_REASON_TO_DISABLE_THRESHOLD_MAP.entrySet()) {
+ int reason = entry.getKey();
+ int threshold = entry.getValue();
+ when(mClock.getWallClockMillis()).thenReturn(0L);
+ handleBssidConnectionFailureMultipleTimes(TEST_BSSID_1, TEST_SSID_1, reason, threshold);
- // Verify that TEST_BSSID_1 is removed from the blocklist after the timeout duration.
- when(mClock.getWallClockMillis()).thenReturn(BASE_BLOCKLIST_DURATION + 1);
- assertEquals(0, mBssidBlocklistMonitor.updateAndGetBssidBlocklist().size());
+ // verify that the blocklist streak is incremented
+ verify(mWifiScoreCard).incrementBssidBlocklistStreak(TEST_SSID_1, TEST_BSSID_1, reason);
- // But the blacklist streak count is not cleared
- verify(mWifiScoreCard, never()).resetBssidBlocklistStreak(TEST_SSID_1, TEST_BSSID_1,
- BssidBlocklistMonitor.REASON_AP_UNABLE_TO_HANDLE_NEW_STA);
+ // Verify that TEST_BSSID_1 is removed from the blocklist after the timeout duration.
+ when(mClock.getWallClockMillis()).thenReturn(BASE_BLOCKLIST_DURATION + 1);
+ assertEquals(0, mBssidBlocklistMonitor.updateAndGetBssidBlocklist().size());
+
+ // But the blocklist streak count is not cleared
+ verify(mWifiScoreCard, never()).resetBssidBlocklistStreak(TEST_SSID_1, TEST_BSSID_1,
+ reason);
+ }
}
/**
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java b/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java
index 954d4fe82..b85f223b7 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiScoreReportTest.java
@@ -20,16 +20,15 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.AdditionalAnswers.answerVoid;
-import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.anyLong;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.atMost;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
@@ -782,7 +781,7 @@ public class WifiScoreReportTest extends WifiBaseTest {
}
/**
- * Verify BSSID blocklist doesnot happen when score stays below threshold for less than the
+ * Verify BSSID blocklist does not happen when score stays below threshold for less than the
* minimum duration
*/
@Test
@@ -802,7 +801,7 @@ public class WifiScoreReportTest extends WifiBaseTest {
mLooper.dispatchAll();
mWifiScoreReport.stopConnectedNetworkScorer();
mLooper.dispatchAll();
- verify(mBssidBlocklistMonitor, never()).blockBssidForDurationMs(any(), any(), anyLong(),
+ verify(mBssidBlocklistMonitor, never()).handleBssidConnectionFailure(any(), any(),
anyInt(), anyInt());
}
@@ -827,12 +826,12 @@ public class WifiScoreReportTest extends WifiBaseTest {
mLooper.dispatchAll();
mWifiScoreReport.stopConnectedNetworkScorer();
mLooper.dispatchAll();
- verify(mBssidBlocklistMonitor).blockBssidForDurationMs(any(), any(), anyLong(), anyInt(),
- anyInt());
+ verify(mBssidBlocklistMonitor).handleBssidConnectionFailure(any(), any(),
+ eq(BssidBlocklistMonitor.REASON_FRAMEWORK_DISCONNECT_CONNECTED_SCORE), anyInt());
}
/**
- * Verify BSSID blocklist doesnot happen when there is score flip flop
+ * Verify BSSID blocklist does not happen when there is score flip flop
*/
@Test
public void bssidBlockListDoesnotHappenWhenExitingIsReset() throws Exception {
@@ -854,7 +853,7 @@ public class WifiScoreReportTest extends WifiBaseTest {
mLooper.dispatchAll();
mWifiScoreReport.stopConnectedNetworkScorer();
mLooper.dispatchAll();
- verify(mBssidBlocklistMonitor, never()).blockBssidForDurationMs(any(), any(), anyLong(),
+ verify(mBssidBlocklistMonitor, never()).handleBssidConnectionFailure(any(), any(),
anyInt(), anyInt());
}