P2P: Assign GO tie breaker bit at the same time with dialog token
Commit 624b4d5a64
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>
This commit is contained in:
parent
f8361e3d68
commit
003c45804f
3 changed files with 6 additions and 5 deletions
|
@ -1368,12 +1368,14 @@ int p2p_connect(struct p2p_data *p2p, const u8 *peer_addr,
|
||||||
else {
|
else {
|
||||||
dev->flags &= ~P2P_DEV_PD_BEFORE_GO_NEG;
|
dev->flags &= ~P2P_DEV_PD_BEFORE_GO_NEG;
|
||||||
/*
|
/*
|
||||||
* Assign dialog token here to use the same value in each
|
* Assign dialog token and tie breaker here to use the same
|
||||||
* retry within the same GO Negotiation exchange.
|
* values in each retry within the same GO Negotiation exchange.
|
||||||
*/
|
*/
|
||||||
dev->dialog_token++;
|
dev->dialog_token++;
|
||||||
if (dev->dialog_token == 0)
|
if (dev->dialog_token == 0)
|
||||||
dev->dialog_token = 1;
|
dev->dialog_token = 1;
|
||||||
|
dev->tie_breaker = p2p->next_tie_breaker;
|
||||||
|
p2p->next_tie_breaker = !p2p->next_tie_breaker;
|
||||||
}
|
}
|
||||||
dev->connect_reqs = 0;
|
dev->connect_reqs = 0;
|
||||||
dev->go_neg_req_sent = 0;
|
dev->go_neg_req_sent = 0;
|
||||||
|
|
|
@ -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_buf_add_capability(buf, p2p->dev_capab &
|
||||||
~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY,
|
~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY,
|
||||||
group_capab);
|
group_capab);
|
||||||
p2p_buf_add_go_intent(buf, (p2p->go_intent << 1) |
|
p2p_buf_add_go_intent(buf, (p2p->go_intent << 1) | peer->tie_breaker);
|
||||||
p2p->next_tie_breaker);
|
|
||||||
p2p->next_tie_breaker = !p2p->next_tie_breaker;
|
|
||||||
p2p_buf_add_config_timeout(buf, p2p->go_timeout, p2p->client_timeout);
|
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_buf_add_listen_channel(buf, p2p->cfg->country, p2p->cfg->reg_class,
|
||||||
p2p->cfg->channel);
|
p2p->cfg->channel);
|
||||||
|
|
|
@ -52,6 +52,7 @@ struct p2p_device {
|
||||||
int go_neg_req_sent;
|
int go_neg_req_sent;
|
||||||
enum p2p_go_state go_state;
|
enum p2p_go_state go_state;
|
||||||
u8 dialog_token;
|
u8 dialog_token;
|
||||||
|
u8 tie_breaker;
|
||||||
u8 intended_addr[ETH_ALEN];
|
u8 intended_addr[ETH_ALEN];
|
||||||
|
|
||||||
char country[3];
|
char country[3];
|
||||||
|
|
Loading…
Reference in a new issue