[RFC] wpa_supplicant: add fast reconnect support

Sam Leffler sleffler
Mon Jan 30 14:19:25 PST 2012

On Wed, Jan 4, 2012 at 7:53 AM, Dan Williams <dcbw at redhat.com> wrote:
> On Tue, 2012-01-03 at 09:57 -0800, Sam Leffler wrote:
>> On Sun, Jan 1, 2012 at 7:54 AM, Jouni Malinen <j at w1.fi> wrote:
>> > On Wed, Dec 21, 2011 at 03:53:21PM -0800, Sam Leffler wrote:
>> > >
>> > http://git.chromium.org/gitweb/?p=chromiumos/third_party/autotest.git;a=blob;f=server/site_tests/network_WiFiRoaming/006BeaconLoss;h=35e1c01b952a71ba86c5c977ad5ddd22b676c448;hb=HEAD
>> > >
>> > > The issue is that when the AP is silently taken down (i.e. w/o sending
>> > > deauth) the client trys to reauth but fails--but never notifies the
>> > > connection manager over D-bus so it thinks it's still associated. ?I
>> > > believe when I split the state machine for fast reconnect I had to handle
>> > > this case in sme.c for reauth failure.
>> >
>> > Hmm.. I was unable to reproduce this. I tested this with ath9k and
>> > couple of seconds after turning off the AP, wpa_supplicant received an
>> > nl80211 event indicating deauthentication and that resulted in
>> > PropertiesChanged notification in D-Bus with State changing to
>> > disconnected.
>> >
>> There is no signal to indicate CurrentBSS is nil. ?I can send you a log
>> demonstrating the problem if you care.
> So CurrentBSS should be reflected through PropertiesChanged when
> wpas_notify_bssid_changed() gets called, which eventually checks
> wpa_s->current_bss for the value to send out in the PC event. ?A quick
> audit doesn't show anywhere that current_bss is set to NULL that doesn't
> also call wpas_notify_bssid_changed() but I didn't look too deeply.
> One way to fix this stuff for sure is to use setter functions that
> automatically send out the change notification when called. ?Like
> replacing every occurrance of wpa_s->current_bss = XXXX with
> wpa_supplicant_set_current_bss (struct wpa_supplicant *wpa_s, struct
> wpa_bss *bss); and checking whether the new bss matches the old BSS and
> if not, sending the change event. ?We'd also need the same for
> CurrentNetwork (wpas_notify_network_changed()) and a few other things to
> start with.

It appears the issue is really that after a fast reconnect attempt
that fails due to an auth failure the state machine clocks
AUTHENTICATING -> DISCONNECTED and for the SME case this does not post
a BSS changed signal because there is no current bss.  The specific
case is where you're associated to an AP and that goes away w/o
notifying the sta.  For mac80211-based devices at least you see this:

2012-01-30T13:43:33.988062-08:00 localhost wpa_supplicant[421]: wlan0:
Event DEAUTH (12) received
2012-01-30T13:43:33.988120-08:00 localhost wpa_supplicant[421]: wlan0:
Deauthentication notification
2012-01-30T13:43:33.988177-08:00 localhost wpa_supplicant[421]: wlan0:
 * reason 4 (locally generated)
2012-01-30T13:43:33.988233-08:00 localhost wpa_supplicant[421]: wlan0:
 * address c0:3f:0e:77:eb:3a

(i.e. beacon miss generates a local Deauth event).  supplicant
immediately tries to re-join and if the scan results are current finds
the AP and tries to re-auth but fails:

2012-01-30T13:43:38.091532-08:00 localhost kernel: [ 5474.132601]
wlan0: authenticate with c0:3f:0e:77:eb:3a (try 1)
2012-01-30T13:43:38.291537-08:00 localhost kernel: [ 5474.332131]
wlan0: authenticate with c0:3f:0e:77:eb:3a (try 2)
2012-01-30T13:43:38.491537-08:00 localhost kernel: [ 5474.532144]
wlan0: authenticate with c0:3f:0e:77:eb:3a (try 3)
2012-01-30T13:43:38.691518-08:00 localhost kernel: [ 5474.732136]
wlan0: authentication with c0:3f:0e:77:eb:3a timed out
2012-01-30T13:43:38.709584-08:00 localhost wpa_supplicant[421]:
nl80211: Event message available
2012-01-30T13:43:38.709682-08:00 localhost wpa_supplicant[421]:
nl80211: MLME event 37; timeout with c0:3f:0e:77:eb:3a
2012-01-30T13:43:38.709743-08:00 localhost wpa_supplicant[421]: wlan0:
Event AUTH_TIMED_OUT (14) received
2012-01-30T13:43:38.709800-08:00 localhost wpa_supplicant[421]: wlan0:
SME: Authentication timed out
2012-01-30T13:43:38.709859-08:00 localhost wpa_supplicant[421]: wlan0:

The problem is that by the time sme_event_auth_timed_out is called it
has no context to recognize a fast reconnect was going on and it needs
to post a bss change signal.  I handled this in my fast reconnect
logic by maintaining this state so on auth timeout or failure I could

static void sme_auth_failed(struct wpa_supplicant *wpa_s)
 274 {
 275         wpas_connection_failed(wpa_s, wpa_s->pending_bssid);
 276         if (wpa_s->fast_reconnect) {
 277                 wpa_s->fast_reconnect = FALSE;
 278                 wpa_printf(MSG_INFO, "Fast reconnect failed");
 279                 wpa_supplicant_mark_disassoc(wpa_s);
 280                 /* NB: wpa_supplicant_mark_disassoc will not signal */
 281                 wpas_notify_bssid_changed(wpa_s);
 282         }
 283 }

Looks like this is still needed even with the 1-channel scan logic
pushed down into  driver_nl80211.c.  Or have I missed something?

>> >
>> > This case should not really have triggered the fast reconnection attempt
>> > since the AP did not send any Deauthentication frame. However, it looks
>> > like the locally generated deauth event with reason 4 was interpreted as
>> > a Deauthentication done by the AP. I'll see how to fix this, but
>> > regardless, I don't see how this would have skipped the disconnection
>> > notification to the connection manager.
>> I don't agree; on beacon loss you should first probe the AP before dropping
>> into a full scan. ?If this is done with a NullData frame then going
>> straight to a full scan makes sense. ?Otherwise a failed direct reconnect
>> will take a few ms and is the right thing to do before incurring the cost
>> of the scan.
>> -Sam
>> _______________________________________________
>> HostAP mailing list
>> HostAP at lists.shmoo.com
>> http://lists.shmoo.com/mailman/listinfo/hostap

More information about the Hostap mailing list