Parcourir la source

Add handling of SME auth/assoc timeout events

This allows wpa_supplicant to start searching for other APs (or re-try)
if the MLME times out.
Jouni Malinen il y a 16 ans
Parent
commit
da1fb17ca7

+ 11 - 2
src/common/nl80211_copy.h

@@ -203,8 +203,12 @@
  *	frame, i.e., it was for the local STA and was received in correct
  *	state. This is similar to MLME-AUTHENTICATE.confirm primitive in the
  *	MLME SAP interface (kernel providing MLME, userspace SME). The
- *	included NL80211_ATTR_FRAME attribute contains the management frame
- *	(including both the header and frame body, but not FCS).
+ *	included %NL80211_ATTR_FRAME attribute contains the management frame
+ *	(including both the header and frame body, but not FCS). This event is
+ *	also used to indicate if the authentication attempt timed out. In that
+ *	case the %NL80211_ATTR_FRAME attribute is replaced with a
+ *	%NL80211_ATTR_TIMED_OUT flag (and %NL80211_ATTR_MAC to indicate which
+ *	pending authentication timed out).
  * @NL80211_CMD_ASSOCIATE: association request and notification; like
  *	NL80211_CMD_AUTHENTICATE but for Association and Reassociation
  *	(similar to MLME-ASSOCIATE.request, MLME-REASSOCIATE.request,
@@ -485,6 +489,9 @@ enum nl80211_commands {
  * @NL80211_ATTR_FREQ_FIXED: a flag indicating the IBSS should not try to look
  *	for other networks on different channels
  *
+ * @NL80211_ATTR_TIMED_OUT: a flag indicating than an operation timed out; this
+ *	is used, e.g., with %NL80211_CMD_AUTHENTICATE event
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -585,6 +592,8 @@ enum nl80211_attrs {
 	NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
 	NL80211_ATTR_WIPHY_RTS_THRESHOLD,
 
+	NL80211_ATTR_TIMED_OUT,
+
 	/* add attributes here, update the policy in nl80211.c */
 
 	__NL80211_ATTR_AFTER_LAST,

+ 15 - 1
src/drivers/driver.h

@@ -1497,7 +1497,17 @@ typedef enum wpa_event_type {
 	 * rejected by the AP. Information about authentication result is
 	 * included in union wpa_event_data::assoc_reject.
 	 */
-	EVENT_ASSOC_REJECT
+	EVENT_ASSOC_REJECT,
+
+	/**
+	 * EVENT_AUTH_TIMED_OUT - Authentication timed out
+	 */
+	EVENT_AUTH_TIMED_OUT,
+
+	/**
+	 * EVENT_ASSOC_TIMED_OUT - Association timed out
+	 */
+	EVENT_ASSOC_TIMED_OUT
 } wpa_event_type;
 
 
@@ -1675,6 +1685,10 @@ union wpa_event_data {
 		 */
 		u16 status_code;
 	} assoc_reject;
+
+	struct timeout_event {
+		u8 addr[ETH_ALEN];
+	} timeout_event;
 };
 
 /**

+ 34 - 2
src/drivers/driver_nl80211.c

@@ -740,9 +740,40 @@ static void mlme_event_assoc(struct wpa_driver_nl80211_data *drv,
 }
 
 
+static void mlme_timeout_event(struct wpa_driver_nl80211_data *drv,
+			       enum nl80211_commands cmd, struct nlattr *addr)
+{
+	union wpa_event_data event;
+	enum wpa_event_type ev;
+
+	if (nla_len(addr) != ETH_ALEN)
+		return;
+
+	wpa_printf(MSG_DEBUG, "nl80211: MLME event %d; timeout with " MACSTR,
+		   cmd, MAC2STR((u8 *) nla_data(addr)));
+
+	if (cmd == NL80211_CMD_AUTHENTICATE)
+		ev = EVENT_AUTH_TIMED_OUT;
+	else if (cmd == NL80211_CMD_ASSOCIATE)
+		ev = EVENT_ASSOC_TIMED_OUT;
+	else
+		return;
+
+	os_memset(&event, 0, sizeof(event));
+	os_memcpy(event.timeout_event.addr, nla_data(addr), ETH_ALEN);
+	wpa_supplicant_event(drv->ctx, ev, &event);
+}
+
+
 static void mlme_event(struct wpa_driver_nl80211_data *drv,
-		       enum nl80211_commands cmd, struct nlattr *frame)
+		       enum nl80211_commands cmd, struct nlattr *frame,
+		       struct nlattr *addr, struct nlattr *timed_out)
 {
+	if (timed_out && addr) {
+		mlme_timeout_event(drv, cmd, addr);
+		return;
+	}
+
 	if (frame == NULL) {
 		wpa_printf(MSG_DEBUG, "nl80211: MLME event %d without frame "
 			   "data", cmd);
@@ -861,7 +892,8 @@ static int process_event(struct nl_msg *msg, void *arg)
 	case NL80211_CMD_ASSOCIATE:
 	case NL80211_CMD_DEAUTHENTICATE:
 	case NL80211_CMD_DISASSOCIATE:
-		mlme_event(drv, gnlh->cmd, tb[NL80211_ATTR_FRAME]);
+		mlme_event(drv, gnlh->cmd, tb[NL80211_ATTR_FRAME],
+			   tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_TIMED_OUT]);
 		break;
 #endif /* HOSTAPD */
 	case NL80211_CMD_MICHAEL_MIC_FAILURE:

+ 6 - 0
wpa_supplicant/events.c

@@ -1229,6 +1229,12 @@ void wpa_supplicant_event(void *ctx, wpa_event_type event,
 	case EVENT_ASSOC_REJECT:
 		sme_event_assoc_reject(wpa_s, data);
 		break;
+	case EVENT_AUTH_TIMED_OUT:
+		sme_event_auth_timed_out(wpa_s, data);
+		break;
+	case EVENT_ASSOC_TIMED_OUT:
+		sme_event_assoc_timed_out(wpa_s, data);
+		break;
 	default:
 		wpa_printf(MSG_INFO, "Unknown event %d", event);
 		break;

+ 17 - 0
wpa_supplicant/sme.c

@@ -361,3 +361,20 @@ void sme_event_assoc_reject(struct wpa_supplicant *wpa_s,
 	 */
 	wpa_supplicant_req_scan(wpa_s, 5, 0);
 }
+
+
+void sme_event_auth_timed_out(struct wpa_supplicant *wpa_s,
+			      union wpa_event_data *data)
+{
+	wpa_printf(MSG_DEBUG, "SME: Authentication timed out");
+	wpa_supplicant_req_scan(wpa_s, 5, 0);
+}
+
+
+void sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s,
+			       union wpa_event_data *data)
+{
+	wpa_printf(MSG_DEBUG, "SME: Association timed out");
+	wpa_supplicant_mark_disassoc(wpa_s);
+	wpa_supplicant_req_scan(wpa_s, 5, 0);
+}

+ 14 - 0
wpa_supplicant/sme.h

@@ -24,6 +24,10 @@ int sme_update_ft_ies(struct wpa_supplicant *wpa_s, const u8 *md,
 		      const u8 *ies, size_t ies_len);
 void sme_event_assoc_reject(struct wpa_supplicant *wpa_s,
 			    union wpa_event_data *data);
+void sme_event_auth_timed_out(struct wpa_supplicant *wpa_s,
+			      union wpa_event_data *data);
+void sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s,
+			       union wpa_event_data *data);
 
 #else /* CONFIG_SME */
 
@@ -50,6 +54,16 @@ static inline void sme_event_assoc_reject(struct wpa_supplicant *wpa_s,
 {
 }
 
+static inline void sme_event_auth_timed_out(struct wpa_supplicant *wpa_s,
+					    union wpa_event_data *data)
+{
+}
+
+static inline void sme_event_assoc_timed_out(struct wpa_supplicant *wpa_s,
+					     union wpa_event_data *data)
+{
+}
+
 #endif /* CONFIG_SME */
 
 #endif /* SME_H */