if (sta->sae->sync > hapd->conf->sae_sync) {
sae_set_state(sta, SAE_NOTHING, "Sync > dot11RSNASAESync");
sta->sae->sync = 0;
+ if (sta->sae->tmp) {
+ /* Disable this SAE instance for 10 seconds to avoid
+ * unnecessary flood of multiple SAE commits in
+ * unexpected mesh cases. */
+ if (os_get_reltime(&sta->sae->tmp->disabled_until) == 0)
+ sta->sae->tmp->disabled_until.sec += 10;
+ }
return -1;
}
return 0;
}
+static bool sae_proto_instance_disabled(struct sta_info *sta)
+{
+ struct sae_temporary_data *tmp;
+
+ if (!sta->sae)
+ return false;
+ tmp = sta->sae->tmp;
+ if (!tmp)
+ return false;
+
+ if (os_reltime_initialized(&tmp->disabled_until)) {
+ struct os_reltime now;
+
+ os_get_reltime(&now);
+ if (os_reltime_before(&now, &tmp->disabled_until))
+ return true;
+ }
+
+ return false;
+}
+
+
static void auth_sae_retransmit_timer(void *eloop_ctx, void *eloop_data)
{
struct hostapd_data *hapd = eloop_ctx;
wpa_printf(MSG_DEBUG, "SAE: Peer " MACSTR " state=%s auth_trans=%u",
MAC2STR(sta->addr), sae_state_txt(sta->sae->state),
auth_transaction);
+
+ if (auth_transaction == 1 && sae_proto_instance_disabled(sta)) {
+ wpa_printf(MSG_DEBUG,
+ "SAE: Protocol instance temporarily disabled - discard received SAE commit");
+ return WLAN_STATUS_SUCCESS;
+ }
+
switch (sta->sae->state) {
case SAE_NOTHING:
if (auth_transaction == 1) {
if (!sae_status_success(hapd, status_code))
goto remove_sta;
+ if (sae_proto_instance_disabled(sta)) {
+ wpa_printf(MSG_DEBUG,
+ "SAE: Protocol instance temporarily disabled - discard received SAE commit");
+ return;
+ }
+
if (!(hapd->conf->mesh & MESH_ENABLED) &&
sta->sae->state == SAE_COMMITTED) {
/* This is needed in the infrastructure BSS case to