Parcourir la source

P2P: Assign GO tie breaker bit at the same time with dialog token

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>
Jouni Malinen il y a 12 ans
Parent
commit
003c45804f
3 fichiers modifiés avec 6 ajouts et 5 suppressions
  1. 4 2
      src/p2p/p2p.c
  2. 1 3
      src/p2p/p2p_go_neg.c
  3. 1 0
      src/p2p/p2p_i.h

+ 4 - 2
src/p2p/p2p.c

@@ -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;

+ 1 - 3
src/p2p/p2p_go_neg.c

@@ -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);

+ 1 - 0
src/p2p/p2p_i.h

@@ -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];