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,
|
int p2p_group_notif_assoc(struct p2p_group *group, const u8 *addr,
|
||||||
const u8 *ie, size_t len)
|
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);
|
m->dev_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p2p_group_remove_member(group, addr);
|
||||||
|
|
||||||
m->next = group->members;
|
m->next = group->members;
|
||||||
group->members = m;
|
group->members = m;
|
||||||
group->num_members++;
|
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)
|
void p2p_group_notif_disassoc(struct p2p_group *group, const u8 *addr)
|
||||||
{
|
{
|
||||||
struct p2p_group_member *m, *prev;
|
if (p2p_group_remove_member(group, addr)) {
|
||||||
|
|
||||||
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--;
|
|
||||||
wpa_msg(group->p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Remove "
|
wpa_msg(group->p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Remove "
|
||||||
"client " MACSTR " from group; num_members=%u/%u",
|
"client " MACSTR " from group; num_members=%u/%u",
|
||||||
MAC2STR(addr), group->num_members,
|
MAC2STR(addr), group->num_members,
|
||||||
|
|
Loading…
Reference in a new issue