diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 603d4dabb..9b3755113 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -2253,7 +2253,8 @@ int wpa_supplicant_fast_associate(struct wpa_supplicant *wpa_s) return -1; os_get_reltime(&now); - if (os_reltime_expired(&now, &wpa_s->last_scan, 5)) { + if (os_reltime_expired(&now, &wpa_s->last_scan, + SCAN_RES_VALID_FOR_CONNECT)) { wpa_printf(MSG_DEBUG, "Fast associate: Old scan results"); return -1; } @@ -4321,6 +4322,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, { struct wpa_supplicant *wpa_s = ctx; int resched; + struct os_reltime age, clear_at; #ifndef CONFIG_NO_STDOUT_DEBUG int level = MSG_DEBUG; #endif /* CONFIG_NO_STDOUT_DEBUG */ @@ -4859,6 +4861,8 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, case EVENT_INTERFACE_ENABLED: wpa_dbg(wpa_s, MSG_DEBUG, "Interface was enabled"); if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) { + eloop_cancel_timeout(wpas_clear_disabled_interface, + wpa_s, NULL); wpa_supplicant_update_mac_addr(wpa_s); wpa_supplicant_set_default_scan_ies(wpa_s); if (wpa_s->p2p_mgmt) { @@ -4927,7 +4931,20 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, wpa_s, WLAN_REASON_DEAUTH_LEAVING, 1); } wpa_supplicant_mark_disassoc(wpa_s); - wpa_bss_flush(wpa_s); + os_reltime_age(&wpa_s->last_scan, &age); + if (age.sec >= SCAN_RES_VALID_FOR_CONNECT) { + clear_at.sec = SCAN_RES_VALID_FOR_CONNECT; + clear_at.usec = 0; + } else { + struct os_reltime tmp; + + tmp.sec = SCAN_RES_VALID_FOR_CONNECT; + tmp.usec = 0; + os_reltime_sub(&tmp, &age, &clear_at); + } + eloop_register_timeout(clear_at.sec, clear_at.usec, + wpas_clear_disabled_interface, + wpa_s, NULL); radio_remove_works(wpa_s, NULL, 0); wpa_supplicant_set_state(wpa_s, WPA_INTERFACE_DISABLED); diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index ce4ce0bfb..08e70e57a 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -476,6 +476,17 @@ void wpas_flush_fils_hlp_req(struct wpa_supplicant *wpa_s) } +void wpas_clear_disabled_interface(void *eloop_ctx, void *timeout_ctx) +{ + struct wpa_supplicant *wpa_s = eloop_ctx; + + if (wpa_s->wpa_state != WPA_INTERFACE_DISABLED) + return; + wpa_dbg(wpa_s, MSG_DEBUG, "Clear cached state on disabled interface"); + wpa_bss_flush(wpa_s); +} + + static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s) { int i; @@ -551,6 +562,7 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s) #endif /* CONFIG_DELAYED_MIC_ERROR_REPORT */ eloop_cancel_timeout(wpas_network_reenabled, wpa_s, NULL); + eloop_cancel_timeout(wpas_clear_disabled_interface, wpa_s, NULL); wpas_wps_deinit(wpa_s); diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 56df23732..422f2cb24 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -47,6 +47,9 @@ struct ctrl_iface_global_priv; struct wpas_dbus_priv; struct wpas_binder_priv; +/* How many seconds to consider old scan results valid for association. */ +#define SCAN_RES_VALID_FOR_CONNECT 5 + /** * struct wpa_interface - Parameters for wpa_supplicant_add_iface() */ @@ -1399,6 +1402,7 @@ int wpas_beacon_rep_scan_process(struct wpa_supplicant *wpa_s, struct scan_info *info); void wpas_clear_beacon_rep_data(struct wpa_supplicant *wpa_s); void wpas_flush_fils_hlp_req(struct wpa_supplicant *wpa_s); +void wpas_clear_disabled_interface(void *eloop_ctx, void *timeout_ctx); /* MBO functions */