diff options
author | Johannes Berg <johannes.berg@intel.com> | 2011-11-16 16:36:40 +0200 |
---|---|---|
committer | Jouni Malinen <j@w1.fi> | 2011-11-16 16:36:40 +0200 |
commit | 38dcca9ab0c8fec3f29ae13b9a9c49225dab684b (patch) | |
tree | 87921f44d6f683e8d48cb99a7f8b079760dab9a6 | |
parent | 0399f2e4e5fa6b2994becfa2495cd4bc69240455 (diff) | |
download | external_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.c | 54 |
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, |