aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-11-16 16:36:40 +0200
committerJouni Malinen <j@w1.fi>2011-11-16 16:36:40 +0200
commit38dcca9ab0c8fec3f29ae13b9a9c49225dab684b (patch)
tree87921f44d6f683e8d48cb99a7f8b079760dab9a6
parent0399f2e4e5fa6b2994becfa2495cd4bc69240455 (diff)
downloadexternal_wpa_supplicant_8_ti-38dcca9ab0c8fec3f29ae13b9a9c49225dab684b.zip
external_wpa_supplicant_8_ti-38dcca9ab0c8fec3f29ae13b9a9c49225dab684b.tar.gz
external_wpa_supplicant_8_ti-38dcca9ab0c8fec3f29ae13b9a9c49225dab684b.tar.bz2
P2P: Deal with a peer associating while connected
If a P2P client associates with the group while it is already associated, two member entries may be added to the group which also confuses num_members counting. Deal with this by removing the existing entry first before adding a new one. I think the way Reinette ran into this was due to our tx_sync implementation in iwlagn, mac80211 might have queued two association frames thinking the first one just failed, but both only went out after the sync was really successful (which tx_sync doesn't wait for). Reported-by: Reinette Chatre <reinette.chatre@intel.com> Signed-hostap: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--src/p2p/p2p_group.c54
1 files changed, 33 insertions, 21 deletions
diff --git a/src/p2p/p2p_group.c b/src/p2p/p2p_group.c
index 58b24c5..c34a92f 100644
--- a/src/p2p/p2p_group.c
+++ b/src/p2p/p2p_group.c
@@ -313,6 +313,36 @@ static struct wpabuf * p2p_build_client_info(const u8 *addr,
}
+static int p2p_group_remove_member(struct p2p_group *group, const u8 *addr)
+{
+ struct p2p_group_member *m, *prev;
+
+ if (group == NULL)
+ return 0;
+
+ m = group->members;
+ prev = NULL;
+ while (m) {
+ if (os_memcmp(m->addr, addr, ETH_ALEN) == 0)
+ break;
+ prev = m;
+ m = m->next;
+ }
+
+ if (m == NULL)
+ return 0;
+
+ if (prev)
+ prev->next = m->next;
+ else
+ group->members = m->next;
+ p2p_group_free_member(m);
+ group->num_members--;
+
+ return 1;
+}
+
+
int p2p_group_notif_assoc(struct p2p_group *group, const u8 *addr,
const u8 *ie, size_t len)
{
@@ -332,6 +362,8 @@ int p2p_group_notif_assoc(struct p2p_group *group, const u8 *addr,
m->dev_addr);
}
+ p2p_group_remove_member(group, addr);
+
m->next = group->members;
group->members = m;
group->num_members++;
@@ -374,27 +406,7 @@ struct wpabuf * p2p_group_assoc_resp_ie(struct p2p_group *group, u8 status)
void p2p_group_notif_disassoc(struct p2p_group *group, const u8 *addr)
{
- struct p2p_group_member *m, *prev;
-
- if (group == NULL)
- return;
-
- m = group->members;
- prev = NULL;
- while (m) {
- if (os_memcmp(m->addr, addr, ETH_ALEN) == 0)
- break;
- prev = m;
- m = m->next;
- }
-
- if (m) {
- if (prev)
- prev->next = m->next;
- else
- group->members = m->next;
- p2p_group_free_member(m);
- group->num_members--;
+ if (p2p_group_remove_member(group, addr)) {
wpa_msg(group->p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Remove "
"client " MACSTR " from group; num_members=%u/%u",
MAC2STR(addr), group->num_members,