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>
This commit is contained in:
parent
0399f2e4e5
commit
38dcca9ab0
1 changed files with 33 additions and 21 deletions
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue