From f0e30c841050d35c72cf2ac3cab02af03aca9e17 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Mon, 24 Feb 2014 15:22:35 +0200 Subject: [PATCH] Do not start another connect work while one is pending It was possible for the connect or sme-connect radio work to get re-scheduled while an earlier request was still pending, e.g., select_network is issued at the moment a scan radio work is in progress and the old scan results are recent enough for starting the connection. This could result in unexpected attempt to re-associate immediately after completing the first connection. Signed-off-by: Jouni Malinen --- wpa_supplicant/sme.c | 5 +++++ wpa_supplicant/wpa_supplicant.c | 19 +++++++++++++++++++ wpa_supplicant/wpa_supplicant_i.h | 1 + 3 files changed, 25 insertions(+) diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c index e712ac439..5ce9da710 100644 --- a/wpa_supplicant/sme.c +++ b/wpa_supplicant/sme.c @@ -475,6 +475,11 @@ void sme_authenticate(struct wpa_supplicant *wpa_s, return; } + if (radio_work_pending(wpa_s, "sme-connect")) { + wpa_dbg(wpa_s, MSG_DEBUG, "SME: Reject sme_authenticate() call since pending work exist"); + return; + } + cwork = os_zalloc(sizeof(*cwork)); if (cwork == NULL) return; diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index e942b6225..60e7a66a7 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -1366,6 +1366,11 @@ void wpa_supplicant_associate(struct wpa_supplicant *wpa_s, return; } + if (radio_work_pending(wpa_s, "connect")) { + wpa_dbg(wpa_s, MSG_DEBUG, "Reject wpa_supplicant_associate() call since pending work exist"); + return; + } + cwork = os_zalloc(sizeof(*cwork)); if (cwork == NULL) return; @@ -3237,6 +3242,20 @@ 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 *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 0; +} + + static int wpas_init_driver(struct wpa_supplicant *wpa_s, struct wpa_interface *iface) { diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index bcdb4d036..3dcc90007 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -308,6 +308,7 @@ 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_connect_work { unsigned int sme:1;