[PATCH] AP: save EAPOL received before assoc resp
Eliad Peller
eliad at wizery.com
Wed Mar 2 08:50:26 PST 2016
There is a race condition in which wpa_supplicant might
receive the EAPOL-Start frame (from the just-associated
station) before the tx completion of the assoc response.
This in turn will cause the EAPOL-Start frame to get
dropped, and potentially failing the connection.
Solve this by saving EAPOLs from authenticated-but-not-
associated stations, and handling them during the assoc
response tx completion processing.
Signed-off-by: Eliad Peller <eliad at wizery.com>
---
src/ap/ieee802_11.c | 19 +++++++++++++++++++
src/ap/ieee802_1x.c | 15 +++++++++++++++
src/ap/sta_info.h | 4 ++++
3 files changed, 38 insertions(+)
diff --git a/src/ap/ieee802_11.c b/src/ap/ieee802_11.c
index b36e68d..d221825 100644
--- a/src/ap/ieee802_11.c
+++ b/src/ap/ieee802_11.c
@@ -2782,6 +2782,25 @@ static void handle_assoc_cb(struct hostapd_data *hapd,
wpa_auth_sm_event(sta->wpa_sm, WPA_ASSOC);
hapd->new_assoc_sta_cb(hapd, sta, !new_assoc);
ieee802_1x_notify_port_enabled(sta->eapol_sm, 1);
+
+ if (sta->pending_eapol_rx) {
+ struct os_reltime now, age;
+ os_get_reltime(&now);
+ os_reltime_sub(&now, &sta->pending_eapol_rx_time, &age);
+ if (age.sec == 0 && age.usec < 200000 &&
+ os_memcmp(sta->pending_eapol_rx_src,
+ mgmt->da, ETH_ALEN) == 0) {
+ wpa_printf(MSG_DEBUG, "Process pending EAPOL "
+ "frame that was received just before "
+ "association notification");
+ ieee802_1x_receive(
+ hapd, sta->pending_eapol_rx_src,
+ wpabuf_head(sta->pending_eapol_rx),
+ wpabuf_len(sta->pending_eapol_rx));
+ }
+ wpabuf_free(sta->pending_eapol_rx);
+ sta->pending_eapol_rx = NULL;
+ }
}
diff --git a/src/ap/ieee802_1x.c b/src/ap/ieee802_1x.c
index c774d5c..e34d0d3 100644
--- a/src/ap/ieee802_1x.c
+++ b/src/ap/ieee802_1x.c
@@ -891,6 +891,18 @@ void ieee802_1x_receive(struct hostapd_data *hapd, const u8 *sa, const u8 *buf,
!(hapd->iface->drv_flags & WPA_DRIVER_FLAGS_WIRED))) {
wpa_printf(MSG_DEBUG, "IEEE 802.1X data frame from not "
"associated/Pre-authenticating STA");
+
+ if (sta && (sta->flags & WLAN_STA_AUTH)) {
+ wpa_printf(MSG_DEBUG, "Saving EAPOL for later use");
+ wpabuf_free(sta->pending_eapol_rx);
+ sta->pending_eapol_rx = wpabuf_alloc_copy(buf, len);
+ if (sta->pending_eapol_rx) {
+ os_get_reltime(&sta->pending_eapol_rx_time);
+ os_memcpy(sta->pending_eapol_rx_src, sa,
+ ETH_ALEN);
+ }
+ }
+
return;
}
@@ -1183,6 +1195,9 @@ void ieee802_1x_free_station(struct hostapd_data *hapd, struct sta_info *sta)
eloop_cancel_timeout(ieee802_1x_wnm_notif_send, hapd, sta);
#endif /* CONFIG_HS20 */
+ wpabuf_free(sta->pending_eapol_rx);
+ sta->pending_eapol_rx = NULL;
+
if (sm == NULL)
return;
diff --git a/src/ap/sta_info.h b/src/ap/sta_info.h
index e223341..ecba920 100644
--- a/src/ap/sta_info.h
+++ b/src/ap/sta_info.h
@@ -113,6 +113,10 @@ struct sta_info {
/* IEEE 802.1X related data */
struct eapol_state_machine *eapol_sm;
+ struct wpabuf *pending_eapol_rx;
+ struct os_reltime pending_eapol_rx_time;
+ u8 pending_eapol_rx_src[ETH_ALEN];
+
u64 acct_session_id;
struct os_reltime acct_session_start;
int acct_session_started;
--
2.6.3
More information about the Hostap
mailing list