From c28059091aad21d13396509cdf8bde50b9aa147a Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 1 Mar 2015 15:54:24 +0200 Subject: [PATCH] Do not add blacklist entries based on normal disconnect request cases There are number of cases where wpa_supplicant requests the current connection to be disconnected before starting a new operation. Such cases do not really indicate that there was an error in connecting or a disconnection initiated by the AP, so do not add a temporary blacklist entry in such sequences. Signed-off-by: Jouni Malinen --- wpa_supplicant/ctrl_iface.c | 4 ++++ wpa_supplicant/events.c | 3 +++ wpa_supplicant/interworking.c | 2 ++ wpa_supplicant/wpa_supplicant.c | 16 ++++++++++++---- wpa_supplicant/wpa_supplicant_i.h | 1 + wpa_supplicant/wps_supplicant.c | 8 +++++++- 6 files changed, 29 insertions(+), 5 deletions(-) diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index e840b352d..7c230dcab 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -209,6 +209,7 @@ static int set_disallow_aps(struct wpa_supplicant *wpa_s, char *val) wpa_s->sme.prev_bssid_set = 0; #endif /* CONFIG_SME */ wpa_s->reassociate = 1; + wpa_s->own_disconnect_req = 1; wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); wpa_supplicant_req_scan(wpa_s, 0, 0); @@ -2835,6 +2836,7 @@ static int wpa_supplicant_ctrl_iface_remove_network( #endif /* CONFIG_SME */ wpa_sm_set_config(wpa_s->wpa, NULL); eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); + wpa_s->own_disconnect_req = 1; wpa_supplicant_deauthenticate( wpa_s, WLAN_REASON_DEAUTH_LEAVING); } @@ -2881,6 +2883,7 @@ static int wpa_supplicant_ctrl_iface_remove_network( wpa_sm_set_config(wpa_s->wpa, NULL); eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); + wpa_s->own_disconnect_req = 1; wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); } @@ -6628,6 +6631,7 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s) wpa_supplicant_stop_countermeasures(wpa_s, NULL); wpa_s->no_keep_alive = 0; + wpa_s->own_disconnect_req = 0; os_free(wpa_s->disallow_aps_bssid); wpa_s->disallow_aps_bssid = NULL; diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 1f9fc97a9..9de8f7abf 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -2671,6 +2671,9 @@ static void wpas_event_disconnect(struct wpa_supplicant *wpa_s, const u8 *addr, } #endif /* CONFIG_AP */ + if (!locally_generated) + wpa_s->own_disconnect_req = 0; + wpa_supplicant_event_disassoc(wpa_s, reason_code, locally_generated); if (((reason_code == WLAN_REASON_IEEE_802_1X_AUTH_FAILED || diff --git a/wpa_supplicant/interworking.c b/wpa_supplicant/interworking.c index 90b299153..ec60f9d55 100644 --- a/wpa_supplicant/interworking.c +++ b/wpa_supplicant/interworking.c @@ -77,6 +77,7 @@ static void interworking_reconnect(struct wpa_supplicant *wpa_s) if (wpa_s->wpa_state >= WPA_AUTHENTICATING) { wpa_supplicant_cancel_sched_scan(wpa_s); + wpa_s->own_disconnect_req = 1; wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); } @@ -915,6 +916,7 @@ static void remove_duplicate_network(struct wpa_supplicant *wpa_s, if (ssid == wpa_s->current_ssid) { wpa_sm_set_config(wpa_s->wpa, NULL); eapol_sm_notify_config(wpa_s->eapol, NULL, NULL); + wpa_s->own_disconnect_req = 1; wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); } diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index e96199ea2..15f856935 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -870,6 +870,7 @@ int wpa_supplicant_reload_configuration(struct wpa_supplicant *wpa_s) eapol_sm_invalidate_cached_session(wpa_s->eapol); if (wpa_s->current_ssid) { + wpa_s->own_disconnect_req = 1; wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); } @@ -2585,6 +2586,7 @@ void wpa_supplicant_select_network(struct wpa_supplicant *wpa_s, int disconnected = 0; if (ssid && ssid != wpa_s->current_ssid && wpa_s->current_ssid) { + wpa_s->own_disconnect_req = 1; wpa_supplicant_deauthenticate( wpa_s, WLAN_REASON_DEAUTH_LEAVING); disconnected = 1; @@ -4792,11 +4794,17 @@ void wpas_connection_failed(struct wpa_supplicant *wpa_s, const u8 *bssid) */ eloop_cancel_timeout(wpa_supplicant_timeout, wpa_s, NULL); + /* + * There is no point in blacklisting the AP if this event is + * generated based on local request to disconnect. + */ + if (wpa_s->own_disconnect_req) { + wpa_s->own_disconnect_req = 0; + wpa_dbg(wpa_s, MSG_DEBUG, + "Ignore connection failure due to local request to disconnect"); + return; + } if (wpa_s->disconnected) { - /* - * There is no point in blacklisting the AP if this event is - * generated based on local request to disconnect. - */ wpa_dbg(wpa_s, MSG_DEBUG, "Ignore connection failure " "indication since interface has been put into " "disconnected state"); diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 7949a0186..0c0ee84a5 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -915,6 +915,7 @@ struct wpa_supplicant { unsigned int ext_eapol_frame_io:1; unsigned int wmm_ac_supported:1; unsigned int ext_work_in_progress:1; + unsigned int own_disconnect_req:1; #define MAC_ADDR_RAND_SCAN BIT(0) #define MAC_ADDR_RAND_SCHED_SCAN BIT(1) diff --git a/wpa_supplicant/wps_supplicant.c b/wpa_supplicant/wps_supplicant.c index b1266c625..eabe98654 100644 --- a/wpa_supplicant/wps_supplicant.c +++ b/wpa_supplicant/wps_supplicant.c @@ -113,6 +113,7 @@ int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s) wpa_printf(MSG_DEBUG, "WPS: Network configuration replaced - " "try to associate with the received credential " "(freq=%u)", freq); + wpa_s->own_disconnect_req = 1; wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); if (disabled) { @@ -160,6 +161,7 @@ int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s) wpa_printf(MSG_DEBUG, "WPS: Registration completed - waiting " "for external credential processing"); wpas_clear_wps(wpa_s); + wpa_s->own_disconnect_req = 1; wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); return 1; @@ -913,6 +915,7 @@ static void wpas_clear_wps(struct wpa_supplicant *wpa_s) while (ssid) { if (ssid->key_mgmt & WPA_KEY_MGMT_WPS) { if (ssid == wpa_s->current_ssid) { + wpa_s->own_disconnect_req = 1; wpa_supplicant_deauthenticate( wpa_s, WLAN_REASON_DEAUTH_LEAVING); } @@ -1022,9 +1025,11 @@ static void wpas_wps_temp_disable(struct wpa_supplicant *wpa_s, { struct wpa_ssid *ssid; - if (wpa_s->current_ssid) + if (wpa_s->current_ssid) { + wpa_s->own_disconnect_req = 1; wpa_supplicant_deauthenticate( wpa_s, WLAN_REASON_DEAUTH_LEAVING); + } /* Mark all other networks disabled and trigger reassociation */ ssid = wpa_s->conf->ssid; @@ -1234,6 +1239,7 @@ int wpas_wps_cancel(struct wpa_supplicant *wpa_s) } else if (wpa_s->wpa_state >= WPA_ASSOCIATED) { wpa_printf(MSG_DEBUG, "WPS: Cancel operation - " "deauthenticate"); + wpa_s->own_disconnect_req = 1; wpa_supplicant_deauthenticate(wpa_s, WLAN_REASON_DEAUTH_LEAVING); wpas_clear_wps(wpa_s);