Patchwork Speed up connection time during ASSOC retry

login
register
mail settings
Submitter Jouni Malinen
Date June 9, 2012, 11:47 a.m.
Message ID <20120609114751.GB9290@w1.fi>
Download mbox | patch
Permalink /patch/163909/
State Superseded
Headers show

Comments

Jouni Malinen - June 9, 2012, 11:47 a.m.
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?
Jithu Jance - June 14, 2012, 10:45 a.m.
Hi Jouni,

> This should probably not be run with WPA_DRIVER_FLAGS_SME..

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

Thanks for pointing these out.

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

I found this while testing P2P connection scenario and I didn't want to
backlist the ssid which would
further delay the connection process. Is it fine to same approach for P2P
and STA in this case? or should we
use  wpas_connection_failed() for STA alone? I also added code to disable
the network and remove the p2p_group,
if the retries reached the threshold. This code so far is working for me.
But not sure whether I have
covered all the cases properly. Request your opinion.

I shall generate a patch, If you feel this is okay. Please find the updated
code below.

void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
  union wpa_event_data *data)

            ...
            ...

case EVENT_ASSOC_REJECT:
if (data->assoc_reject.bssid)
 wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_ASSOC_REJECT
"bssid=" MACSTR " status_code=%u",
 MAC2STR(data->assoc_reject.bssid),
data->assoc_reject.status_code);
 else
wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_ASSOC_REJECT
"status_code=%u",
 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->current_ssid) {
 wpa_printf(MSG_ERROR, "current_ssid == NULL");
break;
}
 /* If assoc reject is reported by the driver, then avoid
 * waiting for  the authentication timeout. Cancel the
 * authentication timeout and retry the assoc.
 */
if(wpa_s->current_ssid->assoc_retry++ < 5) {
 wpa_printf(MSG_ERROR, "Retrying assoc: %d ",
wpa_s->current_ssid->assoc_retry);

wpa_supplicant_cancel_auth_timeout(wpa_s);

/* Clear the states */
 wpa_sm_notify_disassoc(wpa_s->wpa);
wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING);

wpa_s->reassociate = 1;
wpa_supplicant_req_scan(wpa_s, 1, 0);
 } else {
/* If we ASSOC_REJECT's hits threshold, disable the
 * network
  */
wpa_printf(MSG_ERROR, "Assoc retry threshold reached. "
 "Disabling the network");
wpa_supplicant_disable_network(wpa_s, wpa_s->current_ssid);
#ifdef CONFIG_P2P
if(wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE)
wpas_p2p_group_remove(wpa_s, wpa_s->ifname);
#endif
}
}
break;

*   ...*
*   ...*
*}*
*
*
*
*
*- Jithu Jance*



On Sat, Jun 9, 2012 at 5:17 PM, Jouni Malinen <j@w1.fi> wrote:

> 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
> _______________________________________________
> HostAP mailing list
> HostAP@lists.shmoo.com
> http://lists.shmoo.com/mailman/listinfo/hostap
>

Patch

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;