[PATCH] supplicant: Add timers for SME associate & authenticate.

Ben Greear greearb at candelatech.com
Thu Jan 20 22:52:58 EST 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