aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <jouni.malinen@atheros.com>2009-09-04 15:04:41 (GMT)
committerJouni Malinen <j@w1.fi>2009-11-22 18:48:23 (GMT)
commitf9c7b1e06cef6c02a6056896f19740a21c1726de (patch)
tree87f1e377b74ac288a5052cfa0abc4c84e6cfba42
parentdb3717543f21c3d85a8225814f53c6e8cc85730d (diff)
downloadhostap-06-f9c7b1e06cef6c02a6056896f19740a21c1726de.zip
hostap-06-f9c7b1e06cef6c02a6056896f19740a21c1726de.tar.gz
hostap-06-f9c7b1e06cef6c02a6056896f19740a21c1726de.tar.bz2
Delay processing of EAPOL frames when not associated
If an EAPOL frame is received while wpa_supplicant thinks the driver is not associated, queue the frame for processing at the moment when the association event is received. This is a workaround to a race condition in receiving data frames and management events from the kernel. The pending EAPOL frame will not be processed unless an association event is received within 100 msec for the same BSSID. (cherry picked from commit 1ff733383f3d5c73233ef452a738765667021609)
-rw-r--r--wpa_supplicant/events.c19
-rw-r--r--wpa_supplicant/wpa_supplicant.c24
-rw-r--r--wpa_supplicant/wpa_supplicant_i.h4
3 files changed, 47 insertions, 0 deletions
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index ab3cc64..e1c3aa9 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -869,6 +869,25 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
}
+
+ if (wpa_s->pending_eapol_rx) {
+ struct os_time now, age;
+ os_get_time(&now);
+ os_time_sub(&now, &wpa_s->pending_eapol_rx_time, &age);
+ if (age.sec == 0 && age.usec < 100000 &&
+ os_memcmp(wpa_s->pending_eapol_rx_src, bssid, ETH_ALEN) ==
+ 0) {
+ wpa_printf(MSG_DEBUG, "Process pending EAPOL frame "
+ "that was received just before association "
+ "notification");
+ wpa_supplicant_rx_eapol(
+ wpa_s, wpa_s->pending_eapol_rx_src,
+ wpabuf_head(wpa_s->pending_eapol_rx),
+ wpabuf_len(wpa_s->pending_eapol_rx));
+ }
+ wpabuf_free(wpa_s->pending_eapol_rx);
+ wpa_s->pending_eapol_rx = NULL;
+ }
}
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 8033f34..7e78946 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -385,6 +385,9 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
ieee80211_sta_deinit(wpa_s);
wpas_wps_deinit(wpa_s);
+
+ wpabuf_free(wpa_s->pending_eapol_rx);
+ wpa_s->pending_eapol_rx = NULL;
}
@@ -1492,6 +1495,27 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
wpa_printf(MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
+ if (wpa_s->wpa_state < WPA_ASSOCIATED) {
+ /*
+ * There is possible race condition between receiving the
+ * association event and the EAPOL frame since they are coming
+ * through different paths from the driver. In order to avoid
+ * issues in trying to process the EAPOL frame before receiving
+ * association information, lets queue it for processing until
+ * the association event is received.
+ */
+ wpa_printf(MSG_DEBUG, "Not associated - Delay processing of "
+ "received EAPOL frame");
+ wpabuf_free(wpa_s->pending_eapol_rx);
+ wpa_s->pending_eapol_rx = wpabuf_alloc_copy(buf, len);
+ if (wpa_s->pending_eapol_rx) {
+ os_get_time(&wpa_s->pending_eapol_rx_time);
+ os_memcpy(wpa_s->pending_eapol_rx_src, src_addr,
+ ETH_ALEN);
+ }
+ return;
+ }
+
if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
wpa_printf(MSG_DEBUG, "Ignored received EAPOL frame since "
"no key management is configured");
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 5e4dcc1..51e5800 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -358,6 +358,10 @@ struct wpa_supplicant {
struct wps_context *wps;
int wps_success; /* WPS success event received */
int blacklist_cleared;
+
+ struct wpabuf *pending_eapol_rx;
+ struct os_time pending_eapol_rx_time;
+ u8 pending_eapol_rx_src[ETH_ALEN];
};