wpas_p2p_group_formation_timeout and p2p_group_formation

Jouni Malinen j at w1.fi
Mon Nov 30 11:47:34 PST 2015

On Mon, Nov 30, 2015 at 11:54:39AM +0100, Michael Olbrich wrote:
> I am experiencing some problems with P2P connections as client. From what I
> can tell what happens is this:
> in wpas_p2p_wps_success():
> [...]
> wpa_s->p2p_go_group_formation_completed = 1;
> [...]
> eloop_register_timeout(P2P_MAX_INITIAL_CONN_WAIT, 0,
> 		       wpas_p2p_group_formation_timeout,
> 		       wpa_s->parent, NULL);
> [...]
> wpas_group_formation_completed(wpa_s, 1, 0);
> and then in wpas_group_formation_completed():
> [...]
> wpa_s->global->p2p_group_formation = NULL;
> [...]

This does not look ideal.. I was able to reproduce this with hwsim test
scripts. The GO case works fine since it postpones marking the group
completed until the first client connects for an actual data association
while the P2P Client role fails because of not finding the group.

> This causes two problems:
> 1. p2p_ext_listen_timeout() calls p2p_listen() because is_p2p_in_progress()
> returns 0. At least on my hardware (Intel Corporation Wireless 7260) this
> breaks connecting if the p2p_listen() happens before the group is really
> fully ready.

This could be fixed in other ways, but since
wpa_s->global->p2p_group_formation is going to be needed anyway, that
can take care of the issue here.. That said, even if there were an
extended listen operation with reasonably short duration, that should
work during connection operations.

> 2. If the peer cancels the connection at this point and
> wpas_p2p_group_formation_timeout() is called, then
> wpas_group_formation_completed() uses the wrong wpa_s (the management
> interface) because "wpa_s->global->p2p_group_formation" is no longer set.

This is not good.. That pointer needs to be maintained as long as there
is possibility of group formation timeout getting hit.

> I 'fixed' this by not clearing p2p_group_formation in
> wpas_group_formation_completed() (see diff below). But I don't think this
> is the correct solution. Maybe p2p_go_group_formation_completed needs to be
> handled differently?

In practice, that clearing of p2p_group_formation may happen due to
wpa_s->p2p_go_group_formation_completed being 0 here in the future, but
anyway, that is not the only change that's needed to handle this
properly. I think the following changes should handle this. At least
they fixed the hwsim test script I wrote for reproducing this.

P2P: Complete group formation on client data connection

This was already the case in the GO role where the first client
connection is waited before marking
wpa_s->p2p_go_group_formation_completed = 1 and clearing
wpa_s->global->p2p_group_formation. However, in the P2P Client role,
that was done already at the completion of the WPS exchange. This can be
problematic since group formation timeout may still try to clear the
group and with wpa_s->global->p2p_group_formation == NULL, the correct
group interface may not be found.

Fix this by postponing clearing of wpa_s->global->p2p_group_formation on
the P2P Client side until the data connection has been completed and
group is declared started.

diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index a60ae6e..077c5fe 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -6340,6 +6340,8 @@ void wpas_p2p_wps_success(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
 		eloop_register_timeout(P2P_MAX_INITIAL_CONN_WAIT, 0,
 				       wpa_s->parent, NULL);
+		/* Complete group formation on successful data connection. */
+		wpa_s->p2p_go_group_formation_completed = 0;
 	} else if (ssid) {
 		 * Use a separate timeout for initial data connection to
@@ -6890,6 +6892,15 @@ void wpas_p2p_completed(struct wpa_supplicant *wpa_s)
 	wpa_s->show_group_started = 0;
+	if (!wpa_s->p2p_go_group_formation_completed &&
+	    wpa_s->global->p2p_group_formation == wpa_s) {
+		wpa_dbg(wpa_s, MSG_DEBUG,
+			"P2P: Marking group formation completed on client on data connection");
+		wpa_s->p2p_go_group_formation_completed = 1;
+		wpa_s->global->p2p_group_formation = NULL;
+		wpa_s->p2p_in_provisioning = 0;
+		wpa_s->p2p_in_invitation = 0;
+	}
 	os_memset(go_dev_addr, 0, ETH_ALEN);
 	if (ssid->bssid_set)

Jouni Malinen                                            PGP id EFC895FA

More information about the Hostap mailing list