diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 36ae5f20a..2fa338100 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -3771,6 +3771,81 @@ static void wpa_supplicant_event_port_authorized(struct wpa_supplicant *wpa_s) } +static unsigned int wpas_event_cac_ms(const struct wpa_supplicant *wpa_s, + int freq) +{ + size_t i; + int j; + + for (i = 0; i < wpa_s->hw.num_modes; i++) { + const struct hostapd_hw_modes *mode = &wpa_s->hw.modes[i]; + + for (j = 0; j < mode->num_channels; j++) { + const struct hostapd_channel_data *chan; + + chan = &mode->channels[j]; + if (chan->freq == freq) + return chan->dfs_cac_ms; + } + } + + return 0; +} + + +static void wpas_event_dfs_cac_started(struct wpa_supplicant *wpa_s, + struct dfs_event *radar) +{ +#if defined(NEED_AP_MLME) && defined(CONFIG_AP) + if (wpa_s->ap_iface) { + wpas_ap_event_dfs_cac_started(wpa_s, radar); + } else +#endif /* NEED_AP_MLME && CONFIG_AP */ + { + unsigned int cac_time = wpas_event_cac_ms(wpa_s, radar->freq); + + cac_time /= 1000; /* convert from ms to sec */ + if (!cac_time) + cac_time = 10 * 60; /* max timeout: 10 minutes */ + + /* Restart auth timeout: CAC time added to initial timeout */ + wpas_auth_timeout_restart(wpa_s, cac_time); + } +} + + +static void wpas_event_dfs_cac_finished(struct wpa_supplicant *wpa_s, + struct dfs_event *radar) +{ +#if defined(NEED_AP_MLME) && defined(CONFIG_AP) + if (wpa_s->ap_iface) { + wpas_ap_event_dfs_cac_finished(wpa_s, radar); + } else +#endif /* NEED_AP_MLME && CONFIG_AP */ + { + /* Restart auth timeout with original value after CAC is + * finished */ + wpas_auth_timeout_restart(wpa_s, 0); + } +} + + +static void wpas_event_dfs_cac_aborted(struct wpa_supplicant *wpa_s, + struct dfs_event *radar) +{ +#if defined(NEED_AP_MLME) && defined(CONFIG_AP) + if (wpa_s->ap_iface) { + wpas_ap_event_dfs_cac_aborted(wpa_s, radar); + } else +#endif /* NEED_AP_MLME && CONFIG_AP */ + { + /* Restart auth timeout with original value after CAC is + * aborted */ + wpas_auth_timeout_restart(wpa_s, 0); + } +} + + static void wpa_supplicant_event_assoc_auth(struct wpa_supplicant *wpa_s, union wpa_event_data *data) { @@ -4186,18 +4261,6 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, wpas_ap_event_dfs_radar_detected(wpa_s, &data->dfs_event); break; - case EVENT_DFS_CAC_STARTED: - if (data) - wpas_ap_event_dfs_cac_started(wpa_s, &data->dfs_event); - break; - case EVENT_DFS_CAC_FINISHED: - if (data) - wpas_ap_event_dfs_cac_finished(wpa_s, &data->dfs_event); - break; - case EVENT_DFS_CAC_ABORTED: - if (data) - wpas_ap_event_dfs_cac_aborted(wpa_s, &data->dfs_event); - break; case EVENT_DFS_NOP_FINISHED: if (data) wpas_ap_event_dfs_cac_nop_finished(wpa_s, @@ -4205,6 +4268,18 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, break; #endif /* NEED_AP_MLME */ #endif /* CONFIG_AP */ + case EVENT_DFS_CAC_STARTED: + if (data) + wpas_event_dfs_cac_started(wpa_s, &data->dfs_event); + break; + case EVENT_DFS_CAC_FINISHED: + if (data) + wpas_event_dfs_cac_finished(wpa_s, &data->dfs_event); + break; + case EVENT_DFS_CAC_ABORTED: + if (data) + wpas_event_dfs_cac_aborted(wpa_s, &data->dfs_event); + break; case EVENT_RX_MGMT: { u16 fc, stype; const struct ieee80211_mgmt *mgmt; diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 9ee099613..9e4e1efec 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -243,10 +243,30 @@ void wpa_supplicant_req_auth_timeout(struct wpa_supplicant *wpa_s, wpa_dbg(wpa_s, MSG_DEBUG, "Setting authentication timeout: %d sec " "%d usec", sec, usec); eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL); + wpa_s->last_auth_timeout_sec = sec; eloop_register_timeout(sec, usec, wpa_supplicant_timeout, wpa_s, NULL); } +/* + * wpas_auth_timeout_restart - Restart and change timeout for authentication + * @wpa_s: Pointer to wpa_supplicant data + * @sec_diff: difference in seconds applied to original timeout value + */ +void wpas_auth_timeout_restart(struct wpa_supplicant *wpa_s, int sec_diff) +{ + int new_sec = wpa_s->last_auth_timeout_sec + sec_diff; + + if (eloop_is_timeout_registered(wpa_supplicant_timeout, wpa_s, NULL)) { + wpa_dbg(wpa_s, MSG_DEBUG, + "Authentication timeout restart: %d sec", new_sec); + eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL); + eloop_register_timeout(new_sec, 0, wpa_supplicant_timeout, + wpa_s, NULL); + } +} + + /** * wpa_supplicant_cancel_auth_timeout - Cancel authentication timeout * @wpa_s: Pointer to wpa_supplicant data diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index d5bfa7ddf..4d18177fb 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -1182,6 +1182,8 @@ struct wpa_supplicant { /* RIC elements for FT protocol */ struct wpabuf *ric_ies; + int last_auth_timeout_sec; + #ifdef CONFIG_DPP struct dl_list dpp_bootstrap; /* struct dpp_bootstrap_info */ struct dl_list dpp_configurator; /* struct dpp_configurator */ @@ -1255,6 +1257,7 @@ void wpa_supplicant_initiate_eapol(struct wpa_supplicant *wpa_s); void wpa_clear_keys(struct wpa_supplicant *wpa_s, const u8 *addr); void wpa_supplicant_req_auth_timeout(struct wpa_supplicant *wpa_s, int sec, int usec); +void wpas_auth_timeout_restart(struct wpa_supplicant *wpa_s, int sec_diff); void wpa_supplicant_reinit_autoscan(struct wpa_supplicant *wpa_s); void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s, enum wpa_states state);