aboutsummaryrefslogtreecommitdiffstats
path: root/src/p2p/p2p_go_neg.c
diff options
context:
space:
mode:
authorJouni Malinen <j@w1.fi>2012-06-09 18:31:24 +0300
committerJouni Malinen <j@w1.fi>2012-06-09 18:31:24 +0300
commit198f82a1e3f78fd478e879185c43965c25840e0d (patch)
tree81460feae75da7d3953b19c18fb906b7474070f4 /src/p2p/p2p_go_neg.c
parenta1d2ab329e839838a623e1dd8c9fc77e97cd6355 (diff)
downloadexternal_wpa_supplicant_8_ti-198f82a1e3f78fd478e879185c43965c25840e0d.zip
external_wpa_supplicant_8_ti-198f82a1e3f78fd478e879185c43965c25840e0d.tar.gz
external_wpa_supplicant_8_ti-198f82a1e3f78fd478e879185c43965c25840e0d.tar.bz2
P2P: Ignore unexpected GO Neg Resp is we have sent Resp
There is a race condition in GO Negotiation Request frame sending and processing that may end up with both devices sending GO Negotiation Response. This response frame was previously accepted even if a response had already been sent. This could result in two GO Negotiation Confirm frames being exchanged and consequently, with two separate GO Negotiations completing concurrently. These negotiations could result in getting mismatching parameters (e.g., both device could believe it was the GO). Fix this by ignoring GO Negotiation Response from the peer if twe have already sent a GO Negotiation Response frame and we have the higher P2P Device Address. This is similar to the rule used to determine whether to reply to GO Negotiation Request frame when Request was already sent, i.e., the same direction of GO Negotiation is maintained here to enforce that only the negotiation initiated by the device with smaller P2P Device Address is completed. Signed-hostap: Jouni Malinen <j@w1.fi> intended-for: hostap-1
Diffstat (limited to 'src/p2p/p2p_go_neg.c')
-rw-r--r--src/p2p/p2p_go_neg.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c
index cff1f45..766dd6d 100644
--- a/src/p2p/p2p_go_neg.c
+++ b/src/p2p/p2p_go_neg.c
@@ -672,6 +672,17 @@ fail:
if (status == P2P_SC_SUCCESS) {
p2p->pending_action_state = P2P_PENDING_GO_NEG_RESPONSE;
dev->flags |= P2P_DEV_WAIT_GO_NEG_CONFIRM;
+ if (os_memcmp(sa, p2p->cfg->dev_addr, ETH_ALEN) < 0) {
+ /*
+ * Peer has smaller address, so the GO Negotiation
+ * Response from us is expected to complete
+ * negotiation. Ignore a GO Negotiation Response from
+ * the peer if it happens to be received after this
+ * point due to a race condition in GO Negotiation
+ * Request transmission and processing.
+ */
+ dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE;
+ }
} else
p2p->pending_action_state =
P2P_PENDING_GO_NEG_RESPONSE_FAILURE;