Maintain maximum blacklist count over list clear operations
wpas_connection_failed() uses the blacklist count to figure out a suitable time to wait for the next scan. This mechanism did not work properly in cases where the temporary blacklist gets cleared due to no other BSSes being available. Address this by maintaining an additional count of blacklisting values over wpa_blacklist_clear() calls. In addition, add one more step in the count to timeout mapping to go to 10 second interval if more than four failures are seen. Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
4115303bbe
commit
f1a5263389
5 changed files with 35 additions and 1 deletions
|
@ -123,14 +123,19 @@ int wpa_blacklist_del(struct wpa_supplicant *wpa_s, const u8 *bssid)
|
||||||
void wpa_blacklist_clear(struct wpa_supplicant *wpa_s)
|
void wpa_blacklist_clear(struct wpa_supplicant *wpa_s)
|
||||||
{
|
{
|
||||||
struct wpa_blacklist *e, *prev;
|
struct wpa_blacklist *e, *prev;
|
||||||
|
int max_count = 0;
|
||||||
|
|
||||||
e = wpa_s->blacklist;
|
e = wpa_s->blacklist;
|
||||||
wpa_s->blacklist = NULL;
|
wpa_s->blacklist = NULL;
|
||||||
while (e) {
|
while (e) {
|
||||||
|
if (e->count > max_count)
|
||||||
|
max_count = e->count;
|
||||||
prev = e;
|
prev = e;
|
||||||
e = e->next;
|
e = e->next;
|
||||||
wpa_printf(MSG_DEBUG, "Removed BSSID " MACSTR " from "
|
wpa_printf(MSG_DEBUG, "Removed BSSID " MACSTR " from "
|
||||||
"blacklist (clear)", MAC2STR(prev->bssid));
|
"blacklist (clear)", MAC2STR(prev->bssid));
|
||||||
os_free(prev);
|
os_free(prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wpa_s->extra_blacklist_count += max_count;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4786,6 +4786,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
|
||||||
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
|
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
|
||||||
reply_len = -1;
|
reply_len = -1;
|
||||||
else {
|
else {
|
||||||
|
wpa_s->extra_blacklist_count = 0;
|
||||||
wpa_s->disconnected = 0;
|
wpa_s->disconnected = 0;
|
||||||
wpa_s->reassociate = 1;
|
wpa_s->reassociate = 1;
|
||||||
wpa_supplicant_req_scan(wpa_s, 0, 0);
|
wpa_supplicant_req_scan(wpa_s, 0, 0);
|
||||||
|
@ -4796,6 +4797,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
|
||||||
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
|
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED)
|
||||||
reply_len = -1;
|
reply_len = -1;
|
||||||
else if (wpa_s->disconnected) {
|
else if (wpa_s->disconnected) {
|
||||||
|
wpa_s->extra_blacklist_count = 0;
|
||||||
wpa_s->disconnected = 0;
|
wpa_s->disconnected = 0;
|
||||||
wpa_s->reassociate = 1;
|
wpa_s->reassociate = 1;
|
||||||
wpa_supplicant_req_scan(wpa_s, 0, 0);
|
wpa_supplicant_req_scan(wpa_s, 0, 0);
|
||||||
|
|
|
@ -1455,6 +1455,7 @@ DBusMessage * wpas_dbus_handler_reassociate(DBusMessage *message,
|
||||||
struct wpa_supplicant *wpa_s)
|
struct wpa_supplicant *wpa_s)
|
||||||
{
|
{
|
||||||
if (wpa_s->current_ssid != NULL) {
|
if (wpa_s->current_ssid != NULL) {
|
||||||
|
wpa_s->extra_blacklist_count = 0;
|
||||||
wpa_s->normal_scans = 0;
|
wpa_s->normal_scans = 0;
|
||||||
wpa_supplicant_reinit_autoscan(wpa_s);
|
wpa_supplicant_reinit_autoscan(wpa_s);
|
||||||
wpa_s->disconnected = 0;
|
wpa_s->disconnected = 0;
|
||||||
|
|
|
@ -665,6 +665,7 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
|
||||||
ssid && ssid->id_str ? ssid->id_str : "");
|
ssid && ssid->id_str ? ssid->id_str : "");
|
||||||
#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
|
#endif /* CONFIG_CTRL_IFACE || !CONFIG_NO_STDOUT_DEBUG */
|
||||||
wpas_clear_temp_disabled(wpa_s, ssid, 1);
|
wpas_clear_temp_disabled(wpa_s, ssid, 1);
|
||||||
|
wpa_s->extra_blacklist_count = 0;
|
||||||
wpa_s->new_connection = 0;
|
wpa_s->new_connection = 0;
|
||||||
wpa_s->reassociated_connection = 1;
|
wpa_s->reassociated_connection = 1;
|
||||||
wpa_drv_set_operstate(wpa_s, 1);
|
wpa_drv_set_operstate(wpa_s, 1);
|
||||||
|
@ -3446,6 +3447,12 @@ void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add previous failure count in case the temporary blacklist was
|
||||||
|
* cleared due to no other BSSes being available.
|
||||||
|
*/
|
||||||
|
count += wpa_s->extra_blacklist_count;
|
||||||
|
|
||||||
switch (count) {
|
switch (count) {
|
||||||
case 1:
|
case 1:
|
||||||
timeout = 100;
|
timeout = 100;
|
||||||
|
@ -3456,10 +3463,17 @@ void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
|
||||||
case 3:
|
case 3:
|
||||||
timeout = 1000;
|
timeout = 1000;
|
||||||
break;
|
break;
|
||||||
default:
|
case 4:
|
||||||
timeout = 5000;
|
timeout = 5000;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
timeout = 10000;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wpa_dbg(wpa_s, MSG_DEBUG, "Blacklist count %d --> request scan in %d "
|
||||||
|
"ms", count, timeout);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: if more than one possible AP is available in scan results,
|
* TODO: if more than one possible AP is available in scan results,
|
||||||
* could try the other ones before requesting a new scan.
|
* could try the other ones before requesting a new scan.
|
||||||
|
|
|
@ -397,6 +397,18 @@ struct wpa_supplicant {
|
||||||
|
|
||||||
struct wpa_blacklist *blacklist;
|
struct wpa_blacklist *blacklist;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* extra_blacklist_count - Sum of blacklist counts after last connection
|
||||||
|
*
|
||||||
|
* This variable is used to maintain a count of temporary blacklisting
|
||||||
|
* failures (maximum number for any BSS) over blacklist clear
|
||||||
|
* operations. This is needed for figuring out whether there has been
|
||||||
|
* failures prior to the last blacklist clear operation which happens
|
||||||
|
* whenever no other not-blacklisted BSS candidates are available. This
|
||||||
|
* gets cleared whenever a connection has been established successfully.
|
||||||
|
*/
|
||||||
|
int extra_blacklist_count;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* scan_req - Type of the scan request
|
* scan_req - Type of the scan request
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue