Parcourir la source

IEEE 802.11w: Use comeback duration to delay association

Jouni Malinen il y a 16 ans
Parent
commit
6572fc0d1b
1 fichiers modifiés avec 28 ajouts et 6 suppressions
  1. 28 6
      wpa_supplicant/mlme.c

+ 28 - 6
wpa_supplicant/mlme.c

@@ -129,6 +129,8 @@ struct ieee802_11_elems {
 	u8 mdie_len;
 	u8 *ftie;
 	u8 ftie_len;
+	u8 *assoc_comeback;
+	u8 assoc_comeback_len;
 };
 
 typedef enum { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 } ParseRes;
@@ -231,6 +233,10 @@ static ParseRes ieee802_11_parse_elems(u8 *start, size_t len,
 			elems->ftie = pos;
 			elems->ftie_len = elen;
 			break;
+		case WLAN_EID_ASSOC_COMEBACK_TIME:
+			elems->assoc_comeback = pos;
+			elems->assoc_comeback_len = elen;
+			break;
 		default:
 #if 0
 			wpa_printf(MSG_MSGDUMP "MLME: IEEE 802.11 element "
@@ -1231,12 +1237,6 @@ static void ieee80211_rx_mgmt_assoc_resp(struct wpa_supplicant *wpa_s,
 		   reassoc ? "Rea" : "A", MAC2STR(mgmt->sa),
 		   capab_info, status_code, aid);
 
-	if (status_code != WLAN_STATUS_SUCCESS) {
-		wpa_printf(MSG_DEBUG, "MLME: AP denied association (code=%d)",
-			   status_code);
-		return;
-	}
-
 	pos = mgmt->u.assoc_resp.variable;
 	if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems)
 	    == ParseFailed) {
@@ -1244,6 +1244,28 @@ static void ieee80211_rx_mgmt_assoc_resp(struct wpa_supplicant *wpa_s,
 		return;
 	}
 
+	if (status_code != WLAN_STATUS_SUCCESS) {
+		wpa_printf(MSG_DEBUG, "MLME: AP denied association (code=%d)",
+			   status_code);
+#ifdef CONFIG_IEEE80211W
+		if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY &&
+		    elems.assoc_comeback && elems.assoc_comeback_len == 4) {
+			u32 tu, ms;
+			tu = WPA_GET_LE32(elems.assoc_comeback);
+			ms = tu * 1024 / 1000;
+			wpa_printf(MSG_DEBUG, "MLME: AP rejected association "
+				   "temporarily; comeback duration %u TU "
+				   "(%u ms)", tu, ms);
+			if (ms > IEEE80211_ASSOC_TIMEOUT) {
+				wpa_printf(MSG_DEBUG, "MLME: Update timer "
+					   "based on comeback duration");
+				ieee80211_reschedule_timer(wpa_s, ms);
+			}
+		}
+#endif /* CONFIG_IEEE80211W */
+		return;
+	}
+
 	if (elems.supp_rates == NULL) {
 		wpa_printf(MSG_DEBUG, "MLME: no SuppRates element in "
 			   "AssocResp");