[PATCH] Speed up connection time during ASSOC retry

Jouni Malinen j
Sat Jun 9 04:47:51 PDT 2012


On Mon, May 21, 2012 at 06:24:31AM +0000, Jithu Jance wrote:
> In current implementation, authentication timer continues to run even after the
> driver has reported ASSOC_REJECT. Then the association is retried on authentication
> timeout which is 10secs.

This is actually not the case for SME-in-wpa_supplicant, i.e., this
patch did not change anything for my mac80211_hwsim test.. As such, this
change should probably be conditional on WPA_DRIVER_FLAGS_SME not being
set..

> The below patch cancels the authentication timeout on ASSOC_REJECT and initiates an
> scan for association. Kindly see whether the patch is fine.

The patch was whitespace damaged (tabs converted to spaces).

> diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
> @@ -2238,6 +2238,25 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
>                 if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
>                         sme_event_assoc_reject(wpa_s, data);
> +
> +               /* If assoc reject is reported by the driver, then avoid

sme_event_assoc_reject() handles this with similar mechanism to initiate
new attempt immediately.

> +                * waiting for  the authentication timeout. Cancel the
> +                * authentication timeout and retry the assoc.
> +                */
> +               if(wpa_s->assoc_retries++ < 3) {

This should probably not be run with WPA_DRIVER_FLAGS_SME..

> +                       wpa_printf(MSG_ERROR, "Retrying assoc "
> +                       "Iteration:%d", wpa_s->assoc_retries);
> +                       wpa_supplicant_cancel_auth_timeout(wpa_s);
> +
> +                       /* Clear the states */
> +                       wpa_sm_notify_disassoc(wpa_s->wpa);
> +                       wpa_supplicant_disassociate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);

wpa_supplicant_deauthenticate() would sound more appropriate in this
case since association was rejected.

> +                       wpa_s->reassociate = 1;
> +                       wpa_supplicant_req_scan(wpa_s, 1, 0);

This could use wpas_connection_failed() to remain consistent with other
similar connection failure cases..


I have not tested this, but something like this could handle this a bit
more cleanly. Could you please check whether this works in the case you
are seeing?


diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index d09be6c..0b4feb8 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -2320,6 +2320,27 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
 				data->assoc_reject.status_code);
 		if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
 			sme_event_assoc_reject(wpa_s, data);
+		else if (wpa_s->assoc_retries++ < 3) {
+			/*
+			 * If association reject is reported by the driver,
+			 * avoid waiting for the authentication timeout. Cancel
+			 * the authentication timeout and retry the
+			 * association.
+			 */
+			wpa_printf(MSG_DEBUG, "Retrying association "
+				   "(iteration %d)", wpa_s->assoc_retries);
+
+			/* Clear the state */
+			wpa_sm_notify_disassoc(wpa_s->wpa);
+			wpa_supplicant_deauthenticate(
+				wpa_s, WLAN_REASON_DEAUTH_LEAVING);
+
+			wpa_s->reassociate = 1;
+			wpas_connection_failed(wpa_s,
+					       data->assoc_reject.bssid);
+		} else {
+			wpa_s->assoc_retries = 0;
+		}
 		break;
 	case EVENT_AUTH_TIMED_OUT:
 		if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME)
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 3cb954d..fdfcc5d 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -587,6 +587,9 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
 		wpa_supplicant_state_txt(wpa_s->wpa_state),
 		wpa_supplicant_state_txt(state));
 
+	if (state == WPA_ASSOCIATED || state <= WPA_INACTIVE)
+		wpa_s->assoc_retries = 0;
+
 	if (state != WPA_SCANNING)
 		wpa_supplicant_notify_scanning(wpa_s, 0);
 
@@ -3199,8 +3202,11 @@ void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid)
 	 * either not available or has already been tried, so that we can start
 	 * increasing the delay here to avoid constant scanning.
 	 */
-	count = wpa_blacklist_add(wpa_s, bssid);
-	if (count == 1 && wpa_s->current_bss) {
+	if (bssid)
+		count = wpa_blacklist_add(wpa_s, bssid);
+	else
+		count = 3;
+	if (count == 1 && wpa_s->current_bss && bssid) {
 		/*
 		 * This BSS was not in the blacklist before. If there is
 		 * another BSS available for the same ESS, we should try that
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 84e8fa4..50eef00 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -286,6 +286,7 @@ struct wpa_supplicant {
 	struct wpa_bss *current_bss;
 	int ap_ies_from_associnfo;
 	unsigned int assoc_freq;
+	unsigned int assoc_retries;
 
 	/* Selected configuration (based on Beacon/ProbeResp WPA IE) */
 	int pairwise_cipher;
 
-- 
Jouni Malinen                                            PGP id EFC895FA



More information about the Hostap mailing list