From: Avraham Stern Date: Tue, 5 Aug 2025 15:13:15 +0000 (+0200) Subject: Try the next AP from scan results if connection attempt fails X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bbcc1adbc0de133a774e97a36823f21ef0245487;p=thirdparty%2Fhostap.git Try the next AP from scan results if connection attempt fails If connection to a selected AP fails and there are other candidates in the BSS table and scan results are not too old, try to fast associate to the next available candidate without triggering another full scan. Signed-off-by: Avraham Stern Reviewed-by: Peer, Ilan Reviewed-by: Otcheretianski, Andrei Signed-off-by: Benjamin Berg --- diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 42a52899d..9d5024c43 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -1770,7 +1770,8 @@ wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s, struct wpa_bss * wpa_supplicant_pick_network(struct wpa_supplicant *wpa_s, - struct wpa_ssid **selected_ssid) + struct wpa_ssid **selected_ssid, + bool clear_ignorelist) { struct wpa_bss *selected = NULL; size_t prio; @@ -1809,7 +1810,7 @@ struct wpa_bss * wpa_supplicant_pick_network(struct wpa_supplicant *wpa_s, if (!selected && (wpa_s->bssid_ignore || wnm_active_bss_trans_mgmt(wpa_s)) && - !wpa_s->countermeasures) { + !wpa_s->countermeasures && clear_ignorelist) { wpa_dbg(wpa_s, MSG_DEBUG, "No APs found - clear BSSID ignore list and try again"); wnm_btm_reset(wpa_s); @@ -2725,7 +2726,7 @@ static int wpas_select_network_from_last_scan(struct wpa_supplicant *wpa_s, os_free(wpa_s->owe_trans_scan_freq); wpa_s->owe_trans_scan_freq = NULL; #endif /* CONFIG_OWE */ - selected = wpa_supplicant_pick_network(wpa_s, &ssid); + selected = wpa_supplicant_pick_network(wpa_s, &ssid, new_scan); #ifdef CONFIG_MESH if (wpa_s->ifmsh) { diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c index faefb6699..f77880409 100644 --- a/wpa_supplicant/interworking.c +++ b/wpa_supplicant/interworking.c @@ -899,7 +899,7 @@ static int already_connected(struct wpa_supplicant *wpa_s, return 0; sel_ssid = NULL; - selected = wpa_supplicant_pick_network(wpa_s, &sel_ssid); + selected = wpa_supplicant_pick_network(wpa_s, &sel_ssid, true); if (selected && sel_ssid && sel_ssid->priority > ssid->priority) return 0; /* higher priority network in scan results */ diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index d45002fd9..bbd3e1a05 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -8783,46 +8783,11 @@ void add_freq(int *freqs, int *num_freqs, int freq) } -static int * get_bss_freqs_in_ess(struct wpa_supplicant *wpa_s) -{ - struct wpa_bss *bss, *cbss; - const int max_freqs = 10; - int *freqs; - int num_freqs = 0; - - freqs = os_calloc(max_freqs + 1, sizeof(int)); - if (freqs == NULL) - return NULL; - - cbss = wpa_s->current_bss; - - dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { - if (bss == cbss) - continue; - if (bss->ssid_len == cbss->ssid_len && - os_memcmp(bss->ssid, cbss->ssid, bss->ssid_len) == 0 && - !wpa_bssid_ignore_is_listed(wpa_s, bss->bssid)) { - add_freq(freqs, &num_freqs, bss->freq); - if (num_freqs == max_freqs) - break; - } - } - - if (num_freqs == 0) { - os_free(freqs); - freqs = NULL; - } - - return freqs; -} - - void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid, const u8 **link_bssids) { int timeout; int count; - int *freqs = NULL; wpas_connect_work_done(wpa_s); @@ -8859,27 +8824,15 @@ void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid, * attempt if there could be other APs that could accept association. */ count = wpa_bssid_ignore_add(wpa_s, bssid); - if (count == 1 && wpa_s->current_bss) { - /* - * This BSS was not in the ignore list before. If there is - * another BSS available for the same ESS, we should try that - * next. Otherwise, we may as well try this one once more - * before allowing other, likely worse, ESSes to be considered. - */ - freqs = get_bss_freqs_in_ess(wpa_s); - if (freqs) { - wpa_dbg(wpa_s, MSG_DEBUG, "Another BSS in this ESS " - "has been seen; try it next"); - wpa_bssid_ignore_add(wpa_s, bssid); - /* - * On the next scan, go through only the known channels - * used in this ESS based on previous scans to speed up - * common load balancing use case. - */ - os_free(wpa_s->next_scan_freqs); - wpa_s->next_scan_freqs = freqs; - } - } + + /* + * This BSS was not in the ignore list before. If there is + * another BSS available for the same ESS, we should try that + * next. Otherwise, we may as well try this one once more + * before allowing other, likely worse, ESSes to be considered. + */ + if (count == 1 && wpa_supplicant_fast_associate(wpa_s) == 1) + return; wpa_s->consecutive_conn_failures++; @@ -8915,11 +8868,6 @@ void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid, "Consecutive connection failures: %d --> request scan in %d ms", wpa_s->consecutive_conn_failures, timeout); - /* - * TODO: if more than one possible AP is available in scan results, - * could try the other ones before requesting a new scan. - */ - /* speed up the connection attempt with normal scan */ wpa_s->normal_scans = 0; wpa_supplicant_req_scan(wpa_s, timeout / 1000, diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index e7675a4ab..cf27add72 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -1875,7 +1875,8 @@ void wnm_bss_keep_alive_deinit(struct wpa_supplicant *wpa_s); int wpa_supplicant_fast_associate(struct wpa_supplicant *wpa_s); int wpa_wps_supplicant_fast_associate(struct wpa_supplicant *wpa_s); struct wpa_bss * wpa_supplicant_pick_network(struct wpa_supplicant *wpa_s, - struct wpa_ssid **selected_ssid); + struct wpa_ssid **selected_ssid, + bool clear_ignorelist); int wpas_temp_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid); void wpa_supplicant_update_channel_list(struct wpa_supplicant *wpa_s, struct channel_list_changed *info); diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c index 405c5d605..25a5598ce 100644 --- a/wpa_supplicant/wps_supplicant.c +++ b/wpa_supplicant/wps_supplicant.c @@ -148,7 +148,7 @@ int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s) wpa_printf(MSG_DEBUG, "WPS: Checking whether fast association " "without a new scan can be used"); - bss = wpa_supplicant_pick_network(wpa_s, &ssid); + bss = wpa_supplicant_pick_network(wpa_s, &ssid, true); if (bss) { struct wpabuf *wps; struct wps_parse_attr attr;