]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Assign GO tie breaker bit at the same time with dialog token
authorJouni Malinen <jouni@qca.qualcomm.com>
Tue, 26 Feb 2013 14:56:48 +0000 (16:56 +0200)
committerJouni Malinen <j@w1.fi>
Tue, 26 Feb 2013 14:56:48 +0000 (16:56 +0200)
Commit 624b4d5a6469c92b039e0d39655b9e0eb26588aa changed GO Negotiation
to use the same Dialog Token value for all retransmissions of the GO
Negotiation Request within the same session. However, it did leave the
tie breaker bit changing for each frame. While this should not have
caused issues for most cases, it looks like there are possible sequences
where the peer may end up replying to two GO Negotiation Request frames
with different tie breaker values. If in such a case the different GO
Negotiation Response frames are used at each device, GO role
determination may result in conflicting results when same GO intent is
used.

Fix this by assigning the tie breaker value at the same time with the
dialog token (i.e., when processing the p2p_connect command instead of
for each transmitted GO Negotiation Request frame) to avoid issues with
GO selection.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>

src/p2p/p2p.c
src/p2p/p2p_go_neg.c
src/p2p/p2p_i.h

index 1b7225efb1bef2c09134dfdd6ab2bd5f4be0e386..4a4bc9e63ba87b80d3c453896bb30854374bf696 100644 (file)
@@ -1368,12 +1368,14 @@ int p2p_connect(struct p2p_data *p2p, const u8 *peer_addr,
        else {
                dev->flags &= ~P2P_DEV_PD_BEFORE_GO_NEG;
                /*
-                * Assign dialog token here to use the same value in each
-                * retry within the same GO Negotiation exchange.
+                * Assign dialog token and tie breaker here to use the same
+                * values in each retry within the same GO Negotiation exchange.
                 */
                dev->dialog_token++;
                if (dev->dialog_token == 0)
                        dev->dialog_token = 1;
+               dev->tie_breaker = p2p->next_tie_breaker;
+               p2p->next_tie_breaker = !p2p->next_tie_breaker;
        }
        dev->connect_reqs = 0;
        dev->go_neg_req_sent = 0;
index 38d42755b621d8d1ff94793bca7a5b72bc42871b..8811c855760dff4a694ca0a2262ab450e9269cdc 100644 (file)
@@ -161,9 +161,7 @@ static struct wpabuf * p2p_build_go_neg_req(struct p2p_data *p2p,
        p2p_buf_add_capability(buf, p2p->dev_capab &
                               ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY,
                               group_capab);
-       p2p_buf_add_go_intent(buf, (p2p->go_intent << 1) |
-                             p2p->next_tie_breaker);
-       p2p->next_tie_breaker = !p2p->next_tie_breaker;
+       p2p_buf_add_go_intent(buf, (p2p->go_intent << 1) | peer->tie_breaker);
        p2p_buf_add_config_timeout(buf, p2p->go_timeout, p2p->client_timeout);
        p2p_buf_add_listen_channel(buf, p2p->cfg->country, p2p->cfg->reg_class,
                                   p2p->cfg->channel);
index 005f73b08ab701b93471906d6aae72c708ea2b1d..e91959f824fed94ea82515f9732ea0433ad3f8fc 100644 (file)
@@ -52,6 +52,7 @@ struct p2p_device {
        int go_neg_req_sent;
        enum p2p_go_state go_state;
        u8 dialog_token;
+       u8 tie_breaker;
        u8 intended_addr[ETH_ALEN];
 
        char country[3];