diff options
author | Yves-Alexis Perez <corsac@debian.org> | 2015-11-18 14:49:27 +0100 |
---|---|---|
committer | Yves-Alexis Perez <corsac@debian.org> | 2015-11-18 14:49:27 +0100 |
commit | 1e980d6be0ef0e243c6fe82b5e855454b97e24a4 (patch) | |
tree | 0d59eec2ce2ed332434ae80fc78a44db9ad293c5 /src/libcharon/plugins/eap_radius | |
parent | 5dca9ea0e2931f0e2a056c7964d311bcc30a01b8 (diff) | |
download | vyos-strongswan-1e980d6be0ef0e243c6fe82b5e855454b97e24a4.tar.gz vyos-strongswan-1e980d6be0ef0e243c6fe82b5e855454b97e24a4.zip |
Imported Upstream version 5.3.4
Diffstat (limited to 'src/libcharon/plugins/eap_radius')
-rw-r--r-- | src/libcharon/plugins/eap_radius/eap_radius_provider.c | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_provider.c b/src/libcharon/plugins/eap_radius/eap_radius_provider.c index 0cf723711..0f207fbe6 100644 --- a/src/libcharon/plugins/eap_radius/eap_radius_provider.c +++ b/src/libcharon/plugins/eap_radius/eap_radius_provider.c @@ -178,18 +178,38 @@ static void add_addr(private_eap_radius_provider_t *this, * Remove the next address from the locked hashtable stored for given id */ static host_t* remove_addr(private_eap_radius_provider_t *this, - hashtable_t *hashtable, uintptr_t id) + hashtable_t *hashtable, uintptr_t id, host_t *addr) { + enumerator_t *enumerator; entry_t *entry; - host_t *addr = NULL; + host_t *found = NULL, *current; entry = hashtable->remove(hashtable, (void*)id); if (entry) { - entry->addrs->remove_first(entry->addrs, (void**)&addr); + enumerator = entry->addrs->create_enumerator(entry->addrs); + while (enumerator->enumerate(enumerator, ¤t)) + { + if (addr->ip_equals(addr, current)) + { /* prefer an exact match */ + entry->addrs->remove_at(entry->addrs, enumerator); + enumerator->destroy(enumerator); + put_or_destroy_entry(hashtable, entry); + return current; + } + if (!found && addr->get_family(addr) == current->get_family(current)) + { /* fallback to the first IP with a matching address family */ + found = current; + } + } + enumerator->destroy(enumerator); + if (found) + { + entry->addrs->remove(entry->addrs, found, NULL); + } put_or_destroy_entry(hashtable, entry); } - return addr; + return found; } /** @@ -326,7 +346,7 @@ METHOD(attribute_provider_t, acquire_address, host_t*, if (streq(name, "radius")) { this->listener.mutex->lock(this->listener.mutex); - addr = remove_addr(this, this->listener.unclaimed, sa); + addr = remove_addr(this, this->listener.unclaimed, sa, requested); if (addr) { add_addr(this, this->listener.claimed, sa, addr->clone(addr)); @@ -357,7 +377,7 @@ METHOD(attribute_provider_t, release_address, bool, if (streq(name, "radius")) { this->listener.mutex->lock(this->listener.mutex); - found = remove_addr(this, this->listener.claimed, sa); + found = remove_addr(this, this->listener.claimed, sa, address); this->listener.mutex->unlock(this->listener.mutex); break; } |