diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c index 9b9289fc8..055aef071 100644 --- a/wpa_supplicant/bss.c +++ b/wpa_supplicant/bss.c @@ -174,6 +174,31 @@ static void wpa_bss_anqp_free(struct wpa_bss_anqp *anqp) } +static void wpa_bss_update_pending_connect(struct wpa_supplicant *wpa_s, + struct wpa_bss *old_bss, + struct wpa_bss *new_bss) +{ + struct wpa_radio_work *work; + struct wpa_connect_work *cwork; + + work = radio_work_pending(wpa_s, "sme-connect"); + if (!work) + work = radio_work_pending(wpa_s, "connect"); + if (!work) + return; + + cwork = work->ctx; + if (cwork->bss != old_bss) + return; + + wpa_printf(MSG_DEBUG, + "Update BSS pointer for the pending connect radio work"); + cwork->bss = new_bss; + if (!new_bss) + cwork->bss_removed = 1; +} + + static void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, const char *reason) { @@ -190,6 +215,7 @@ static void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, } } } + wpa_bss_update_pending_connect(wpa_s, bss, NULL); dl_list_del(&bss->list); dl_list_del(&bss->list_id); wpa_s->num_bss--; @@ -543,6 +569,7 @@ wpa_bss_update(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, } if (wpa_s->current_bss == bss) wpa_s->current_bss = nbss; + wpa_bss_update_pending_connect(wpa_s, bss, nbss); bss = nbss; os_memcpy(bss + 1, res + 1, res->ie_len + res->beacon_ie_len); diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index 9841c10eb..7269eb059 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -497,7 +497,8 @@ static void sme_auth_start_cb(struct wpa_radio_work *work, int deinit) wpa_s->connect_work = work; - if (!wpas_valid_bss_ssid(wpa_s, cwork->bss, cwork->ssid)) { + if (cwork->bss_removed || + !wpas_valid_bss_ssid(wpa_s, cwork->bss, cwork->ssid)) { wpa_dbg(wpa_s, MSG_DEBUG, "SME: BSS/SSID entry for authentication not valid anymore - drop connection attempt"); wpas_connect_work_done(wpa_s); return; diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 6e08256f0..5a4d8dc60 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -1602,7 +1602,7 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit) wpa_s->connect_work = work; - if (!wpas_valid_bss_ssid(wpa_s, bss, ssid)) { + if (cwork->bss_removed || !wpas_valid_bss_ssid(wpa_s, bss, ssid)) { wpa_dbg(wpa_s, MSG_DEBUG, "BSS/SSID entry for association not valid anymore - drop connection attempt"); wpas_connect_work_done(wpa_s); return; @@ -3608,17 +3608,18 @@ void radio_work_done(struct wpa_radio_work *work) } -int radio_work_pending(struct wpa_supplicant *wpa_s, const char *type) +struct wpa_radio_work * +radio_work_pending(struct wpa_supplicant *wpa_s, const char *type) { struct wpa_radio_work *work; struct wpa_radio *radio = wpa_s->radio; dl_list_for_each(work, &radio->work, struct wpa_radio_work, list) { if (work->wpa_s == wpa_s && os_strcmp(work->type, type) == 0) - return 1; + return work; } - return 0; + return NULL; } diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index e122b7403..cadf7246e 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -321,10 +321,12 @@ void radio_work_done(struct wpa_radio_work *work); void radio_remove_works(struct wpa_supplicant *wpa_s, const char *type, int remove_all); void radio_work_check_next(struct wpa_supplicant *wpa_s); -int radio_work_pending(struct wpa_supplicant *wpa_s, const char *type); +struct wpa_radio_work * +radio_work_pending(struct wpa_supplicant *wpa_s, const char *type); struct wpa_connect_work { unsigned int sme:1; + unsigned int bss_removed:1; struct wpa_bss *bss; struct wpa_ssid *ssid; };