Add workaround for race condition with AssocResp TX status
authorJouni Malinen <jouni.malinen@atheros.com>
Fri, 15 Apr 2011 16:26:28 +0000 (19:26 +0300)
committerJouni Malinen <j@w1.fi>
Fri, 15 Apr 2011 16:26:28 +0000 (19:26 +0300)
It may take some time for the TX status to be delivered for a
(Re)Association Response frame and if any Data frames are received
during that time, they may end up getting dropped as Class 3 frames in
not-associated state. This results in a Disassociation frame being sent
to the station and it assuming that the association has been lost.

Work around the issue by remembering that the (Re)Association Request
has already been accepted and skip the Deauth/Disassoc sending because
of the possible Class 3 frames before the TX status callback is
received.

src/ap/ieee802_11.c
src/ap/sta_info.h

index ffc38ae..4d8dd25 100644 (file)
@@ -1103,6 +1103,7 @@ static void handle_assoc(struct hostapd_data *hapd,
                       "association OK (aid %d)", sta->aid);
        /* Station will be marked associated, after it acknowledges AssocResp
         */
+       sta->flags |= WLAN_STA_ASSOC_REQ_OK;
 
 #ifdef CONFIG_IEEE80211W
        if ((sta->flags & WLAN_STA_MFP) && sta->sa_query_timed_out) {
@@ -1159,7 +1160,7 @@ static void handle_disassoc(struct hostapd_data *hapd,
                return;
        }
 
-       sta->flags &= ~WLAN_STA_ASSOC;
+       sta->flags &= ~(WLAN_STA_ASSOC | WLAN_STA_ASSOC_REQ_OK);
        wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED MACSTR,
                MAC2STR(sta->addr));
        wpa_auth_sm_event(sta->wpa_sm, WPA_DISASSOC);
@@ -1209,7 +1210,8 @@ static void handle_deauth(struct hostapd_data *hapd,
                return;
        }
 
-       sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC);
+       sta->flags &= ~(WLAN_STA_AUTH | WLAN_STA_ASSOC |
+                       WLAN_STA_ASSOC_REQ_OK);
        wpa_msg(hapd->msg_ctx, MSG_INFO, AP_STA_DISCONNECTED MACSTR,
                MAC2STR(sta->addr));
        wpa_auth_sm_event(sta->wpa_sm, WPA_DEAUTH);
@@ -1858,6 +1860,14 @@ void ieee802_11_rx_from_unknown(struct hostapd_data *hapd, const u8 *src,
                return;
        }
 
+       if (sta && (sta->flags & WLAN_STA_ASSOC_REQ_OK)) {
+               wpa_printf(MSG_DEBUG, "Association Response to the STA has "
+                          "already been sent, but no TX status yet known - "
+                          "ignore Class 3 frame issue with " MACSTR,
+                          MAC2STR(src));
+               return;
+       }
+
        if (sta && (sta->flags & WLAN_STA_AUTH))
                hostapd_drv_sta_disassoc(
                        hapd, src,
index c22f253..9ec4fe3 100644 (file)
@@ -31,6 +31,7 @@
 #define WLAN_STA_WPS BIT(12)
 #define WLAN_STA_MAYBE_WPS BIT(13)
 #define WLAN_STA_WDS BIT(14)
+#define WLAN_STA_ASSOC_REQ_OK BIT(15)
 #define WLAN_STA_NONERP BIT(31)
 
 /* Maximum number of supported rates (from both Supported Rates and Extended