]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Address race condition with GO Negotiation Request TX status
authorNeeraj Kumar Garg <neerajkg@broadcom.com>
Sat, 9 Jun 2012 15:03:47 +0000 (18:03 +0300)
committerJouni Malinen <j@w1.fi>
Sat, 9 Jun 2012 15:03:47 +0000 (18:03 +0300)
If both peers initiate GO Negotiation at about the same time, it is
possible for the GO Negotiation Request frame from the peer to be
received between the local attempt to send the GO Negotiation Request
and TX status event for that. This could result in both devices sending
GO Negotiation Response frames even though one of them should have
skipped this based which device uses a higher MAC address.

Resolve this race by incrementing go_neg_req_sent when p2p_send_action()
returns success instead of doing this from the TX status callback. If
the frame is not acknowledged, go_neg_req_sent is cleared in TX status
handler.

Signed-off-by: Neeraj Garg <neerajkg@broadcom.com>
src/p2p/p2p.c
src/p2p/p2p_go_neg.c

index 716454c187f262b117ef7b444132594737054513..7046f7b8d1409707838dd141cda85482ed1f0aa4 100644 (file)
@@ -2704,11 +2704,13 @@ static void p2p_go_neg_req_cb(struct p2p_data *p2p, int success)
        }
 
        if (success) {
-               dev->go_neg_req_sent++;
                if (dev->flags & P2P_DEV_USER_REJECTED) {
                        p2p_set_state(p2p, P2P_IDLE);
                        return;
                }
+       } else if (dev->go_neg_req_sent) {
+               /* Cancel the increment from p2p_connect_send() on failure */
+               dev->go_neg_req_sent--;
        }
 
        if (!success &&
index 5b723b6b75a5097c04ad417e911ad2f7e5257bc9..cff1f45d990243c9ac371f6b6522a547c9d9a30b 100644 (file)
@@ -227,7 +227,8 @@ int p2p_connect_send(struct p2p_data *p2p, struct p2p_device *dev)
                        "P2P: Failed to send Action frame");
                /* Use P2P find to recover and retry */
                p2p_set_timeout(p2p, 0, 0);
-       }
+       } else
+               dev->go_neg_req_sent++;
 
        wpabuf_free(req);