2008-02-28 02:34:43 +01:00
|
|
|
/*
|
2021-02-07 16:02:37 +01:00
|
|
|
* wpa_supplicant - List of temporarily ignored BSSIDs
|
|
|
|
* Copyright (c) 2003-2021, Jouni Malinen <j@w1.fi>
|
2008-02-28 02:34:43 +01:00
|
|
|
*
|
2012-02-11 15:46:35 +01:00
|
|
|
* This software may be distributed under the terms of the BSD license.
|
|
|
|
* See README for more details.
|
2008-02-28 02:34:43 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "includes.h"
|
|
|
|
|
|
|
|
#include "common.h"
|
|
|
|
#include "wpa_supplicant_i.h"
|
2021-02-07 16:06:19 +01:00
|
|
|
#include "bssid_ignore.h"
|
2008-02-28 02:34:43 +01:00
|
|
|
|
|
|
|
/**
|
2021-02-07 16:02:37 +01:00
|
|
|
* wpa_bssid_ignore_get - Get the ignore list entry for a BSSID
|
2008-02-28 02:34:43 +01:00
|
|
|
* @wpa_s: Pointer to wpa_supplicant data
|
|
|
|
* @bssid: BSSID
|
2021-02-07 16:02:37 +01:00
|
|
|
* Returns: Matching entry for the BSSID or %NULL if not found
|
2008-02-28 02:34:43 +01:00
|
|
|
*/
|
2021-02-07 16:02:37 +01:00
|
|
|
struct wpa_bssid_ignore * wpa_bssid_ignore_get(struct wpa_supplicant *wpa_s,
|
|
|
|
const u8 *bssid)
|
2008-02-28 02:34:43 +01:00
|
|
|
{
|
2021-02-07 16:02:37 +01:00
|
|
|
struct wpa_bssid_ignore *e;
|
2008-02-28 02:34:43 +01:00
|
|
|
|
2012-11-01 19:41:27 +01:00
|
|
|
if (wpa_s == NULL || bssid == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
wpa_supplicant: Clear blacklist when SSID configs change
If the stored configurations for an SSID have changed, we can no longer
trust the current blacklist state of that SSID, since the updated
configs could change the behavior of the network. E.g., the BSS could be
blacklisted due to a bad password, and the config could be updated to
store the correct password. In this case, keeping the BSS in the
blacklist will prevent the user from connecting to the BSS after the
correct password has been updated.
Add the value was_changed_recently to the wpa_ssid struct. Update this
value every time a config is changed through wpa_set_config(). Check
this value in wpa_blacklist_get() to clear the blacklist whenever the
configs of current_ssid have changed.
This solution was chosen over simply clearing the blacklist whenever
configs change because the user should be able to change configs on an
inactive SSID without affecting the blacklist for the currently active
SSID. This way, the blacklist won't be cleared until the user attempts
to connect to the inactive network again. Furthermore, the blacklist is
stored per-BSSID while configs are stored per-SSID, so we don't have the
option to just clear out certain blacklist entries that would be
affected by the configs.
Finally, the function wpa_supplicant_reload_configuration() causes the
configs to be reloaded from scratch, so after a call to this function
all bets are off as to the relevance of our current blacklist state.
Thus, we clear the entire blacklist within this function.
Signed-off-by: Kevin Lund <kglund@google.com>
Signed-off-by: Brian Norris <briannorris@chromium.org>
2020-06-11 23:11:19 +02:00
|
|
|
if (wpa_s->current_ssid &&
|
|
|
|
wpa_s->current_ssid->was_recently_reconfigured) {
|
2021-02-07 16:02:37 +01:00
|
|
|
wpa_bssid_ignore_clear(wpa_s);
|
wpa_supplicant: Clear blacklist when SSID configs change
If the stored configurations for an SSID have changed, we can no longer
trust the current blacklist state of that SSID, since the updated
configs could change the behavior of the network. E.g., the BSS could be
blacklisted due to a bad password, and the config could be updated to
store the correct password. In this case, keeping the BSS in the
blacklist will prevent the user from connecting to the BSS after the
correct password has been updated.
Add the value was_changed_recently to the wpa_ssid struct. Update this
value every time a config is changed through wpa_set_config(). Check
this value in wpa_blacklist_get() to clear the blacklist whenever the
configs of current_ssid have changed.
This solution was chosen over simply clearing the blacklist whenever
configs change because the user should be able to change configs on an
inactive SSID without affecting the blacklist for the currently active
SSID. This way, the blacklist won't be cleared until the user attempts
to connect to the inactive network again. Furthermore, the blacklist is
stored per-BSSID while configs are stored per-SSID, so we don't have the
option to just clear out certain blacklist entries that would be
affected by the configs.
Finally, the function wpa_supplicant_reload_configuration() causes the
configs to be reloaded from scratch, so after a call to this function
all bets are off as to the relevance of our current blacklist state.
Thus, we clear the entire blacklist within this function.
Signed-off-by: Kevin Lund <kglund@google.com>
Signed-off-by: Brian Norris <briannorris@chromium.org>
2020-06-11 23:11:19 +02:00
|
|
|
wpa_s->current_ssid->was_recently_reconfigured = false;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2021-02-07 16:02:37 +01:00
|
|
|
wpa_bssid_ignore_update(wpa_s);
|
2020-06-11 23:11:17 +02:00
|
|
|
|
2021-02-07 16:02:37 +01:00
|
|
|
e = wpa_s->bssid_ignore;
|
2008-02-28 02:34:43 +01:00
|
|
|
while (e) {
|
Use ether_addr_equal() to compare whether two MAC addresses are equal
This was done with spatch using the following semantic patch and minor
manual edits to clean up coding style and avoid compiler warnings in
driver_wext.c:
@@
expression a,b;
@@
- os_memcmp(a, b, ETH_ALEN) == 0
+ ether_addr_equal(a, b)
@@
expression a,b;
@@
- os_memcmp(a, b, ETH_ALEN) != 0
+ !ether_addr_equal(a, b)
@@
expression a,b;
@@
- !os_memcmp(a, b, ETH_ALEN)
+ ether_addr_equal(a, b)
Signed-off-by: Jouni Malinen <j@w1.fi>
2024-01-13 22:15:36 +01:00
|
|
|
if (ether_addr_equal(e->bssid, bssid))
|
2008-02-28 02:34:43 +01:00
|
|
|
return e;
|
|
|
|
e = e->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2021-02-07 16:02:37 +01:00
|
|
|
* wpa_bssid_ignore_add - Add an BSSID to the ignore list
|
2008-02-28 02:34:43 +01:00
|
|
|
* @wpa_s: Pointer to wpa_supplicant data
|
2021-02-07 16:02:37 +01:00
|
|
|
* @bssid: BSSID to be added to the ignore list
|
|
|
|
* Returns: Current ignore list count on success, -1 on failure
|
2008-02-28 02:34:43 +01:00
|
|
|
*
|
2021-02-07 16:02:37 +01:00
|
|
|
* This function adds the specified BSSID to the ignore list or increases the
|
|
|
|
* ignore count if the BSSID was already listed. It should be called when
|
2008-02-28 02:34:43 +01:00
|
|
|
* an association attempt fails either due to the selected BSS rejecting
|
|
|
|
* association or due to timeout.
|
|
|
|
*
|
2021-02-07 16:02:37 +01:00
|
|
|
* This ignore list is used to force %wpa_supplicant to go through all available
|
2008-02-28 02:34:43 +01:00
|
|
|
* BSSes before retrying to associate with an BSS that rejected or timed out
|
|
|
|
* association. It does not prevent the listed BSS from being used; it only
|
|
|
|
* changes the order in which they are tried.
|
|
|
|
*/
|
2021-02-07 16:02:37 +01:00
|
|
|
int wpa_bssid_ignore_add(struct wpa_supplicant *wpa_s, const u8 *bssid)
|
2008-02-28 02:34:43 +01:00
|
|
|
{
|
2021-02-07 16:02:37 +01:00
|
|
|
struct wpa_bssid_ignore *e;
|
wpa_supplicant: Implement time-based blacklisting
wpa_supplicant keeps a blacklist of BSSs in order to prevent repeated
associations to problematic APs*. Currently, this blacklist is
completely cleared whenever we successfully connect to any AP. This
causes problematic behavior when in the presence of both a bad AP and
a good AP. The device can repeatedly attempt to roam to the bad AP
because it is clearing the blacklist every time it connects to the good
AP. This results in the connection constantly ping-ponging between the
APs, leaving the user stuck without connection.
Instead of clearing the blacklist, implement timeout functionality which
allows association attempts to blacklisted APs after some time has
passed. Each time a BSS would be added to the blacklist, increase the
duration of this timeout exponentially, up to a cap of 1800 seconds.
This means that the device will no longer be able to immediately attempt
to roam back to a bad AP whenever it successfully connects to any other
AP.
Other details:
The algorithm for building up the blacklist count and timeout duration
on a given AP has been designed to be minimally obtrusive. Starting with
a fresh blacklist, the device may attempt to connect to a problematic AP
no more than 6 times in any ~45 minute period. Once an AP has reached a
blacklist count >= 6, the device may attempt to connect to it no more
than once every 30 minutes. The goal of these limits is to find an
ideal balance between minimizing connection attempts to bad APs while
still trying them out occasionally to see if the problems have stopped.
The only exception to the above limits is that the blacklist is still
completely cleared whenever there are no APs available in a scan. This
means that if all nearby APs have been blacklisted, all APs will be
completely exonerated regardless of their blacklist counts or how close
their blacklist entries are to expiring. When all nearby APs have been
blacklisted we know that every nearby AP is in some way problematic.
Once we know that every AP is causing problems, it doesn't really make
sense to sort them beyond that because the blacklist count and timeout
duration don't necessarily reflect the degree to which an AP is
problematic (i.e. they can be manipulated by external factors such as
the user physically moving around). Instead, its best to restart the
blacklist and let the normal roaming algorithm take over to maximize
our chance of getting the best possible connection quality.
As stated above, the time-based blacklisting algorithm is designed to
be minimally obtrusive to user experience, so occasionally restarting
the process is not too impactful on the user.
*problematic AP: rejects new clients, frequently de-auths clients, very
poor connection quality, etc.
Signed-off-by: Kevin Lund <kglund@google.com>
Signed-off-by: Brian Norris <briannorris@chromium.org>
2020-06-11 23:11:16 +02:00
|
|
|
struct os_reltime now;
|
2008-02-28 02:34:43 +01:00
|
|
|
|
2012-11-01 19:41:27 +01:00
|
|
|
if (wpa_s == NULL || bssid == NULL)
|
|
|
|
return -1;
|
|
|
|
|
2021-02-07 16:02:37 +01:00
|
|
|
e = wpa_bssid_ignore_get(wpa_s, bssid);
|
wpa_supplicant: Implement time-based blacklisting
wpa_supplicant keeps a blacklist of BSSs in order to prevent repeated
associations to problematic APs*. Currently, this blacklist is
completely cleared whenever we successfully connect to any AP. This
causes problematic behavior when in the presence of both a bad AP and
a good AP. The device can repeatedly attempt to roam to the bad AP
because it is clearing the blacklist every time it connects to the good
AP. This results in the connection constantly ping-ponging between the
APs, leaving the user stuck without connection.
Instead of clearing the blacklist, implement timeout functionality which
allows association attempts to blacklisted APs after some time has
passed. Each time a BSS would be added to the blacklist, increase the
duration of this timeout exponentially, up to a cap of 1800 seconds.
This means that the device will no longer be able to immediately attempt
to roam back to a bad AP whenever it successfully connects to any other
AP.
Other details:
The algorithm for building up the blacklist count and timeout duration
on a given AP has been designed to be minimally obtrusive. Starting with
a fresh blacklist, the device may attempt to connect to a problematic AP
no more than 6 times in any ~45 minute period. Once an AP has reached a
blacklist count >= 6, the device may attempt to connect to it no more
than once every 30 minutes. The goal of these limits is to find an
ideal balance between minimizing connection attempts to bad APs while
still trying them out occasionally to see if the problems have stopped.
The only exception to the above limits is that the blacklist is still
completely cleared whenever there are no APs available in a scan. This
means that if all nearby APs have been blacklisted, all APs will be
completely exonerated regardless of their blacklist counts or how close
their blacklist entries are to expiring. When all nearby APs have been
blacklisted we know that every nearby AP is in some way problematic.
Once we know that every AP is causing problems, it doesn't really make
sense to sort them beyond that because the blacklist count and timeout
duration don't necessarily reflect the degree to which an AP is
problematic (i.e. they can be manipulated by external factors such as
the user physically moving around). Instead, its best to restart the
blacklist and let the normal roaming algorithm take over to maximize
our chance of getting the best possible connection quality.
As stated above, the time-based blacklisting algorithm is designed to
be minimally obtrusive to user experience, so occasionally restarting
the process is not too impactful on the user.
*problematic AP: rejects new clients, frequently de-auths clients, very
poor connection quality, etc.
Signed-off-by: Kevin Lund <kglund@google.com>
Signed-off-by: Brian Norris <briannorris@chromium.org>
2020-06-11 23:11:16 +02:00
|
|
|
os_get_reltime(&now);
|
2008-02-28 02:34:43 +01:00
|
|
|
if (e) {
|
2021-02-07 16:02:37 +01:00
|
|
|
e->start = now;
|
2008-02-28 02:34:43 +01:00
|
|
|
e->count++;
|
wpa_supplicant: Implement time-based blacklisting
wpa_supplicant keeps a blacklist of BSSs in order to prevent repeated
associations to problematic APs*. Currently, this blacklist is
completely cleared whenever we successfully connect to any AP. This
causes problematic behavior when in the presence of both a bad AP and
a good AP. The device can repeatedly attempt to roam to the bad AP
because it is clearing the blacklist every time it connects to the good
AP. This results in the connection constantly ping-ponging between the
APs, leaving the user stuck without connection.
Instead of clearing the blacklist, implement timeout functionality which
allows association attempts to blacklisted APs after some time has
passed. Each time a BSS would be added to the blacklist, increase the
duration of this timeout exponentially, up to a cap of 1800 seconds.
This means that the device will no longer be able to immediately attempt
to roam back to a bad AP whenever it successfully connects to any other
AP.
Other details:
The algorithm for building up the blacklist count and timeout duration
on a given AP has been designed to be minimally obtrusive. Starting with
a fresh blacklist, the device may attempt to connect to a problematic AP
no more than 6 times in any ~45 minute period. Once an AP has reached a
blacklist count >= 6, the device may attempt to connect to it no more
than once every 30 minutes. The goal of these limits is to find an
ideal balance between minimizing connection attempts to bad APs while
still trying them out occasionally to see if the problems have stopped.
The only exception to the above limits is that the blacklist is still
completely cleared whenever there are no APs available in a scan. This
means that if all nearby APs have been blacklisted, all APs will be
completely exonerated regardless of their blacklist counts or how close
their blacklist entries are to expiring. When all nearby APs have been
blacklisted we know that every nearby AP is in some way problematic.
Once we know that every AP is causing problems, it doesn't really make
sense to sort them beyond that because the blacklist count and timeout
duration don't necessarily reflect the degree to which an AP is
problematic (i.e. they can be manipulated by external factors such as
the user physically moving around). Instead, its best to restart the
blacklist and let the normal roaming algorithm take over to maximize
our chance of getting the best possible connection quality.
As stated above, the time-based blacklisting algorithm is designed to
be minimally obtrusive to user experience, so occasionally restarting
the process is not too impactful on the user.
*problematic AP: rejects new clients, frequently de-auths clients, very
poor connection quality, etc.
Signed-off-by: Kevin Lund <kglund@google.com>
Signed-off-by: Brian Norris <briannorris@chromium.org>
2020-06-11 23:11:16 +02:00
|
|
|
if (e->count > 5)
|
|
|
|
e->timeout_secs = 1800;
|
|
|
|
else if (e->count == 5)
|
|
|
|
e->timeout_secs = 600;
|
|
|
|
else if (e->count == 4)
|
|
|
|
e->timeout_secs = 120;
|
|
|
|
else if (e->count == 3)
|
|
|
|
e->timeout_secs = 60;
|
|
|
|
else
|
|
|
|
e->timeout_secs = 10;
|
2023-11-21 00:51:45 +01:00
|
|
|
wpa_msg(wpa_s, MSG_INFO, "BSSID " MACSTR
|
|
|
|
" ignore list count incremented to %d, ignoring for %d seconds",
|
|
|
|
MAC2STR(bssid), e->count, e->timeout_secs);
|
2010-11-25 21:00:04 +01:00
|
|
|
return e->count;
|
2008-02-28 02:34:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
e = os_zalloc(sizeof(*e));
|
|
|
|
if (e == NULL)
|
|
|
|
return -1;
|
|
|
|
os_memcpy(e->bssid, bssid, ETH_ALEN);
|
|
|
|
e->count = 1;
|
wpa_supplicant: Implement time-based blacklisting
wpa_supplicant keeps a blacklist of BSSs in order to prevent repeated
associations to problematic APs*. Currently, this blacklist is
completely cleared whenever we successfully connect to any AP. This
causes problematic behavior when in the presence of both a bad AP and
a good AP. The device can repeatedly attempt to roam to the bad AP
because it is clearing the blacklist every time it connects to the good
AP. This results in the connection constantly ping-ponging between the
APs, leaving the user stuck without connection.
Instead of clearing the blacklist, implement timeout functionality which
allows association attempts to blacklisted APs after some time has
passed. Each time a BSS would be added to the blacklist, increase the
duration of this timeout exponentially, up to a cap of 1800 seconds.
This means that the device will no longer be able to immediately attempt
to roam back to a bad AP whenever it successfully connects to any other
AP.
Other details:
The algorithm for building up the blacklist count and timeout duration
on a given AP has been designed to be minimally obtrusive. Starting with
a fresh blacklist, the device may attempt to connect to a problematic AP
no more than 6 times in any ~45 minute period. Once an AP has reached a
blacklist count >= 6, the device may attempt to connect to it no more
than once every 30 minutes. The goal of these limits is to find an
ideal balance between minimizing connection attempts to bad APs while
still trying them out occasionally to see if the problems have stopped.
The only exception to the above limits is that the blacklist is still
completely cleared whenever there are no APs available in a scan. This
means that if all nearby APs have been blacklisted, all APs will be
completely exonerated regardless of their blacklist counts or how close
their blacklist entries are to expiring. When all nearby APs have been
blacklisted we know that every nearby AP is in some way problematic.
Once we know that every AP is causing problems, it doesn't really make
sense to sort them beyond that because the blacklist count and timeout
duration don't necessarily reflect the degree to which an AP is
problematic (i.e. they can be manipulated by external factors such as
the user physically moving around). Instead, its best to restart the
blacklist and let the normal roaming algorithm take over to maximize
our chance of getting the best possible connection quality.
As stated above, the time-based blacklisting algorithm is designed to
be minimally obtrusive to user experience, so occasionally restarting
the process is not too impactful on the user.
*problematic AP: rejects new clients, frequently de-auths clients, very
poor connection quality, etc.
Signed-off-by: Kevin Lund <kglund@google.com>
Signed-off-by: Brian Norris <briannorris@chromium.org>
2020-06-11 23:11:16 +02:00
|
|
|
e->timeout_secs = 10;
|
2021-02-07 16:02:37 +01:00
|
|
|
e->start = now;
|
|
|
|
e->next = wpa_s->bssid_ignore;
|
|
|
|
wpa_s->bssid_ignore = e;
|
2023-11-21 00:51:45 +01:00
|
|
|
wpa_msg(wpa_s, MSG_INFO, "Added BSSID " MACSTR
|
|
|
|
" into ignore list, ignoring for %d seconds",
|
|
|
|
MAC2STR(bssid), e->timeout_secs);
|
2008-02-28 02:34:43 +01:00
|
|
|
|
2010-11-25 21:00:04 +01:00
|
|
|
return e->count;
|
2008-02-28 02:34:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2021-02-07 16:02:37 +01:00
|
|
|
* wpa_bssid_ignore_del - Remove an BSSID from the ignore list
|
2008-02-28 02:34:43 +01:00
|
|
|
* @wpa_s: Pointer to wpa_supplicant data
|
2021-02-07 16:02:37 +01:00
|
|
|
* @bssid: BSSID to be removed from the ignore list
|
2008-02-28 02:34:43 +01:00
|
|
|
* Returns: 0 on success, -1 on failure
|
|
|
|
*/
|
2021-02-07 16:02:37 +01:00
|
|
|
int wpa_bssid_ignore_del(struct wpa_supplicant *wpa_s, const u8 *bssid)
|
2008-02-28 02:34:43 +01:00
|
|
|
{
|
2021-02-07 16:02:37 +01:00
|
|
|
struct wpa_bssid_ignore *e, *prev = NULL;
|
2008-02-28 02:34:43 +01:00
|
|
|
|
2012-11-01 19:41:27 +01:00
|
|
|
if (wpa_s == NULL || bssid == NULL)
|
|
|
|
return -1;
|
|
|
|
|
2021-02-07 16:02:37 +01:00
|
|
|
e = wpa_s->bssid_ignore;
|
2008-02-28 02:34:43 +01:00
|
|
|
while (e) {
|
Use ether_addr_equal() to compare whether two MAC addresses are equal
This was done with spatch using the following semantic patch and minor
manual edits to clean up coding style and avoid compiler warnings in
driver_wext.c:
@@
expression a,b;
@@
- os_memcmp(a, b, ETH_ALEN) == 0
+ ether_addr_equal(a, b)
@@
expression a,b;
@@
- os_memcmp(a, b, ETH_ALEN) != 0
+ !ether_addr_equal(a, b)
@@
expression a,b;
@@
- !os_memcmp(a, b, ETH_ALEN)
+ ether_addr_equal(a, b)
Signed-off-by: Jouni Malinen <j@w1.fi>
2024-01-13 22:15:36 +01:00
|
|
|
if (ether_addr_equal(e->bssid, bssid)) {
|
2008-02-28 02:34:43 +01:00
|
|
|
if (prev == NULL) {
|
2021-02-07 16:02:37 +01:00
|
|
|
wpa_s->bssid_ignore = e->next;
|
2008-02-28 02:34:43 +01:00
|
|
|
} else {
|
|
|
|
prev->next = e->next;
|
|
|
|
}
|
2023-11-21 00:51:45 +01:00
|
|
|
wpa_msg(wpa_s, MSG_INFO, "Removed BSSID " MACSTR
|
|
|
|
" from ignore list", MAC2STR(bssid));
|
2008-02-28 02:34:43 +01:00
|
|
|
os_free(e);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
prev = e;
|
|
|
|
e = e->next;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
wpa_supplicant: Implement time-based blacklisting
wpa_supplicant keeps a blacklist of BSSs in order to prevent repeated
associations to problematic APs*. Currently, this blacklist is
completely cleared whenever we successfully connect to any AP. This
causes problematic behavior when in the presence of both a bad AP and
a good AP. The device can repeatedly attempt to roam to the bad AP
because it is clearing the blacklist every time it connects to the good
AP. This results in the connection constantly ping-ponging between the
APs, leaving the user stuck without connection.
Instead of clearing the blacklist, implement timeout functionality which
allows association attempts to blacklisted APs after some time has
passed. Each time a BSS would be added to the blacklist, increase the
duration of this timeout exponentially, up to a cap of 1800 seconds.
This means that the device will no longer be able to immediately attempt
to roam back to a bad AP whenever it successfully connects to any other
AP.
Other details:
The algorithm for building up the blacklist count and timeout duration
on a given AP has been designed to be minimally obtrusive. Starting with
a fresh blacklist, the device may attempt to connect to a problematic AP
no more than 6 times in any ~45 minute period. Once an AP has reached a
blacklist count >= 6, the device may attempt to connect to it no more
than once every 30 minutes. The goal of these limits is to find an
ideal balance between minimizing connection attempts to bad APs while
still trying them out occasionally to see if the problems have stopped.
The only exception to the above limits is that the blacklist is still
completely cleared whenever there are no APs available in a scan. This
means that if all nearby APs have been blacklisted, all APs will be
completely exonerated regardless of their blacklist counts or how close
their blacklist entries are to expiring. When all nearby APs have been
blacklisted we know that every nearby AP is in some way problematic.
Once we know that every AP is causing problems, it doesn't really make
sense to sort them beyond that because the blacklist count and timeout
duration don't necessarily reflect the degree to which an AP is
problematic (i.e. they can be manipulated by external factors such as
the user physically moving around). Instead, its best to restart the
blacklist and let the normal roaming algorithm take over to maximize
our chance of getting the best possible connection quality.
As stated above, the time-based blacklisting algorithm is designed to
be minimally obtrusive to user experience, so occasionally restarting
the process is not too impactful on the user.
*problematic AP: rejects new clients, frequently de-auths clients, very
poor connection quality, etc.
Signed-off-by: Kevin Lund <kglund@google.com>
Signed-off-by: Brian Norris <briannorris@chromium.org>
2020-06-11 23:11:16 +02:00
|
|
|
/**
|
2021-02-07 16:02:37 +01:00
|
|
|
* wpa_bssid_ignore_is_listed - Check whether a BSSID is ignored temporarily
|
wpa_supplicant: Implement time-based blacklisting
wpa_supplicant keeps a blacklist of BSSs in order to prevent repeated
associations to problematic APs*. Currently, this blacklist is
completely cleared whenever we successfully connect to any AP. This
causes problematic behavior when in the presence of both a bad AP and
a good AP. The device can repeatedly attempt to roam to the bad AP
because it is clearing the blacklist every time it connects to the good
AP. This results in the connection constantly ping-ponging between the
APs, leaving the user stuck without connection.
Instead of clearing the blacklist, implement timeout functionality which
allows association attempts to blacklisted APs after some time has
passed. Each time a BSS would be added to the blacklist, increase the
duration of this timeout exponentially, up to a cap of 1800 seconds.
This means that the device will no longer be able to immediately attempt
to roam back to a bad AP whenever it successfully connects to any other
AP.
Other details:
The algorithm for building up the blacklist count and timeout duration
on a given AP has been designed to be minimally obtrusive. Starting with
a fresh blacklist, the device may attempt to connect to a problematic AP
no more than 6 times in any ~45 minute period. Once an AP has reached a
blacklist count >= 6, the device may attempt to connect to it no more
than once every 30 minutes. The goal of these limits is to find an
ideal balance between minimizing connection attempts to bad APs while
still trying them out occasionally to see if the problems have stopped.
The only exception to the above limits is that the blacklist is still
completely cleared whenever there are no APs available in a scan. This
means that if all nearby APs have been blacklisted, all APs will be
completely exonerated regardless of their blacklist counts or how close
their blacklist entries are to expiring. When all nearby APs have been
blacklisted we know that every nearby AP is in some way problematic.
Once we know that every AP is causing problems, it doesn't really make
sense to sort them beyond that because the blacklist count and timeout
duration don't necessarily reflect the degree to which an AP is
problematic (i.e. they can be manipulated by external factors such as
the user physically moving around). Instead, its best to restart the
blacklist and let the normal roaming algorithm take over to maximize
our chance of getting the best possible connection quality.
As stated above, the time-based blacklisting algorithm is designed to
be minimally obtrusive to user experience, so occasionally restarting
the process is not too impactful on the user.
*problematic AP: rejects new clients, frequently de-auths clients, very
poor connection quality, etc.
Signed-off-by: Kevin Lund <kglund@google.com>
Signed-off-by: Brian Norris <briannorris@chromium.org>
2020-06-11 23:11:16 +02:00
|
|
|
* @wpa_s: Pointer to wpa_supplicant data
|
|
|
|
* @bssid: BSSID to be checked
|
2021-02-07 16:02:37 +01:00
|
|
|
* Returns: count if BSS is currently considered to be ignored, 0 otherwise
|
wpa_supplicant: Implement time-based blacklisting
wpa_supplicant keeps a blacklist of BSSs in order to prevent repeated
associations to problematic APs*. Currently, this blacklist is
completely cleared whenever we successfully connect to any AP. This
causes problematic behavior when in the presence of both a bad AP and
a good AP. The device can repeatedly attempt to roam to the bad AP
because it is clearing the blacklist every time it connects to the good
AP. This results in the connection constantly ping-ponging between the
APs, leaving the user stuck without connection.
Instead of clearing the blacklist, implement timeout functionality which
allows association attempts to blacklisted APs after some time has
passed. Each time a BSS would be added to the blacklist, increase the
duration of this timeout exponentially, up to a cap of 1800 seconds.
This means that the device will no longer be able to immediately attempt
to roam back to a bad AP whenever it successfully connects to any other
AP.
Other details:
The algorithm for building up the blacklist count and timeout duration
on a given AP has been designed to be minimally obtrusive. Starting with
a fresh blacklist, the device may attempt to connect to a problematic AP
no more than 6 times in any ~45 minute period. Once an AP has reached a
blacklist count >= 6, the device may attempt to connect to it no more
than once every 30 minutes. The goal of these limits is to find an
ideal balance between minimizing connection attempts to bad APs while
still trying them out occasionally to see if the problems have stopped.
The only exception to the above limits is that the blacklist is still
completely cleared whenever there are no APs available in a scan. This
means that if all nearby APs have been blacklisted, all APs will be
completely exonerated regardless of their blacklist counts or how close
their blacklist entries are to expiring. When all nearby APs have been
blacklisted we know that every nearby AP is in some way problematic.
Once we know that every AP is causing problems, it doesn't really make
sense to sort them beyond that because the blacklist count and timeout
duration don't necessarily reflect the degree to which an AP is
problematic (i.e. they can be manipulated by external factors such as
the user physically moving around). Instead, its best to restart the
blacklist and let the normal roaming algorithm take over to maximize
our chance of getting the best possible connection quality.
As stated above, the time-based blacklisting algorithm is designed to
be minimally obtrusive to user experience, so occasionally restarting
the process is not too impactful on the user.
*problematic AP: rejects new clients, frequently de-auths clients, very
poor connection quality, etc.
Signed-off-by: Kevin Lund <kglund@google.com>
Signed-off-by: Brian Norris <briannorris@chromium.org>
2020-06-11 23:11:16 +02:00
|
|
|
*/
|
2021-02-07 16:02:37 +01:00
|
|
|
int wpa_bssid_ignore_is_listed(struct wpa_supplicant *wpa_s, const u8 *bssid)
|
wpa_supplicant: Implement time-based blacklisting
wpa_supplicant keeps a blacklist of BSSs in order to prevent repeated
associations to problematic APs*. Currently, this blacklist is
completely cleared whenever we successfully connect to any AP. This
causes problematic behavior when in the presence of both a bad AP and
a good AP. The device can repeatedly attempt to roam to the bad AP
because it is clearing the blacklist every time it connects to the good
AP. This results in the connection constantly ping-ponging between the
APs, leaving the user stuck without connection.
Instead of clearing the blacklist, implement timeout functionality which
allows association attempts to blacklisted APs after some time has
passed. Each time a BSS would be added to the blacklist, increase the
duration of this timeout exponentially, up to a cap of 1800 seconds.
This means that the device will no longer be able to immediately attempt
to roam back to a bad AP whenever it successfully connects to any other
AP.
Other details:
The algorithm for building up the blacklist count and timeout duration
on a given AP has been designed to be minimally obtrusive. Starting with
a fresh blacklist, the device may attempt to connect to a problematic AP
no more than 6 times in any ~45 minute period. Once an AP has reached a
blacklist count >= 6, the device may attempt to connect to it no more
than once every 30 minutes. The goal of these limits is to find an
ideal balance between minimizing connection attempts to bad APs while
still trying them out occasionally to see if the problems have stopped.
The only exception to the above limits is that the blacklist is still
completely cleared whenever there are no APs available in a scan. This
means that if all nearby APs have been blacklisted, all APs will be
completely exonerated regardless of their blacklist counts or how close
their blacklist entries are to expiring. When all nearby APs have been
blacklisted we know that every nearby AP is in some way problematic.
Once we know that every AP is causing problems, it doesn't really make
sense to sort them beyond that because the blacklist count and timeout
duration don't necessarily reflect the degree to which an AP is
problematic (i.e. they can be manipulated by external factors such as
the user physically moving around). Instead, its best to restart the
blacklist and let the normal roaming algorithm take over to maximize
our chance of getting the best possible connection quality.
As stated above, the time-based blacklisting algorithm is designed to
be minimally obtrusive to user experience, so occasionally restarting
the process is not too impactful on the user.
*problematic AP: rejects new clients, frequently de-auths clients, very
poor connection quality, etc.
Signed-off-by: Kevin Lund <kglund@google.com>
Signed-off-by: Brian Norris <briannorris@chromium.org>
2020-06-11 23:11:16 +02:00
|
|
|
{
|
2021-02-07 16:02:37 +01:00
|
|
|
struct wpa_bssid_ignore *e;
|
wpa_supplicant: Implement time-based blacklisting
wpa_supplicant keeps a blacklist of BSSs in order to prevent repeated
associations to problematic APs*. Currently, this blacklist is
completely cleared whenever we successfully connect to any AP. This
causes problematic behavior when in the presence of both a bad AP and
a good AP. The device can repeatedly attempt to roam to the bad AP
because it is clearing the blacklist every time it connects to the good
AP. This results in the connection constantly ping-ponging between the
APs, leaving the user stuck without connection.
Instead of clearing the blacklist, implement timeout functionality which
allows association attempts to blacklisted APs after some time has
passed. Each time a BSS would be added to the blacklist, increase the
duration of this timeout exponentially, up to a cap of 1800 seconds.
This means that the device will no longer be able to immediately attempt
to roam back to a bad AP whenever it successfully connects to any other
AP.
Other details:
The algorithm for building up the blacklist count and timeout duration
on a given AP has been designed to be minimally obtrusive. Starting with
a fresh blacklist, the device may attempt to connect to a problematic AP
no more than 6 times in any ~45 minute period. Once an AP has reached a
blacklist count >= 6, the device may attempt to connect to it no more
than once every 30 minutes. The goal of these limits is to find an
ideal balance between minimizing connection attempts to bad APs while
still trying them out occasionally to see if the problems have stopped.
The only exception to the above limits is that the blacklist is still
completely cleared whenever there are no APs available in a scan. This
means that if all nearby APs have been blacklisted, all APs will be
completely exonerated regardless of their blacklist counts or how close
their blacklist entries are to expiring. When all nearby APs have been
blacklisted we know that every nearby AP is in some way problematic.
Once we know that every AP is causing problems, it doesn't really make
sense to sort them beyond that because the blacklist count and timeout
duration don't necessarily reflect the degree to which an AP is
problematic (i.e. they can be manipulated by external factors such as
the user physically moving around). Instead, its best to restart the
blacklist and let the normal roaming algorithm take over to maximize
our chance of getting the best possible connection quality.
As stated above, the time-based blacklisting algorithm is designed to
be minimally obtrusive to user experience, so occasionally restarting
the process is not too impactful on the user.
*problematic AP: rejects new clients, frequently de-auths clients, very
poor connection quality, etc.
Signed-off-by: Kevin Lund <kglund@google.com>
Signed-off-by: Brian Norris <briannorris@chromium.org>
2020-06-11 23:11:16 +02:00
|
|
|
struct os_reltime now;
|
|
|
|
|
2021-02-07 16:02:37 +01:00
|
|
|
e = wpa_bssid_ignore_get(wpa_s, bssid);
|
wpa_supplicant: Implement time-based blacklisting
wpa_supplicant keeps a blacklist of BSSs in order to prevent repeated
associations to problematic APs*. Currently, this blacklist is
completely cleared whenever we successfully connect to any AP. This
causes problematic behavior when in the presence of both a bad AP and
a good AP. The device can repeatedly attempt to roam to the bad AP
because it is clearing the blacklist every time it connects to the good
AP. This results in the connection constantly ping-ponging between the
APs, leaving the user stuck without connection.
Instead of clearing the blacklist, implement timeout functionality which
allows association attempts to blacklisted APs after some time has
passed. Each time a BSS would be added to the blacklist, increase the
duration of this timeout exponentially, up to a cap of 1800 seconds.
This means that the device will no longer be able to immediately attempt
to roam back to a bad AP whenever it successfully connects to any other
AP.
Other details:
The algorithm for building up the blacklist count and timeout duration
on a given AP has been designed to be minimally obtrusive. Starting with
a fresh blacklist, the device may attempt to connect to a problematic AP
no more than 6 times in any ~45 minute period. Once an AP has reached a
blacklist count >= 6, the device may attempt to connect to it no more
than once every 30 minutes. The goal of these limits is to find an
ideal balance between minimizing connection attempts to bad APs while
still trying them out occasionally to see if the problems have stopped.
The only exception to the above limits is that the blacklist is still
completely cleared whenever there are no APs available in a scan. This
means that if all nearby APs have been blacklisted, all APs will be
completely exonerated regardless of their blacklist counts or how close
their blacklist entries are to expiring. When all nearby APs have been
blacklisted we know that every nearby AP is in some way problematic.
Once we know that every AP is causing problems, it doesn't really make
sense to sort them beyond that because the blacklist count and timeout
duration don't necessarily reflect the degree to which an AP is
problematic (i.e. they can be manipulated by external factors such as
the user physically moving around). Instead, its best to restart the
blacklist and let the normal roaming algorithm take over to maximize
our chance of getting the best possible connection quality.
As stated above, the time-based blacklisting algorithm is designed to
be minimally obtrusive to user experience, so occasionally restarting
the process is not too impactful on the user.
*problematic AP: rejects new clients, frequently de-auths clients, very
poor connection quality, etc.
Signed-off-by: Kevin Lund <kglund@google.com>
Signed-off-by: Brian Norris <briannorris@chromium.org>
2020-06-11 23:11:16 +02:00
|
|
|
if (!e)
|
|
|
|
return 0;
|
|
|
|
os_get_reltime(&now);
|
2021-02-07 16:02:37 +01:00
|
|
|
if (os_reltime_expired(&now, &e->start, e->timeout_secs))
|
wpa_supplicant: Implement time-based blacklisting
wpa_supplicant keeps a blacklist of BSSs in order to prevent repeated
associations to problematic APs*. Currently, this blacklist is
completely cleared whenever we successfully connect to any AP. This
causes problematic behavior when in the presence of both a bad AP and
a good AP. The device can repeatedly attempt to roam to the bad AP
because it is clearing the blacklist every time it connects to the good
AP. This results in the connection constantly ping-ponging between the
APs, leaving the user stuck without connection.
Instead of clearing the blacklist, implement timeout functionality which
allows association attempts to blacklisted APs after some time has
passed. Each time a BSS would be added to the blacklist, increase the
duration of this timeout exponentially, up to a cap of 1800 seconds.
This means that the device will no longer be able to immediately attempt
to roam back to a bad AP whenever it successfully connects to any other
AP.
Other details:
The algorithm for building up the blacklist count and timeout duration
on a given AP has been designed to be minimally obtrusive. Starting with
a fresh blacklist, the device may attempt to connect to a problematic AP
no more than 6 times in any ~45 minute period. Once an AP has reached a
blacklist count >= 6, the device may attempt to connect to it no more
than once every 30 minutes. The goal of these limits is to find an
ideal balance between minimizing connection attempts to bad APs while
still trying them out occasionally to see if the problems have stopped.
The only exception to the above limits is that the blacklist is still
completely cleared whenever there are no APs available in a scan. This
means that if all nearby APs have been blacklisted, all APs will be
completely exonerated regardless of their blacklist counts or how close
their blacklist entries are to expiring. When all nearby APs have been
blacklisted we know that every nearby AP is in some way problematic.
Once we know that every AP is causing problems, it doesn't really make
sense to sort them beyond that because the blacklist count and timeout
duration don't necessarily reflect the degree to which an AP is
problematic (i.e. they can be manipulated by external factors such as
the user physically moving around). Instead, its best to restart the
blacklist and let the normal roaming algorithm take over to maximize
our chance of getting the best possible connection quality.
As stated above, the time-based blacklisting algorithm is designed to
be minimally obtrusive to user experience, so occasionally restarting
the process is not too impactful on the user.
*problematic AP: rejects new clients, frequently de-auths clients, very
poor connection quality, etc.
Signed-off-by: Kevin Lund <kglund@google.com>
Signed-off-by: Brian Norris <briannorris@chromium.org>
2020-06-11 23:11:16 +02:00
|
|
|
return 0;
|
|
|
|
return e->count;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-28 02:34:43 +01:00
|
|
|
/**
|
2021-02-07 16:02:37 +01:00
|
|
|
* wpa_bssid_ignore_clear - Clear the ignore list of all entries
|
2008-02-28 02:34:43 +01:00
|
|
|
* @wpa_s: Pointer to wpa_supplicant data
|
|
|
|
*/
|
2021-02-07 16:02:37 +01:00
|
|
|
void wpa_bssid_ignore_clear(struct wpa_supplicant *wpa_s)
|
2008-02-28 02:34:43 +01:00
|
|
|
{
|
2021-02-07 16:02:37 +01:00
|
|
|
struct wpa_bssid_ignore *e, *prev;
|
2008-02-28 02:34:43 +01:00
|
|
|
|
2021-02-07 16:02:37 +01:00
|
|
|
e = wpa_s->bssid_ignore;
|
|
|
|
wpa_s->bssid_ignore = NULL;
|
2008-02-28 02:34:43 +01:00
|
|
|
while (e) {
|
|
|
|
prev = e;
|
|
|
|
e = e->next;
|
2023-11-21 00:51:45 +01:00
|
|
|
wpa_msg(wpa_s, MSG_INFO, "Removed BSSID " MACSTR
|
|
|
|
" from ignore list (clear)", MAC2STR(prev->bssid));
|
2008-02-28 02:34:43 +01:00
|
|
|
os_free(prev);
|
|
|
|
}
|
|
|
|
}
|
2020-06-11 23:11:17 +02:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
2021-02-07 16:02:37 +01:00
|
|
|
* wpa_bssid_ignore_update - Update the entries in the ignore list,
|
2020-06-11 23:11:17 +02:00
|
|
|
* deleting entries that have been expired for over an hour.
|
|
|
|
* @wpa_s: Pointer to wpa_supplicant data
|
|
|
|
*/
|
2021-02-07 16:02:37 +01:00
|
|
|
void wpa_bssid_ignore_update(struct wpa_supplicant *wpa_s)
|
2020-06-11 23:11:17 +02:00
|
|
|
{
|
2021-02-07 16:02:37 +01:00
|
|
|
struct wpa_bssid_ignore *e, *prev = NULL;
|
2020-06-11 23:11:17 +02:00
|
|
|
struct os_reltime now;
|
|
|
|
|
|
|
|
if (!wpa_s)
|
|
|
|
return;
|
|
|
|
|
2021-02-07 16:02:37 +01:00
|
|
|
e = wpa_s->bssid_ignore;
|
2020-06-11 23:11:17 +02:00
|
|
|
os_get_reltime(&now);
|
|
|
|
while (e) {
|
2021-02-07 16:02:37 +01:00
|
|
|
if (os_reltime_expired(&now, &e->start,
|
2020-06-11 23:11:17 +02:00
|
|
|
e->timeout_secs + 3600)) {
|
2021-02-07 16:02:37 +01:00
|
|
|
struct wpa_bssid_ignore *to_delete = e;
|
2020-06-11 23:11:17 +02:00
|
|
|
|
|
|
|
if (prev) {
|
|
|
|
prev->next = e->next;
|
|
|
|
e = prev->next;
|
|
|
|
} else {
|
2021-02-07 16:02:37 +01:00
|
|
|
wpa_s->bssid_ignore = e->next;
|
|
|
|
e = wpa_s->bssid_ignore;
|
2020-06-11 23:11:17 +02:00
|
|
|
}
|
2023-11-21 00:51:45 +01:00
|
|
|
wpa_msg(wpa_s, MSG_INFO, "Removed BSSID " MACSTR
|
|
|
|
" from ignore list (expired)",
|
|
|
|
MAC2STR(to_delete->bssid));
|
2020-06-11 23:11:17 +02:00
|
|
|
os_free(to_delete);
|
|
|
|
} else {
|
|
|
|
prev = e;
|
|
|
|
e = e->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|