aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2008-12-26 10:30:34 (GMT)
committerJouni Malinen <j@w1.fi>2008-12-26 10:30:34 (GMT)
commit45c94154a61d932174232e19f096e346a129b028 (patch)
tree78c40b76060ad7efa64dcb4f204bcc44fa394721
parent93b76319f1506c386966721a3fb30482883b4b3d (diff)
downloadhostap-06-45c94154a61d932174232e19f096e346a129b028.zip
hostap-06-45c94154a61d932174232e19f096e346a129b028.tar.gz
hostap-06-45c94154a61d932174232e19f096e346a129b028.tar.bz2
Updated SA Query procedure to use timeouts per 802.11w/D7.0
The previous max_attempts * timeout is now replaced with two timeouts (one for each retry, the other one for maximum wait).
-rw-r--r--hostapd/ap.h1
-rw-r--r--hostapd/config.c26
-rw-r--r--hostapd/config.h8
-rw-r--r--hostapd/hostapd.conf16
-rw-r--r--hostapd/ieee802_11.c17
-rw-r--r--hostapd/sta_info.c49
-rw-r--r--hostapd/sta_info.h1
7 files changed, 78 insertions, 40 deletions
diff --git a/hostapd/ap.h b/hostapd/ap.h
index 4f67e27..98f8ee7 100644
--- a/hostapd/ap.h
+++ b/hostapd/ap.h
@@ -106,6 +106,7 @@ struct sta_info {
u8 *sa_query_trans_id; /* buffer of WLAN_SA_QUERY_TR_ID_LEN *
* sa_query_count octets of pending SA Query
* transaction identifiers */
+ struct os_time sa_query_start;
#endif /* CONFIG_IEEE80211W */
struct wpabuf *wps_ie; /* WPS IE from (Re)Association Request */
diff --git a/hostapd/config.c b/hostapd/config.c
index 39cc18d..650ddb9 100644
--- a/hostapd/config.c
+++ b/hostapd/config.c
@@ -184,8 +184,8 @@ static void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
bss->max_listen_interval = 65535;
#ifdef CONFIG_IEEE80211W
- bss->assoc_ping_timeout = 1000;
- bss->assoc_ping_attempts = 3;
+ bss->assoc_sa_query_max_timeout = 1000;
+ bss->assoc_sa_query_retry_timeout = 201;
#endif /* CONFIG_IEEE80211W */
#ifdef EAP_FAST
/* both anonymous and authenticated provisioning */
@@ -2064,18 +2064,20 @@ struct hostapd_config * hostapd_config_read(const char *fname)
#ifdef CONFIG_IEEE80211W
} else if (os_strcmp(buf, "ieee80211w") == 0) {
bss->ieee80211w = atoi(pos);
- } else if (os_strcmp(buf, "assoc_ping_timeout") == 0) {
- bss->assoc_ping_timeout = atoi(pos);
- if (bss->assoc_ping_timeout == 0) {
- printf("Line %d: invalid assoc_ping_timeout\n",
- line);
+ } else if (os_strcmp(buf, "assoc_sa_query_max_timeout") == 0) {
+ bss->assoc_sa_query_max_timeout = atoi(pos);
+ if (bss->assoc_sa_query_max_timeout == 0) {
+ printf("Line %d: invalid "
+ "assoc_sa_query_max_timeout\n",
+ line);
errors++;
}
- } else if (os_strcmp(buf, "assoc_ping_attempts") == 0) {
- bss->assoc_ping_timeout = atoi(pos);
- if (bss->assoc_ping_timeout == 0) {
- printf("Line %d: invalid assoc_ping_attempts "
- "(valid range: 1..255)\n",
+ } else if (os_strcmp(buf, "assoc_sa_query_retry_timeout") == 0)
+ {
+ bss->assoc_sa_query_retry_timeout = atoi(pos);
+ if (bss->assoc_sa_query_retry_timeout == 0) {
+ printf("Line %d: invalid "
+ "assoc_sa_query_retry_timeout\n",
line);
errors++;
}
diff --git a/hostapd/config.h b/hostapd/config.h
index 68b9856..c9c715c 100644
--- a/hostapd/config.h
+++ b/hostapd/config.h
@@ -210,10 +210,10 @@ struct hostapd_bss_config {
IEEE80211W_OPTIONAL = 1,
IEEE80211W_REQUIRED = 2
} ieee80211w;
- /* dot11AssociationPingResponseTimeout (in TU) */
- unsigned int assoc_ping_timeout;
- /* dot11AssociationMaximumPingAttempts */
- int assoc_ping_attempts;
+ /* dot11AssociationSAQueryMaximumTimeout (in TUs) */
+ unsigned int assoc_sa_query_max_timeout;
+ /* dot11AssociationSAQueryRetryTimeout (in TUs) */
+ int assoc_sa_query_retry_timeout;
#endif /* CONFIG_IEEE80211W */
int wpa_pairwise;
int wpa_group;
diff --git a/hostapd/hostapd.conf b/hostapd/hostapd.conf
index eaf0d4e..9732573 100644
--- a/hostapd/hostapd.conf
+++ b/hostapd/hostapd.conf
@@ -755,13 +755,15 @@ own_ip_addr=127.0.0.1
# 2 = required
#ieee80211w=0
-# Association ping timeout (in TU = 1.024 ms; for MFP)
-# dot11AssociationPingResponseTimeout, 1...4294967295
-#assoc_ping_timeout=1000
-
-# Maximum number of association pings
-# dot11AssociationMaximumPingAttempts , 1...255
-#assoc_ping_attempts=3
+# Association SA Query maximum timeout (in TU = 1.024 ms; for MFP)
+# (maximum time to wait for a SA Query response)
+# dot11AssociationSAQueryMaximumTimeout, 1...4294967295
+#assoc_sa_query_max_timeout=1000
+
+# Association SA Query retry timeout (in TU = 1.024 ms; for MFP)
+# (time between two subsequent SA Query requests)
+# dot11AssociationSAQueryRetryTimeout, 1...4294967295
+#assoc_sa_query_retry_timeout=201
# okc: Opportunistic Key Caching (aka Proactive Key Caching)
diff --git a/hostapd/ieee802_11.c b/hostapd/ieee802_11.c
index b80e6c3..c8f6ed8 100644
--- a/hostapd/ieee802_11.c
+++ b/hostapd/ieee802_11.c
@@ -298,12 +298,20 @@ static u8 * hostapd_eid_assoc_comeback_time(struct hostapd_data *hapd,
struct sta_info *sta, u8 *eid)
{
u8 *pos = eid;
- u32 timeout;
+ u32 timeout, tu;
+ struct os_time now, passed;
*pos++ = WLAN_EID_ASSOC_COMEBACK_TIME;
*pos++ = 4;
- timeout = (hapd->conf->assoc_ping_attempts - sta->sa_query_count + 1) *
- hapd->conf->assoc_ping_timeout;
+ os_get_time(&now);
+ os_time_sub(&now, &sta->sa_query_start, &passed);
+ tu = (passed.sec * 1000000 + passed.usec) / 1024;
+ if (hapd->conf->assoc_sa_query_max_timeout > tu)
+ timeout = hapd->conf->assoc_sa_query_max_timeout - tu;
+ else
+ timeout = 0;
+ if (timeout < hapd->conf->assoc_sa_query_max_timeout)
+ timeout++; /* add some extra time for local timers */
WPA_PUT_LE32(pos, timeout);
pos += 4;
@@ -893,6 +901,9 @@ static void handle_assoc(struct hostapd_data *hapd,
if (resp != WLAN_STATUS_SUCCESS)
goto fail;
#ifdef CONFIG_IEEE80211W
+ if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out &&
+ sta->sa_query_count > 0)
+ ap_check_sa_query_timeout(hapd, sta);
if ((sta->flags & WLAN_STA_MFP) && !sta->sa_query_timed_out) {
/*
* STA has already been associated with MFP and SA
diff --git a/hostapd/sta_info.c b/hostapd/sta_info.c
index 3beda7f..df11901 100644
--- a/hostapd/sta_info.c
+++ b/hostapd/sta_info.c
@@ -637,44 +637,65 @@ static void ieee802_11_send_sa_query_req(struct hostapd_data *hapd,
}
-static void ap_sa_query_timer(void *eloop_ctx, void *timeout_ctx)
+int ap_check_sa_query_timeout(struct hostapd_data *hapd, struct sta_info *sta)
{
- struct hostapd_data *hapd = eloop_ctx;
- struct sta_info *sta = timeout_ctx;
- unsigned int timeout, sec, usec;
- u8 *trans_id, *nbuf;
-
- if (sta->sa_query_count >= hapd->conf->assoc_ping_attempts) {
- hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
+ u32 tu;
+ struct os_time now, passed;
+ os_get_time(&now);
+ os_time_sub(&now, &sta->sa_query_start, &passed);
+ tu = (passed.sec * 1000000 + passed.usec) / 1024;
+ if (hapd->conf->assoc_sa_query_max_timeout < tu) {
+ hostapd_logger(hapd, sta->addr,
+ HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_DEBUG,
"association SA Query timed out");
sta->sa_query_timed_out = 1;
os_free(sta->sa_query_trans_id);
sta->sa_query_trans_id = NULL;
sta->sa_query_count = 0;
- return;
+ eloop_cancel_timeout(ap_sa_query_timer, hapd, sta);
+ return 1;
}
+ return 0;
+}
+
+
+static void ap_sa_query_timer(void *eloop_ctx, void *timeout_ctx)
+{
+ struct hostapd_data *hapd = eloop_ctx;
+ struct sta_info *sta = timeout_ctx;
+ unsigned int timeout, sec, usec;
+ u8 *trans_id, *nbuf;
+
+ if (sta->sa_query_count > 0 &&
+ ap_check_sa_query_timeout(hapd, sta))
+ return;
+
nbuf = os_realloc(sta->sa_query_trans_id,
(sta->sa_query_count + 1) * WLAN_SA_QUERY_TR_ID_LEN);
if (nbuf == NULL)
return;
+ if (sta->sa_query_count == 0) {
+ /* Starting a new SA Query procedure */
+ os_get_time(&sta->sa_query_start);
+ }
trans_id = nbuf + sta->sa_query_count * WLAN_SA_QUERY_TR_ID_LEN;
sta->sa_query_trans_id = nbuf;
sta->sa_query_count++;
os_get_random(trans_id, WLAN_SA_QUERY_TR_ID_LEN);
+ timeout = hapd->conf->assoc_sa_query_retry_timeout;
+ sec = ((timeout / 1000) * 1024) / 1000;
+ usec = (timeout % 1000) * 1024;
+ eloop_register_timeout(sec, usec, ap_sa_query_timer, hapd, sta);
+
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
HOSTAPD_LEVEL_DEBUG,
"association SA Query attempt %d", sta->sa_query_count);
ieee802_11_send_sa_query_req(hapd, sta->addr, trans_id);
-
- timeout = hapd->conf->assoc_ping_timeout;
- sec = ((timeout / 1000) * 1024) / 1000;
- usec = (timeout % 1000) * 1024;
- eloop_register_timeout(sec, usec, ap_sa_query_timer, hapd, sta);
}
diff --git a/hostapd/sta_info.h b/hostapd/sta_info.h
index 024cf33..e835970 100644
--- a/hostapd/sta_info.h
+++ b/hostapd/sta_info.h
@@ -38,5 +38,6 @@ int ap_sta_bind_vlan(struct hostapd_data *hapd, struct sta_info *sta,
int old_vlanid);
void ap_sta_start_sa_query(struct hostapd_data *hapd, struct sta_info *sta);
void ap_sta_stop_sa_query(struct hostapd_data *hapd, struct sta_info *sta);
+int ap_check_sa_query_timeout(struct hostapd_data *hapd, struct sta_info *sta);
#endif /* STA_INFO_H */