Implemented table of half open IKE_SAs without linked_list_t.

This commit is contained in:
Tobias Brunner
2012-03-20 17:31:41 +01:00
parent e49bb4e3e3
commit 3489370458
+47 -52
View File
@@ -225,14 +225,6 @@ static void half_open_destroy(half_open_t *this)
free(this); free(this);
} }
/**
* Function that matches half_open_t objects by the given IP address chunk.
*/
static bool half_open_match(half_open_t *half_open, chunk_t *addr)
{
return chunk_equals(*addr, half_open->other);
}
typedef struct connected_peers_t connected_peers_t; typedef struct connected_peers_t connected_peers_t;
struct connected_peers_t { struct connected_peers_t {
@@ -354,7 +346,7 @@ struct private_ike_sa_manager_t {
/** /**
* Hash table with half_open_t objects. * Hash table with half_open_t objects.
*/ */
linked_list_t **half_open_table; table_item_t **half_open_table;
/** /**
* Segments of the "half-open" hash table. * Segments of the "half-open" hash table.
@@ -730,44 +722,43 @@ static bool wait_for_entry(private_ike_sa_manager_t *this, entry_t *entry,
*/ */
static void put_half_open(private_ike_sa_manager_t *this, entry_t *entry) static void put_half_open(private_ike_sa_manager_t *this, entry_t *entry)
{ {
half_open_t *half_open = NULL; table_item_t *item;
linked_list_t *list;
chunk_t addr;
u_int row, segment; u_int row, segment;
rwlock_t *lock; rwlock_t *lock;
half_open_t *half_open;
chunk_t addr;
addr = entry->other->get_address(entry->other); addr = entry->other->get_address(entry->other);
row = chunk_hash(addr) & this->table_mask; row = chunk_hash(addr) & this->table_mask;
segment = row & this->segment_mask; segment = row & this->segment_mask;
lock = this->half_open_segments[segment].lock; lock = this->half_open_segments[segment].lock;
lock->write_lock(lock); lock->write_lock(lock);
list = this->half_open_table[row]; item = this->half_open_table[row];
if (list) while (item)
{ {
half_open_t *current; half_open = item->value;
if (list->find_first(list, (linked_list_match_t)half_open_match, if (chunk_equals(addr, half_open->other))
(void**)&current, &addr) == SUCCESS)
{ {
half_open = current;
half_open->count++; half_open->count++;
this->half_open_segments[segment].count++; break;
} }
} item = item->next;
else
{
list = this->half_open_table[row] = linked_list_create();
} }
if (!half_open) if (!item)
{ {
INIT(half_open, INIT(half_open,
.other = chunk_clone(addr), .other = chunk_clone(addr),
.count = 1, .count = 1,
); );
list->insert_last(list, half_open); INIT(item,
this->half_open_segments[segment].count++; .value = half_open,
.next = this->half_open_table[row],
);
this->half_open_table[row] = item;
} }
this->half_open_segments[segment].count++;
lock->unlock(lock); lock->unlock(lock);
} }
@@ -776,37 +767,41 @@ static void put_half_open(private_ike_sa_manager_t *this, entry_t *entry)
*/ */
static void remove_half_open(private_ike_sa_manager_t *this, entry_t *entry) static void remove_half_open(private_ike_sa_manager_t *this, entry_t *entry)
{ {
linked_list_t *list; table_item_t *item, *prev = NULL;
chunk_t addr;
u_int row, segment; u_int row, segment;
rwlock_t *lock; rwlock_t *lock;
chunk_t addr;
addr = entry->other->get_address(entry->other); addr = entry->other->get_address(entry->other);
row = chunk_hash(addr) & this->table_mask; row = chunk_hash(addr) & this->table_mask;
segment = row & this->segment_mask; segment = row & this->segment_mask;
lock = this->half_open_segments[segment].lock; lock = this->half_open_segments[segment].lock;
lock->write_lock(lock); lock->write_lock(lock);
list = this->half_open_table[row]; item = this->half_open_table[row];
if (list) while (item)
{ {
half_open_t *current; half_open_t *half_open = item->value;
enumerator_t *enumerator;
enumerator = list->create_enumerator(list); if (chunk_equals(addr, half_open->other))
while (enumerator->enumerate(enumerator, &current))
{ {
if (half_open_match(current, &addr)) if (--half_open->count == 0)
{ {
if (--current->count == 0) if (prev)
{ {
list->remove_at(list, enumerator); prev->next = item->next;
half_open_destroy(current);
} }
this->half_open_segments[segment].count--; else
break; {
this->half_open_table[row] = item->next;
}
half_open_destroy(half_open);
free(item);
} }
this->half_open_segments[segment].count--;
break;
} }
enumerator->destroy(enumerator); prev = item;
item = item->next;
} }
lock->unlock(lock); lock->unlock(lock);
} }
@@ -1739,8 +1734,8 @@ METHOD(ike_sa_manager_t, get_count, u_int,
METHOD(ike_sa_manager_t, get_half_open_count, u_int, METHOD(ike_sa_manager_t, get_half_open_count, u_int,
private_ike_sa_manager_t *this, host_t *ip) private_ike_sa_manager_t *this, host_t *ip)
{ {
linked_list_t *list; table_item_t *item;
u_int segment, row; u_int row, segment;
rwlock_t *lock; rwlock_t *lock;
chunk_t addr; chunk_t addr;
u_int count = 0; u_int count = 0;
@@ -1750,16 +1745,17 @@ METHOD(ike_sa_manager_t, get_half_open_count, u_int,
addr = ip->get_address(ip); addr = ip->get_address(ip);
row = chunk_hash(addr) & this->table_mask; row = chunk_hash(addr) & this->table_mask;
segment = row & this->segment_mask; segment = row & this->segment_mask;
lock = this->half_open_segments[segment & this->segment_mask].lock; lock = this->half_open_segments[segment].lock;
lock->read_lock(lock); lock->read_lock(lock);
if ((list = this->half_open_table[row]) != NULL) item = this->half_open_table[row];
while (item)
{ {
half_open_t *current; half_open_t *half_open = item->value;
if (list->find_first(list, (linked_list_match_t)half_open_match, if (chunk_equals(addr, half_open->other))
(void**)&current, &addr) == SUCCESS)
{ {
count = current->count; count = half_open->count;
break;
} }
} }
lock->unlock(lock); lock->unlock(lock);
@@ -1768,7 +1764,7 @@ METHOD(ike_sa_manager_t, get_half_open_count, u_int,
{ {
for (segment = 0; segment < this->segment_count; segment++) for (segment = 0; segment < this->segment_count; segment++)
{ {
lock = this->half_open_segments[segment & this->segment_mask].lock; lock = this->half_open_segments[segment].lock;
lock->read_lock(lock); lock->read_lock(lock);
count += this->half_open_segments[segment].count; count += this->half_open_segments[segment].count;
lock->unlock(lock); lock->unlock(lock);
@@ -1872,7 +1868,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->half_open_table[i]);
DESTROY_IF(this->connected_peers_table[i]); DESTROY_IF(this->connected_peers_table[i]);
DESTROY_IF(this->init_hashes_table[i]); DESTROY_IF(this->init_hashes_table[i]);
} }
@@ -1977,7 +1972,7 @@ ike_sa_manager_t *ike_sa_manager_create()
} }
/* we use the same table parameters for the table to track half-open SAs */ /* we use the same table parameters for the table to track half-open SAs */
this->half_open_table = calloc(this->table_size, sizeof(linked_list_t*)); this->half_open_table = calloc(this->table_size, sizeof(table_item_t*));
this->half_open_segments = calloc(this->segment_count, sizeof(shareable_segment_t)); this->half_open_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++)
{ {