[PATCH] supplicant: Add timers for SME associate & authenticate.
Ben Greear
greearb
Thu Jan 20 19:52:58 PST 2011
I was seeing stations stuck in ASSOCIATING state forever
without this fix, when running lots of virtual stations
on ath9k.
Signed-off-by: Ben Greear <greearb at candelatech.com>
---
:100644 100644 c72bebe... a9a3f95... M wpa_supplicant/events.c
:100644 100644 e6b24d9... 2cc6f72... M wpa_supplicant/sme.c
:100644 100644 b5f150d... 686c5a4... M wpa_supplicant/sme.h
:100644 100644 f118922... 012cd26... M wpa_supplicant/wpa_supplicant.c
wpa_supplicant/events.c | 19 +++++++++++++++--
wpa_supplicant/sme.c | 40 +++++++++++++++++++++++++++++++++++++-
wpa_supplicant/sme.h | 11 ++++++++++
wpa_supplicant/wpa_supplicant.c | 7 ++++++
4 files changed, 72 insertions(+), 5 deletions(-)
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index c72bebe..a9a3f95 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -693,13 +693,19 @@ void wpa_supplicant_connect(struct wpa_supplicant *wpa_s,
*/
if (wpa_s->reassociate ||
(os_memcmp(selected->bssid, wpa_s->bssid, ETH_ALEN) != 0 &&
- (wpa_s->wpa_state != WPA_ASSOCIATING ||
- os_memcmp(selected->bssid, wpa_s->pending_bssid, ETH_ALEN) !=
- 0))) {
+ ((!((wpa_s->wpa_state == WPA_ASSOCIATING) ||
+ (wpa_s->wpa_state == WPA_AUTHENTICATING))) ||
+ os_memcmp(selected->bssid, wpa_s->pending_bssid,
+ ETH_ALEN) != 0))) {
if (wpa_supplicant_scard_init(wpa_s, ssid)) {
wpa_supplicant_req_new_scan(wpa_s, 10, 0);
return;
}
+ wpa_msg(wpa_s, MSG_DEBUG, "wpa_connect calling associate, reassociate: %i selected: "
+ MACSTR " bssid: " MACSTR " pending: " MACSTR " wpa_state: %i",
+ wpa_s->reassociate, MAC2STR(selected->bssid), MAC2STR(wpa_s->bssid),
+ MAC2STR(wpa_s->pending_bssid),
+ wpa_s->wpa_state);
wpa_supplicant_associate(wpa_s, selected, ssid);
} else {
wpa_msg(wpa_s, MSG_DEBUG, "Already associated with the selected "
@@ -1390,6 +1396,13 @@ static void wpa_supplicant_event_disassoc(struct wpa_supplicant *wpa_s,
"proceed after disconnection event");
wpa_supplicant_set_state(wpa_s, WPA_AUTHENTICATING);
os_memcpy(wpa_s->pending_bssid, prev_pending_bssid, ETH_ALEN);
+
+
+ /* Re-arm authentication timer in case auth fails for
+ * whatever reason.
+ */
+ eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL);
+ eloop_register_timeout(2, 0, sme_auth_timer, wpa_s, NULL);
}
#endif /* CONFIG_SME */
}
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index e6b24d9..2cc6f72 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -250,7 +250,8 @@ void sme_authenticate(struct wpa_supplicant *wpa_s,
return;
}
- /* TODO: add timeout on authentication */
+ /* 2 second timer seem about right? */
+ eloop_register_timeout(2, 0, sme_auth_timer, wpa_s, NULL);
/*
* Association will be started based on the authentication event from
@@ -289,6 +290,8 @@ void sme_event_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data)
wpa_hexdump(MSG_MSGDUMP, "SME: Authentication response IEs",
data->auth.ies, data->auth.ies_len);
+ eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL);
+
if (data->auth.status_code != WLAN_STATUS_SUCCESS) {
wpa_msg(wpa_s, MSG_DEBUG, "SME: Authentication failed (status "
"code %d)", data->auth.status_code);
@@ -404,7 +407,8 @@ void sme_associate(struct wpa_supplicant *wpa_s, enum wpas_mode mode,
return;
}
- /* TODO: add timeout on association */
+ /* 2 second timer seem about right? */
+ eloop_register_timeout(2, 0, sme_assoc_timer, wpa_s, NULL);
}
@@ -443,6 +447,8 @@ void sme_event_assoc_reject(struct wpa_supplicant *wpa_s,
bssid_changed = !is_zero_ether_addr(wpa_s->bssid);
+ eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL);
+
/*
* For now, unconditionally terminate the previous authentication. In
* theory, this should not be needed, but mac80211 gets quite confused
@@ -502,6 +508,36 @@ void sme_event_disassoc(struct wpa_supplicant *wpa_s,
}
}
+void sme_auth_timer(void *eloop_ctx, void *timeout_ctx)
+{
+ struct wpa_supplicant *wpa_s = eloop_ctx;
+ if (wpa_s->wpa_state == WPA_AUTHENTICATING) {
+ wpa_msg(wpa_s, MSG_DEBUG, "SME: Authentication timout.");
+ wpa_drv_deauthenticate(wpa_s, wpa_s->pending_bssid,
+ WLAN_REASON_DEAUTH_LEAVING);
+ wpa_s->sme.prev_bssid_set = 0;
+ wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
+ wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
+ os_memset(wpa_s->bssid, 0, ETH_ALEN);
+ os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
+ }
+}
+
+void sme_assoc_timer(void *eloop_ctx, void *timeout_ctx)
+{
+ struct wpa_supplicant *wpa_s = eloop_ctx;
+ if (wpa_s->wpa_state == WPA_ASSOCIATING) {
+ wpa_msg(wpa_s, MSG_DEBUG, "SME: Association timout.");
+ wpa_drv_deauthenticate(wpa_s, wpa_s->pending_bssid,
+ WLAN_REASON_DEAUTH_LEAVING);
+ wpa_s->sme.prev_bssid_set = 0;
+ wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
+ wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);
+ os_memset(wpa_s->bssid, 0, ETH_ALEN);
+ os_memset(wpa_s->pending_bssid, 0, ETH_ALEN);
+ }
+}
+
#ifdef CONFIG_IEEE80211W
diff --git a/wpa_supplicant/sme.h b/wpa_supplicant/sme.h
index b5f150d..686c5a4 100644
--- a/wpa_supplicant/sme.h
+++ b/wpa_supplicant/sme.h
@@ -38,6 +38,9 @@ void sme_stop_sa_query(struct wpa_supplicant *wpa_s);
void sme_sa_query_rx(struct wpa_supplicant *wpa_s, const u8 *sa,
const u8 *data, size_t len);
+void sme_auth_timer(void *eloop_ctx, void *timeout_ctx);
+void sme_assoc_timer(void *eloop_ctx, void *timeout_ctx);
+
#else /* CONFIG_SME */
static inline void sme_authenticate(struct wpa_supplicant *wpa_s,
@@ -84,6 +87,14 @@ static inline void sme_event_unprot_disconnect(struct wpa_supplicant *wpa_s,
{
}
+static inline void sme_auth_timer(void *eloop_ctx, void *timeout_ctx)
+{
+}
+
+static inline void sme_assoc_timer(void *eloop_ctx, void *timeout_ctx)
+{
+}
+
#endif /* CONFIG_SME */
#endif /* SME_H */
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index f118922..012cd26 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -570,6 +570,13 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
wpa_drv_set_supp_port(wpa_s, 0);
#endif /* IEEE8021X_EAPOL */
}
+
+ /* Make sure timers are cleaned up appropriately. */
+ if (state != WPA_ASSOCIATING)
+ eloop_cancel_timeout(sme_assoc_timer, wpa_s, NULL);
+ if (state != WPA_AUTHENTICATING)
+ eloop_cancel_timeout(sme_auth_timer, wpa_s, NULL);
+
wpa_s->wpa_state = state;
if (wpa_s->wpa_state != old_state)
--
1.7.2.3
More information about the Hostap
mailing list