25bef9c
From: Jouni Malinen <jouni.malinen@atheros.com>
25bef9c
Date: Fri, 4 Sep 2009 15:04:41 +0000 (+0300)
25bef9c
Subject: Delay processing of EAPOL frames when not associated
25bef9c
X-Git-Url: http://w1.fi/gitweb/gitweb.cgi?p=hostap.git;a=commitdiff_plain;h=1ff733383f3d5c73233ef452a738765667021609
25bef9c
25bef9c
Delay processing of EAPOL frames when not associated
25bef9c
25bef9c
If an EAPOL frame is received while wpa_supplicant thinks the driver is
25bef9c
not associated, queue the frame for processing at the moment when the
25bef9c
association event is received. This is a workaround to a race condition
25bef9c
in receiving data frames and management events from the kernel.
25bef9c
25bef9c
The pending EAPOL frame will not be processed unless an association
25bef9c
event is received within 100 msec for the same BSSID.
25bef9c
---
25bef9c
25bef9c
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
25bef9c
index e5e799d..2ea9279 100644
25bef9c
--- a/wpa_supplicant/events.c
25bef9c
+++ b/wpa_supplicant/events.c
25bef9c
@@ -943,6 +943,25 @@ static void wpa_supplicant_event_assoc(struct wpa_supplicant *wpa_s,
25bef9c
 		eapol_sm_notify_portValid(wpa_s->eapol, TRUE);
25bef9c
 		eapol_sm_notify_eap_success(wpa_s->eapol, TRUE);
25bef9c
 	}
25bef9c
+
25bef9c
+	if (wpa_s->pending_eapol_rx) {
25bef9c
+		struct os_time now, age;
25bef9c
+		os_get_time(&now;;
25bef9c
+		os_time_sub(&now, &wpa_s->pending_eapol_rx_time, &age;;
25bef9c
+		if (age.sec == 0 && age.usec < 100000 &&
25bef9c
+		    os_memcmp(wpa_s->pending_eapol_rx_src, bssid, ETH_ALEN) ==
25bef9c
+		    0) {
25bef9c
+			wpa_printf(MSG_DEBUG, "Process pending EAPOL frame "
25bef9c
+				   "that was received just before association "
25bef9c
+				   "notification");
25bef9c
+			wpa_supplicant_rx_eapol(
25bef9c
+				wpa_s, wpa_s->pending_eapol_rx_src,
25bef9c
+				wpabuf_head(wpa_s->pending_eapol_rx),
25bef9c
+				wpabuf_len(wpa_s->pending_eapol_rx));
25bef9c
+		}
25bef9c
+		wpabuf_free(wpa_s->pending_eapol_rx);
25bef9c
+		wpa_s->pending_eapol_rx = NULL;
25bef9c
+	}
25bef9c
 }
25bef9c
 
25bef9c
 
25bef9c
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
25bef9c
index d03e9da..c68dd82 100644
25bef9c
--- a/wpa_supplicant/wpa_supplicant.c
25bef9c
+++ b/wpa_supplicant/wpa_supplicant.c
25bef9c
@@ -405,6 +405,9 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
25bef9c
 	ieee80211_sta_deinit(wpa_s);
25bef9c
 
25bef9c
 	wpas_wps_deinit(wpa_s);
25bef9c
+
25bef9c
+	wpabuf_free(wpa_s->pending_eapol_rx);
25bef9c
+	wpa_s->pending_eapol_rx = NULL;
25bef9c
 }
25bef9c
 
25bef9c
 
25bef9c
@@ -1574,6 +1577,27 @@ void wpa_supplicant_rx_eapol(void *ctx, const u8 *src_addr,
25bef9c
 	wpa_printf(MSG_DEBUG, "RX EAPOL from " MACSTR, MAC2STR(src_addr));
25bef9c
 	wpa_hexdump(MSG_MSGDUMP, "RX EAPOL", buf, len);
25bef9c
 
25bef9c
+	if (wpa_s->wpa_state < WPA_ASSOCIATED) {
25bef9c
+		/*
25bef9c
+		 * There is possible race condition between receiving the
25bef9c
+		 * association event and the EAPOL frame since they are coming
25bef9c
+		 * through different paths from the driver. In order to avoid
25bef9c
+		 * issues in trying to process the EAPOL frame before receiving
25bef9c
+		 * association information, lets queue it for processing until
25bef9c
+		 * the association event is received.
25bef9c
+		 */
25bef9c
+		wpa_printf(MSG_DEBUG, "Not associated - Delay processing of "
25bef9c
+			   "received EAPOL frame");
25bef9c
+		wpabuf_free(wpa_s->pending_eapol_rx);
25bef9c
+		wpa_s->pending_eapol_rx = wpabuf_alloc_copy(buf, len);
25bef9c
+		if (wpa_s->pending_eapol_rx) {
25bef9c
+			os_get_time(&wpa_s->pending_eapol_rx_time);
25bef9c
+			os_memcpy(wpa_s->pending_eapol_rx_src, src_addr,
25bef9c
+				  ETH_ALEN);
25bef9c
+		}
25bef9c
+		return;
25bef9c
+	}
25bef9c
+
25bef9c
 	if (wpa_s->key_mgmt == WPA_KEY_MGMT_NONE) {
25bef9c
 		wpa_printf(MSG_DEBUG, "Ignored received EAPOL frame since "
25bef9c
 			   "no key management is configured");
25bef9c
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
25bef9c
index 63984d8..e814f86 100644
25bef9c
--- a/wpa_supplicant/wpa_supplicant_i.h
25bef9c
+++ b/wpa_supplicant/wpa_supplicant_i.h
25bef9c
@@ -364,6 +364,10 @@ struct wpa_supplicant {
25bef9c
 	int wps_success; /* WPS success event received */
25bef9c
 	int blacklist_cleared;
25bef9c
 
25bef9c
+	struct wpabuf *pending_eapol_rx;
25bef9c
+	struct os_time pending_eapol_rx_time;
25bef9c
+	u8 pending_eapol_rx_src[ETH_ALEN];
25bef9c
+
25bef9c
 	int disconnect_count;
25bef9c
 };
25bef9c
 
25bef9c