mirror of
https://github.com/strongswan/strongswan.git
synced 2025-11-12 00:02:03 -05:00
Implemented table of connected peers without linked_list_t.
This commit is contained in:
parent
3489370458
commit
6f0cca20d8
@ -252,9 +252,9 @@ static void connected_peers_destroy(connected_peers_t *this)
|
|||||||
/**
|
/**
|
||||||
* Function that matches connected_peers_t objects by the given ids.
|
* Function that matches connected_peers_t objects by the given ids.
|
||||||
*/
|
*/
|
||||||
static bool connected_peers_match(connected_peers_t *connected_peers,
|
static inline bool connected_peers_match(connected_peers_t *connected_peers,
|
||||||
identification_t *my_id, identification_t *other_id,
|
identification_t *my_id, identification_t *other_id,
|
||||||
uintptr_t family)
|
int family)
|
||||||
{
|
{
|
||||||
return my_id->equals(my_id, connected_peers->my_id) &&
|
return my_id->equals(my_id, connected_peers->my_id) &&
|
||||||
other_id->equals(other_id, connected_peers->other_id) &&
|
other_id->equals(other_id, connected_peers->other_id) &&
|
||||||
@ -356,7 +356,7 @@ struct private_ike_sa_manager_t {
|
|||||||
/**
|
/**
|
||||||
* Hash table with connected_peers_t objects.
|
* Hash table with connected_peers_t objects.
|
||||||
*/
|
*/
|
||||||
linked_list_t **connected_peers_table;
|
table_item_t **connected_peers_table;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Segments of the "connected peers" hash table.
|
* Segments of the "connected peers" hash table.
|
||||||
@ -811,28 +811,28 @@ static void remove_half_open(private_ike_sa_manager_t *this, entry_t *entry)
|
|||||||
*/
|
*/
|
||||||
static void put_connected_peers(private_ike_sa_manager_t *this, entry_t *entry)
|
static void put_connected_peers(private_ike_sa_manager_t *this, entry_t *entry)
|
||||||
{
|
{
|
||||||
connected_peers_t *connected_peers = NULL;
|
table_item_t *item;
|
||||||
chunk_t my_id, other_id;
|
|
||||||
linked_list_t *list;
|
|
||||||
u_int row, segment;
|
u_int row, segment;
|
||||||
rwlock_t *lock;
|
rwlock_t *lock;
|
||||||
|
connected_peers_t *connected_peers;
|
||||||
|
chunk_t my_id, other_id;
|
||||||
|
int family;
|
||||||
|
|
||||||
my_id = entry->my_id->get_encoding(entry->my_id);
|
my_id = entry->my_id->get_encoding(entry->my_id);
|
||||||
other_id = entry->other_id->get_encoding(entry->other_id);
|
other_id = entry->other_id->get_encoding(entry->other_id);
|
||||||
|
family = entry->other->get_family(entry->other);
|
||||||
row = chunk_hash_inc(other_id, chunk_hash(my_id)) & this->table_mask;
|
row = chunk_hash_inc(other_id, chunk_hash(my_id)) & this->table_mask;
|
||||||
segment = row & this->segment_mask;
|
segment = row & this->segment_mask;
|
||||||
lock = this->connected_peers_segments[segment].lock;
|
lock = this->connected_peers_segments[segment].lock;
|
||||||
lock->write_lock(lock);
|
lock->write_lock(lock);
|
||||||
list = this->connected_peers_table[row];
|
item = this->connected_peers_table[row];
|
||||||
if (list)
|
while (item)
|
||||||
{
|
{
|
||||||
connected_peers_t *current;
|
connected_peers = item->value;
|
||||||
|
|
||||||
if (list->find_first(list, (linked_list_match_t)connected_peers_match,
|
if (connected_peers_match(connected_peers, entry->my_id,
|
||||||
(void**)¤t, entry->my_id, entry->other_id,
|
entry->other_id, family))
|
||||||
(uintptr_t)entry->other->get_family(entry->other)) == SUCCESS)
|
|
||||||
{
|
{
|
||||||
connected_peers = current;
|
|
||||||
if (connected_peers->sas->find_first(connected_peers->sas,
|
if (connected_peers->sas->find_first(connected_peers->sas,
|
||||||
(linked_list_match_t)entry->ike_sa_id->equals,
|
(linked_list_match_t)entry->ike_sa_id->equals,
|
||||||
NULL, entry->ike_sa_id) == SUCCESS)
|
NULL, entry->ike_sa_id) == SUCCESS)
|
||||||
@ -840,22 +840,24 @@ static void put_connected_peers(private_ike_sa_manager_t *this, entry_t *entry)
|
|||||||
lock->unlock(lock);
|
lock->unlock(lock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
item = item->next;
|
||||||
else
|
|
||||||
{
|
|
||||||
list = this->connected_peers_table[row] = linked_list_create();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!connected_peers)
|
if (!item)
|
||||||
{
|
{
|
||||||
INIT(connected_peers,
|
INIT(connected_peers,
|
||||||
.my_id = entry->my_id->clone(entry->my_id),
|
.my_id = entry->my_id->clone(entry->my_id),
|
||||||
.other_id = entry->other_id->clone(entry->other_id),
|
.other_id = entry->other_id->clone(entry->other_id),
|
||||||
.family = entry->other->get_family(entry->other),
|
.family = family,
|
||||||
.sas = linked_list_create(),
|
.sas = linked_list_create(),
|
||||||
);
|
);
|
||||||
list->insert_last(list, connected_peers);
|
INIT(item,
|
||||||
|
.value = connected_peers,
|
||||||
|
.next = this->connected_peers_table[row],
|
||||||
|
);
|
||||||
|
this->connected_peers_table[row] = item;
|
||||||
}
|
}
|
||||||
connected_peers->sas->insert_last(connected_peers->sas,
|
connected_peers->sas->insert_last(connected_peers->sas,
|
||||||
entry->ike_sa_id->clone(entry->ike_sa_id));
|
entry->ike_sa_id->clone(entry->ike_sa_id));
|
||||||
@ -868,54 +870,61 @@ static void put_connected_peers(private_ike_sa_manager_t *this, entry_t *entry)
|
|||||||
*/
|
*/
|
||||||
static void remove_connected_peers(private_ike_sa_manager_t *this, entry_t *entry)
|
static void remove_connected_peers(private_ike_sa_manager_t *this, entry_t *entry)
|
||||||
{
|
{
|
||||||
chunk_t my_id, other_id;
|
table_item_t *item, *prev = NULL;
|
||||||
linked_list_t *list;
|
|
||||||
u_int row, segment;
|
u_int row, segment;
|
||||||
rwlock_t *lock;
|
rwlock_t *lock;
|
||||||
|
chunk_t my_id, other_id;
|
||||||
|
int family;
|
||||||
|
|
||||||
my_id = entry->my_id->get_encoding(entry->my_id);
|
my_id = entry->my_id->get_encoding(entry->my_id);
|
||||||
other_id = entry->other_id->get_encoding(entry->other_id);
|
other_id = entry->other_id->get_encoding(entry->other_id);
|
||||||
|
family = entry->other->get_family(entry->other);
|
||||||
|
|
||||||
row = chunk_hash_inc(other_id, chunk_hash(my_id)) & this->table_mask;
|
row = chunk_hash_inc(other_id, chunk_hash(my_id)) & this->table_mask;
|
||||||
segment = row & this->segment_mask;
|
segment = row & this->segment_mask;
|
||||||
|
|
||||||
lock = this->connected_peers_segments[segment].lock;
|
lock = this->connected_peers_segments[segment].lock;
|
||||||
lock->write_lock(lock);
|
lock->write_lock(lock);
|
||||||
list = this->connected_peers_table[row];
|
item = this->connected_peers_table[row];
|
||||||
if (list)
|
while (item)
|
||||||
{
|
{
|
||||||
connected_peers_t *current;
|
connected_peers_t *current = item->value;
|
||||||
enumerator_t *enumerator;
|
|
||||||
|
|
||||||
enumerator = list->create_enumerator(list);
|
|
||||||
while (enumerator->enumerate(enumerator, ¤t))
|
|
||||||
{
|
|
||||||
if (connected_peers_match(current, entry->my_id, entry->other_id,
|
if (connected_peers_match(current, entry->my_id, entry->other_id,
|
||||||
(uintptr_t)entry->other->get_family(entry->other)))
|
family))
|
||||||
{
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
ike_sa_id_t *ike_sa_id;
|
ike_sa_id_t *ike_sa_id;
|
||||||
enumerator_t *inner;
|
|
||||||
|
|
||||||
inner = current->sas->create_enumerator(current->sas);
|
enumerator = current->sas->create_enumerator(current->sas);
|
||||||
while (inner->enumerate(inner, &ike_sa_id))
|
while (enumerator->enumerate(enumerator, &ike_sa_id))
|
||||||
{
|
{
|
||||||
if (ike_sa_id->equals(ike_sa_id, entry->ike_sa_id))
|
if (ike_sa_id->equals(ike_sa_id, entry->ike_sa_id))
|
||||||
{
|
{
|
||||||
current->sas->remove_at(current->sas, inner);
|
current->sas->remove_at(current->sas, enumerator);
|
||||||
ike_sa_id->destroy(ike_sa_id);
|
ike_sa_id->destroy(ike_sa_id);
|
||||||
this->connected_peers_segments[segment].count--;
|
this->connected_peers_segments[segment].count--;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inner->destroy(inner);
|
enumerator->destroy(enumerator);
|
||||||
if (current->sas->get_count(current->sas) == 0)
|
if (current->sas->get_count(current->sas) == 0)
|
||||||
{
|
{
|
||||||
list->remove_at(list, enumerator);
|
if (prev)
|
||||||
|
{
|
||||||
|
prev->next = item->next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->connected_peers_table[row] = item->next;
|
||||||
|
}
|
||||||
connected_peers_destroy(current);
|
connected_peers_destroy(current);
|
||||||
|
free(item);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
prev = item;
|
||||||
enumerator->destroy(enumerator);
|
item = item->next;
|
||||||
}
|
}
|
||||||
lock->unlock(lock);
|
lock->unlock(lock);
|
||||||
}
|
}
|
||||||
@ -1573,26 +1582,29 @@ METHOD(ike_sa_manager_t, create_id_enumerator, enumerator_t*,
|
|||||||
private_ike_sa_manager_t *this, identification_t *me,
|
private_ike_sa_manager_t *this, identification_t *me,
|
||||||
identification_t *other, int family)
|
identification_t *other, int family)
|
||||||
{
|
{
|
||||||
linked_list_t *list, *ids = NULL;
|
table_item_t *item;
|
||||||
connected_peers_t *current;
|
|
||||||
u_int row, segment;
|
u_int row, segment;
|
||||||
rwlock_t *lock;
|
rwlock_t *lock;
|
||||||
|
linked_list_t *ids = NULL;
|
||||||
|
|
||||||
row = chunk_hash_inc(other->get_encoding(other),
|
row = chunk_hash_inc(other->get_encoding(other),
|
||||||
chunk_hash(me->get_encoding(me))) & this->table_mask;
|
chunk_hash(me->get_encoding(me))) & this->table_mask;
|
||||||
segment = row & this->segment_mask;
|
segment = row & this->segment_mask;
|
||||||
|
|
||||||
lock = this->connected_peers_segments[segment & this->segment_mask].lock;
|
lock = this->connected_peers_segments[segment].lock;
|
||||||
lock->read_lock(lock);
|
lock->read_lock(lock);
|
||||||
list = this->connected_peers_table[row];
|
item = this->connected_peers_table[row];
|
||||||
if (list)
|
while (item)
|
||||||
{
|
{
|
||||||
if (list->find_first(list, (linked_list_match_t)connected_peers_match,
|
connected_peers_t *current = item->value;
|
||||||
(void**)¤t, me, other, (uintptr_t)family) == SUCCESS)
|
|
||||||
|
if (connected_peers_match(current, me, other, family))
|
||||||
{
|
{
|
||||||
ids = current->sas->clone_offset(current->sas,
|
ids = current->sas->clone_offset(current->sas,
|
||||||
offsetof(ike_sa_id_t, clone));
|
offsetof(ike_sa_id_t, clone));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
item = item->next;
|
||||||
}
|
}
|
||||||
lock->unlock(lock);
|
lock->unlock(lock);
|
||||||
|
|
||||||
@ -1691,7 +1703,7 @@ METHOD(ike_sa_manager_t, has_contact, bool,
|
|||||||
private_ike_sa_manager_t *this, identification_t *me,
|
private_ike_sa_manager_t *this, identification_t *me,
|
||||||
identification_t *other, int family)
|
identification_t *other, int family)
|
||||||
{
|
{
|
||||||
linked_list_t *list;
|
table_item_t *item;
|
||||||
u_int row, segment;
|
u_int row, segment;
|
||||||
rwlock_t *lock;
|
rwlock_t *lock;
|
||||||
bool found = FALSE;
|
bool found = FALSE;
|
||||||
@ -1699,16 +1711,17 @@ METHOD(ike_sa_manager_t, has_contact, bool,
|
|||||||
row = chunk_hash_inc(other->get_encoding(other),
|
row = chunk_hash_inc(other->get_encoding(other),
|
||||||
chunk_hash(me->get_encoding(me))) & this->table_mask;
|
chunk_hash(me->get_encoding(me))) & this->table_mask;
|
||||||
segment = row & this->segment_mask;
|
segment = row & this->segment_mask;
|
||||||
lock = this->connected_peers_segments[segment & this->segment_mask].lock;
|
lock = this->connected_peers_segments[segment].lock;
|
||||||
lock->read_lock(lock);
|
lock->read_lock(lock);
|
||||||
list = this->connected_peers_table[row];
|
item = this->connected_peers_table[row];
|
||||||
if (list)
|
while (item)
|
||||||
{
|
{
|
||||||
if (list->find_first(list, (linked_list_match_t)connected_peers_match,
|
if (connected_peers_match(item->value, me, other, family))
|
||||||
NULL, me, other, family) == SUCCESS)
|
|
||||||
{
|
{
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
item = item->next;
|
||||||
}
|
}
|
||||||
lock->unlock(lock);
|
lock->unlock(lock);
|
||||||
|
|
||||||
@ -1868,7 +1881,6 @@ METHOD(ike_sa_manager_t, destroy, void,
|
|||||||
|
|
||||||
for (i = 0; i < this->table_size; i++)
|
for (i = 0; i < this->table_size; i++)
|
||||||
{
|
{
|
||||||
DESTROY_IF(this->connected_peers_table[i]);
|
|
||||||
DESTROY_IF(this->init_hashes_table[i]);
|
DESTROY_IF(this->init_hashes_table[i]);
|
||||||
}
|
}
|
||||||
free(this->ike_sa_table);
|
free(this->ike_sa_table);
|
||||||
@ -1981,7 +1993,7 @@ ike_sa_manager_t *ike_sa_manager_create()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* also for the hash table used for duplicate tests */
|
/* also for the hash table used for duplicate tests */
|
||||||
this->connected_peers_table = calloc(this->table_size, sizeof(linked_list_t*));
|
this->connected_peers_table = calloc(this->table_size, sizeof(table_item_t*));
|
||||||
this->connected_peers_segments = calloc(this->segment_count, sizeof(shareable_segment_t));
|
this->connected_peers_segments = calloc(this->segment_count, sizeof(shareable_segment_t));
|
||||||
for (i = 0; i < this->segment_count; i++)
|
for (i = 0; i < this->segment_count; i++)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user