P2P: Reject group formation on WPS provisioning failure

There is no need to wait for the 15 second group formation timeout to
clear the state if WPS failure is detected during P2P group formation.
Allow the WPS exchange steps (WSC_NACK and EAP-Failure) to be completed
and remove the group to get rid of the extra wait.

Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2014-01-06 17:56:50 +02:00
parent 6fc61e180e
commit 95fb2db242
4 changed files with 53 additions and 3 deletions

View file

@ -1497,6 +1497,17 @@ void wpas_p2p_group_formation_failed(struct wpa_supplicant *wpa_s)
}
static void wpas_p2p_grpform_fail_after_wps(struct wpa_supplicant *wpa_s)
{
wpa_printf(MSG_DEBUG, "P2P: Reject group formation due to WPS provisioning failure");
eloop_cancel_timeout(wpas_p2p_group_formation_timeout,
wpa_s->parent, NULL);
eloop_register_timeout(0, 0, wpas_p2p_group_formation_timeout,
wpa_s->parent, NULL);
wpa_s->global->p2p_fail_on_wps_complete = 0;
}
void wpas_p2p_ap_setup_failed(struct wpa_supplicant *wpa_s)
{
if (wpa_s->global->p2p_group_formation != wpa_s)
@ -4496,6 +4507,8 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
os_free(wpa_s->global->add_psk);
wpa_s->global->add_psk = NULL;
wpa_s->global->p2p_fail_on_wps_complete = 0;
if (go_intent < 0)
go_intent = wpa_s->conf->p2p_go_intent;
@ -5123,9 +5136,14 @@ static void wpas_p2p_idle_update(void *ctx, int idle)
if (!wpa_s->ap_iface)
return;
wpa_printf(MSG_DEBUG, "P2P: GO - group %sidle", idle ? "" : "not ");
if (idle)
if (idle) {
if (wpa_s->global->p2p_fail_on_wps_complete &&
wpa_s->p2p_in_provisioning) {
wpas_p2p_grpform_fail_after_wps(wpa_s);
return;
}
wpas_p2p_set_group_idle_timeout(wpa_s);
else
} else
eloop_cancel_timeout(wpas_p2p_group_idle_timeout, wpa_s, NULL);
}
@ -5244,6 +5262,31 @@ void wpas_p2p_wps_failed(struct wpa_supplicant *wpa_s,
}
wpas_notify_p2p_wps_failed(wpa_s, fail);
if (wpa_s == wpa_s->global->p2p_group_formation) {
/*
* Allow some time for the failed WPS negotiation exchange to
* complete, but remove the group since group formation cannot
* succeed after provisioning failure.
*/
wpa_printf(MSG_DEBUG, "P2P: WPS step failed during group formation - reject connection from timeout");
wpa_s->global->p2p_fail_on_wps_complete = 1;
eloop_deplete_timeout(0, 50000,
wpas_p2p_group_formation_timeout,
wpa_s->parent, NULL);
}
}
int wpas_p2p_wps_eapol_cb(struct wpa_supplicant *wpa_s)
{
if (!wpa_s->global->p2p_fail_on_wps_complete ||
!wpa_s->p2p_in_provisioning)
return 0;
wpas_p2p_grpform_fail_after_wps(wpa_s);
return 1;
}

View file

@ -128,6 +128,7 @@ int wpas_p2p_unauthorize(struct wpa_supplicant *wpa_s, const char *addr);
int wpas_p2p_disconnect(struct wpa_supplicant *wpa_s);
void wpas_p2p_wps_failed(struct wpa_supplicant *wpa_s,
struct wps_event_fail *fail);
int wpas_p2p_wps_eapol_cb(struct wpa_supplicant *wpa_s);
int wpas_p2p_in_progress(struct wpa_supplicant *wpa_s);
void wpas_p2p_network_removed(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid);

View file

@ -258,6 +258,7 @@ struct wpa_global {
WPA_CONC_PREF_P2P
} conc_pref;
unsigned int p2p_per_sta_psk:1;
unsigned int p2p_fail_on_wps_complete:1;
#ifdef CONFIG_WIFI_DISPLAY
int wifi_display;

View file

@ -1,6 +1,6 @@
/*
* wpa_supplicant / WPS integration
* Copyright (c) 2008-2013, Jouni Malinen <j@w1.fi>
* Copyright (c) 2008-2014, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
@ -54,6 +54,11 @@ static void wpas_wps_clear_ap_info(struct wpa_supplicant *wpa_s)
int wpas_wps_eapol_cb(struct wpa_supplicant *wpa_s)
{
#ifdef CONFIG_P2P
if (wpas_p2p_wps_eapol_cb(wpa_s) > 0)
return 1;
#endif /* CONFIG_P2P */
if (!wpa_s->wps_success &&
wpa_s->current_ssid &&
eap_is_wps_pin_enrollee(&wpa_s->current_ssid->eap)) {