From e7d20342b54121b69e39944a1fe4bdafb3e8a76a Mon Sep 17 00:00:00 2001 From: Hu Wang Date: Fri, 24 Apr 2015 15:53:08 +0300 Subject: [PATCH] WPS: Enforce five second minimum time before AP iteration Previously, wpa_supplicant was using number of scan iterations (WPS_PIN_SCAN_IGNORE_SEL_REG = 3) to give some time for finding a WPS AP with Selected Registrar TRUE before starting to iterate through all WPS APs. While this works fine in most cases, some drivers may return the initial three scan results so quickly that the total amount of time is only couple of seconds in case none of the APs are initially advertising Selected Registrar TRUE. To give some more time for APs (WPS Registrars) to become ready, add an additional constraint on the iteration based on time (WPS_PIN_TIME_IGNORE_SEL_REG = 5 seconds). Signed-off-by: Jouni Malinen --- wpa_supplicant/wpa_supplicant_i.h | 1 + wpa_supplicant/wps_supplicant.c | 21 ++++++++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 1b9753c00..0e36b4652 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -639,6 +639,7 @@ struct wpa_supplicant { int wps_success; /* WPS success event received */ struct wps_er *wps_er; unsigned int wps_run; + struct os_reltime wps_pin_start_time; int blacklist_cleared; struct wpabuf *pending_eapol_rx; diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c index 52594a10c..e34573b66 100644 --- a/wpa_supplicant/wps_supplicant.c +++ b/wpa_supplicant/wps_supplicant.c @@ -39,6 +39,14 @@ #define WPS_PIN_SCAN_IGNORE_SEL_REG 3 #endif /* WPS_PIN_SCAN_IGNORE_SEL_REG */ +/* + * The minimum time in seconds before trying to associate to a WPS PIN AP that + * does not have Selected Registrar TRUE. + */ +#ifndef WPS_PIN_TIME_IGNORE_SEL_REG +#define WPS_PIN_TIME_IGNORE_SEL_REG 5 +#endif /* WPS_PIN_TIME_IGNORE_SEL_REG */ + static void wpas_wps_timeout(void *eloop_ctx, void *timeout_ctx); static void wpas_clear_wps(struct wpa_supplicant *wpa_s); @@ -1216,6 +1224,7 @@ static int wpas_wps_start_dev_pw(struct wpa_supplicant *wpa_s, int wpas_wps_start_pin(struct wpa_supplicant *wpa_s, const u8 *bssid, const char *pin, int p2p_group, u16 dev_pw_id) { + os_get_reltime(&wpa_s->wps_pin_start_time); return wpas_wps_start_dev_pw(wpa_s, NULL, bssid, pin, p2p_group, dev_pw_id, NULL, NULL, 0, 0); } @@ -1609,9 +1618,15 @@ int wpas_wps_ssid_bss_match(struct wpa_supplicant *wpa_s, * external Registrar. */ if (!wps_is_addr_authorized(wps_ie, wpa_s->own_addr, 1)) { - if (wpa_s->scan_runs < WPS_PIN_SCAN_IGNORE_SEL_REG) { - wpa_printf(MSG_DEBUG, " skip - WPS AP " - "without active PIN Registrar"); + struct os_reltime age; + + os_reltime_age(&wpa_s->wps_pin_start_time, &age); + + if (wpa_s->scan_runs < WPS_PIN_SCAN_IGNORE_SEL_REG || + age.sec < WPS_PIN_TIME_IGNORE_SEL_REG) { + wpa_printf(MSG_DEBUG, + " skip - WPS AP without active PIN Registrar (scan_runs=%d age=%d)", + wpa_s->scan_runs, (int) age.sec); wpabuf_free(wps_ie); return 0; }