Clean up authenticator PMKSA cache implementation

This makes the implementation somewhat easier to understand.

Signed-off-by: Jouni Malinen <j@w1.fi>
This commit is contained in:
Jouni Malinen 2014-10-04 22:08:17 +03:00
parent cb129db34c
commit a61fcc131a

View file

@ -50,38 +50,42 @@ void pmksa_cache_free_entry(struct rsn_pmksa_cache *pmksa,
struct rsn_pmksa_cache_entry *entry) struct rsn_pmksa_cache_entry *entry)
{ {
struct rsn_pmksa_cache_entry *pos, *prev; struct rsn_pmksa_cache_entry *pos, *prev;
unsigned int hash;
pmksa->pmksa_count--; pmksa->pmksa_count--;
pmksa->free_cb(entry, pmksa->ctx); pmksa->free_cb(entry, pmksa->ctx);
pos = pmksa->pmkid[PMKID_HASH(entry->pmkid)];
/* unlink from hash list */
hash = PMKID_HASH(entry->pmkid);
pos = pmksa->pmkid[hash];
prev = NULL; prev = NULL;
while (pos) { while (pos) {
if (pos == entry) { if (pos == entry) {
if (prev != NULL) { if (prev != NULL)
prev->hnext = pos->hnext; prev->hnext = entry->hnext;
} else { else
pmksa->pmkid[PMKID_HASH(entry->pmkid)] = pmksa->pmkid[hash] = entry->hnext;
pos->hnext;
}
break; break;
} }
prev = pos; prev = pos;
pos = pos->hnext; pos = pos->hnext;
} }
/* unlink from entry list */
pos = pmksa->pmksa; pos = pmksa->pmksa;
prev = NULL; prev = NULL;
while (pos) { while (pos) {
if (pos == entry) { if (pos == entry) {
if (prev != NULL) if (prev != NULL)
prev->next = pos->next; prev->next = entry->next;
else else
pmksa->pmksa = pos->next; pmksa->pmksa = entry->next;
break; break;
} }
prev = pos; prev = pos;
pos = pos->next; pos = pos->next;
} }
_pmksa_cache_free_entry(entry); _pmksa_cache_free_entry(entry);
} }
@ -186,6 +190,7 @@ static void pmksa_cache_link_entry(struct rsn_pmksa_cache *pmksa,
struct rsn_pmksa_cache_entry *entry) struct rsn_pmksa_cache_entry *entry)
{ {
struct rsn_pmksa_cache_entry *pos, *prev; struct rsn_pmksa_cache_entry *pos, *prev;
int hash;
/* Add the new entry; order by expiration time */ /* Add the new entry; order by expiration time */
pos = pmksa->pmksa; pos = pmksa->pmksa;
@ -203,8 +208,10 @@ static void pmksa_cache_link_entry(struct rsn_pmksa_cache *pmksa,
entry->next = prev->next; entry->next = prev->next;
prev->next = entry; prev->next = entry;
} }
entry->hnext = pmksa->pmkid[PMKID_HASH(entry->pmkid)];
pmksa->pmkid[PMKID_HASH(entry->pmkid)] = entry; hash = PMKID_HASH(entry->pmkid);
entry->hnext = pmksa->pmkid[hash];
pmksa->pmkid[hash] = entry;
pmksa->pmksa_count++; pmksa->pmksa_count++;
if (prev == NULL) if (prev == NULL)
@ -340,6 +347,8 @@ void pmksa_cache_auth_deinit(struct rsn_pmksa_cache *pmksa)
_pmksa_cache_free_entry(prev); _pmksa_cache_free_entry(prev);
} }
eloop_cancel_timeout(pmksa_cache_expire, pmksa, NULL); eloop_cancel_timeout(pmksa_cache_expire, pmksa, NULL);
pmksa->pmksa_count = 0;
pmksa->pmksa = NULL;
for (i = 0; i < PMKID_HASH_SIZE; i++) for (i = 0; i < PMKID_HASH_SIZE; i++)
pmksa->pmkid[i] = NULL; pmksa->pmkid[i] = NULL;
os_free(pmksa); os_free(pmksa);
@ -359,18 +368,22 @@ pmksa_cache_auth_get(struct rsn_pmksa_cache *pmksa,
{ {
struct rsn_pmksa_cache_entry *entry; struct rsn_pmksa_cache_entry *entry;
if (pmkid) if (pmkid) {
entry = pmksa->pmkid[PMKID_HASH(pmkid)]; for (entry = pmksa->pmkid[PMKID_HASH(pmkid)]; entry;
else entry = entry->hnext) {
entry = pmksa->pmksa; if ((spa == NULL ||
while (entry) { os_memcmp(entry->spa, spa, ETH_ALEN) == 0) &&
if ((spa == NULL || os_memcmp(entry->pmkid, pmkid, PMKID_LEN) == 0)
os_memcmp(entry->spa, spa, ETH_ALEN) == 0) && return entry;
(pmkid == NULL || }
os_memcmp(entry->pmkid, pmkid, PMKID_LEN) == 0)) } else {
return entry; for (entry = pmksa->pmksa; entry; entry = entry->next) {
entry = pmkid ? entry->hnext : entry->next; if (spa == NULL ||
os_memcmp(entry->spa, spa, ETH_ALEN) == 0)
return entry;
}
} }
return NULL; return NULL;
} }