]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
AP: Fix Deauth/Disassoc TX status timeout handling
authorJouni Malinen <jouni@qca.qualcomm.com>
Fri, 15 Jan 2016 17:28:58 +0000 (19:28 +0200)
committerJouni Malinen <j@w1.fi>
Fri, 15 Jan 2016 17:32:49 +0000 (19:32 +0200)
The ap_sta_deauth_cb and ap_sta_disassoc_cb eloop timeouts are used to
clear a disconnecting STA from the kernel driver if the STA did not ACK
the Deauthentication/Disassociation frame from the AP within two
seconds. However, it was possible for a STA to not ACK such a frame,
e.g., when the disconnection happened due to hostapd pruning old
associations from other BSSes and the STA was not on the old channel
anymore. If that same STA then started a new authentication/association
with the BSS, the two second timeout could trigger during this new
association and result in the STA entry getting removed from the kernel.

Fix this by canceling these eloop timeouts when receiving an indication
of a new authentication or association.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
src/ap/ap_mlme.c
src/ap/hostapd.c
src/ap/sta_info.c
src/ap/sta_info.h

index 13604edc49406e0a78e9dc57cb487d9d0a63e24e..e7308a01d7432f3fb5ea0d6bcda4a7f4bdb412ee 100644 (file)
@@ -59,6 +59,7 @@ void mlme_authenticate_indication(struct hostapd_data *hapd,
                       MAC2STR(sta->addr), mlme_auth_alg_str(sta->auth_alg));
        if (sta->auth_alg != WLAN_AUTH_FT && !(sta->flags & WLAN_STA_MFP))
                mlme_deletekeys_request(hapd, sta);
+       ap_sta_clear_disconnect_timeouts(hapd, sta);
 }
 
 
@@ -106,6 +107,7 @@ void mlme_associate_indication(struct hostapd_data *hapd, struct sta_info *sta)
                       MAC2STR(sta->addr));
        if (sta->auth_alg != WLAN_AUTH_FT)
                mlme_deletekeys_request(hapd, sta);
+       ap_sta_clear_disconnect_timeouts(hapd, sta);
 }
 
 
@@ -130,6 +132,7 @@ void mlme_reassociate_indication(struct hostapd_data *hapd,
                       MAC2STR(sta->addr));
        if (sta->auth_alg != WLAN_AUTH_FT)
                mlme_deletekeys_request(hapd, sta);
+       ap_sta_clear_disconnect_timeouts(hapd, sta);
 }
 
 
index b10b454e35106664879601ad9f83c8adb0be70db..8e04d6c5e6e6e8e54185d7fd9879409eddf6e46e 100644 (file)
@@ -2634,6 +2634,7 @@ void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta,
        }
 
        hostapd_prune_associations(hapd, sta->addr);
+       ap_sta_clear_disconnect_timeouts(hapd, sta);
 
        /* IEEE 802.11F (IAPP) */
        if (hapd->conf->ieee802_11f)
index 68fff4cf9636699167ff45cf53aeb4a16f3ad81f..c3105aa254d713c5f231590183328c115bb2d0d8 100644 (file)
@@ -249,8 +249,7 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
        eloop_cancel_timeout(ap_handle_timer, hapd, sta);
        eloop_cancel_timeout(ap_handle_session_timer, hapd, sta);
        eloop_cancel_timeout(ap_handle_session_warning_timer, hapd, sta);
-       eloop_cancel_timeout(ap_sta_deauth_cb_timeout, hapd, sta);
-       eloop_cancel_timeout(ap_sta_disassoc_cb_timeout, hapd, sta);
+       ap_sta_clear_disconnect_timeouts(hapd, sta);
        sae_clear_retransmit_timer(hapd, sta);
 
        ieee802_1x_free_station(hapd, sta);
@@ -1117,6 +1116,22 @@ void ap_sta_disassoc_cb(struct hostapd_data *hapd, struct sta_info *sta)
 }
 
 
+void ap_sta_clear_disconnect_timeouts(struct hostapd_data *hapd,
+                                     struct sta_info *sta)
+{
+       if (eloop_cancel_timeout(ap_sta_deauth_cb_timeout, hapd, sta) > 0)
+               wpa_printf(MSG_DEBUG,
+                          "%s: Removed ap_sta_deauth_cb_timeout timeout for "
+                          MACSTR,
+                          hapd->conf->iface, MAC2STR(sta->addr));
+       if (eloop_cancel_timeout(ap_sta_disassoc_cb_timeout, hapd, sta) > 0)
+               wpa_printf(MSG_DEBUG,
+                          "%s: Removed ap_sta_disassoc_cb_timeout timeout for "
+                          MACSTR,
+                          hapd->conf->iface, MAC2STR(sta->addr));
+}
+
+
 int ap_sta_flags_txt(u32 flags, char *buf, size_t buflen)
 {
        int res;
index 09deac6d7e3f51fb6d9501c190356c9cd5c201de..e3b4915a801454a045ef35f77614eeda55eb44ce 100644 (file)
@@ -236,6 +236,8 @@ static inline int ap_sta_is_authorized(struct sta_info *sta)
 
 void ap_sta_deauth_cb(struct hostapd_data *hapd, struct sta_info *sta);
 void ap_sta_disassoc_cb(struct hostapd_data *hapd, struct sta_info *sta);
+void ap_sta_clear_disconnect_timeouts(struct hostapd_data *hapd,
+                                     struct sta_info *sta);
 
 int ap_sta_flags_txt(u32 flags, char *buf, size_t buflen);