summaryrefslogtreecommitdiff
path: root/src/libcharon/sa/ike_sa_manager.c
diff options
context:
space:
mode:
authorYves-Alexis Perez <corsac@debian.org>2016-07-16 15:19:53 +0200
committerYves-Alexis Perez <corsac@debian.org>2016-07-16 15:19:53 +0200
commitbf372706c469764d59e9f29c39e3ecbebd72b8d2 (patch)
tree0f0e296e2d50e4a7faf99ae6fa428d2681e81ea1 /src/libcharon/sa/ike_sa_manager.c
parent518dd33c94e041db0444c7d1f33da363bb8e3faf (diff)
downloadvyos-strongswan-bf372706c469764d59e9f29c39e3ecbebd72b8d2.tar.gz
vyos-strongswan-bf372706c469764d59e9f29c39e3ecbebd72b8d2.zip
Imported Upstream version 5.5.0
Diffstat (limited to 'src/libcharon/sa/ike_sa_manager.c')
-rw-r--r--src/libcharon/sa/ike_sa_manager.c94
1 files changed, 55 insertions, 39 deletions
diff --git a/src/libcharon/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c
index 307ea3b4a..ce44207c4 100644
--- a/src/libcharon/sa/ike_sa_manager.c
+++ b/src/libcharon/sa/ike_sa_manager.c
@@ -113,7 +113,7 @@ struct entry_t {
/**
* message ID or hash of currently processing message, -1 if none
*/
- u_int32_t processing;
+ uint32_t processing;
};
/**
@@ -265,7 +265,7 @@ struct init_hash_t {
chunk_t hash;
/** our SPI allocated for the IKE_SA based on this message */
- u_int64_t our_spi;
+ uint64_t our_spi;
};
typedef struct segment_t segment_t;
@@ -977,9 +977,9 @@ static void remove_connected_peers(private_ike_sa_manager_t *this, entry_t *entr
/**
* Get a random SPI for new IKE_SAs
*/
-static u_int64_t get_spi(private_ike_sa_manager_t *this)
+static uint64_t get_spi(private_ike_sa_manager_t *this)
{
- u_int64_t spi;
+ uint64_t spi;
this->spi_lock->read_lock(this->spi_lock);
if (this->spi_cb.cb)
@@ -987,7 +987,7 @@ static u_int64_t get_spi(private_ike_sa_manager_t *this)
spi = this->spi_cb.cb(this->spi_cb.data);
}
else if (!this->rng ||
- !this->rng->get_bytes(this->rng, sizeof(spi), (u_int8_t*)&spi))
+ !this->rng->get_bytes(this->rng, sizeof(spi), (uint8_t*)&spi))
{
spi = 0;
}
@@ -1007,8 +1007,8 @@ static bool get_init_hash(hasher_t *hasher, message_t *message, chunk_t *hash)
if (message->get_first_payload_type(message) == PLV1_FRAGMENT)
{ /* only hash the source IP, port and SPI for fragmented init messages */
- u_int16_t port;
- u_int64_t spi;
+ uint16_t port;
+ uint64_t spi;
src = message->get_source(message);
if (!hasher->allocate_hash(hasher, src->get_address(src), NULL))
@@ -1050,13 +1050,13 @@ static bool get_init_hash(hasher_t *hasher, message_t *message, chunk_t *hash)
* FAILED if the SPI allocation failed
*/
static status_t check_and_put_init_hash(private_ike_sa_manager_t *this,
- chunk_t init_hash, u_int64_t *our_spi)
+ chunk_t init_hash, uint64_t *our_spi)
{
table_item_t *item;
u_int row, segment;
mutex_t *mutex;
init_hash_t *init;
- u_int64_t spi;
+ uint64_t spi;
row = chunk_hash(init_hash) & this->table_mask;
segment = row & this->segment_mask;
@@ -1174,8 +1174,8 @@ METHOD(ike_sa_manager_t, checkout_new, ike_sa_t*,
{
ike_sa_id_t *ike_sa_id;
ike_sa_t *ike_sa;
- u_int8_t ike_version;
- u_int64_t spi;
+ uint8_t ike_version;
+ uint64_t spi;
ike_version = version == IKEV1 ? IKEV1_MAJOR_VERSION : IKEV2_MAJOR_VERSION;
@@ -1208,7 +1208,7 @@ METHOD(ike_sa_manager_t, checkout_new, ike_sa_t*,
/**
* Get the message ID or message hash to detect early retransmissions
*/
-static u_int32_t get_message_id_or_hash(message_t *message)
+static uint32_t get_message_id_or_hash(message_t *message)
{
if (message->get_major_version(message) == IKEV1_MAJOR_VERSION)
{
@@ -1273,7 +1273,7 @@ METHOD(ike_sa_manager_t, checkout_by_message, ike_sa_t*,
if (is_init)
{
hasher_t *hasher;
- u_int64_t our_spi;
+ uint64_t our_spi;
chunk_t hash;
hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
@@ -1415,7 +1415,8 @@ METHOD(ike_sa_manager_t, checkout_by_config, ike_sa_t*,
{
continue;
}
- if (entry->ike_sa->get_state(entry->ike_sa) == IKE_DELETING)
+ if (entry->ike_sa->get_state(entry->ike_sa) == IKE_DELETING ||
+ entry->ike_sa->get_state(entry->ike_sa) == IKE_REKEYED)
{ /* skip IKE_SAs which are not usable, wake other waiting threads */
entry->condvar->signal(entry->condvar);
continue;
@@ -1455,7 +1456,7 @@ out:
}
METHOD(ike_sa_manager_t, checkout_by_id, ike_sa_t*,
- private_ike_sa_manager_t *this, u_int32_t id)
+ private_ike_sa_manager_t *this, uint32_t id)
{
enumerator_t *enumerator;
entry_t *entry;
@@ -2094,10 +2095,41 @@ METHOD(ike_sa_manager_t, set_spi_cb, void,
this->spi_lock->unlock(this->spi_lock);
}
+/**
+ * Destroy all entries
+ */
+static void destroy_all_entries(private_ike_sa_manager_t *this)
+{
+ enumerator_t *enumerator;
+ entry_t *entry;
+ u_int segment;
+
+ enumerator = create_table_enumerator(this);
+ while (enumerator->enumerate(enumerator, &entry, &segment))
+ {
+ charon->bus->set_sa(charon->bus, entry->ike_sa);
+ if (entry->half_open)
+ {
+ remove_half_open(this, entry);
+ }
+ if (entry->my_id && entry->other_id)
+ {
+ remove_connected_peers(this, entry);
+ }
+ if (entry->init_hash.ptr)
+ {
+ remove_init_hash(this, entry->init_hash);
+ }
+ remove_entry_at((private_enumerator_t*)enumerator);
+ entry_destroy(entry);
+ }
+ enumerator->destroy(enumerator);
+ charon->bus->set_sa(charon->bus, NULL);
+}
+
METHOD(ike_sa_manager_t, flush, void,
private_ike_sa_manager_t *this)
{
- /* destroy all list entries */
enumerator_t *enumerator;
entry_t *entry;
u_int segment;
@@ -2153,31 +2185,11 @@ METHOD(ike_sa_manager_t, flush, void,
DBG2(DBG_MGR, "destroy all entries");
/* Step 4: destroy all entries */
- enumerator = create_table_enumerator(this);
- while (enumerator->enumerate(enumerator, &entry, &segment))
- {
- charon->bus->set_sa(charon->bus, entry->ike_sa);
- if (entry->half_open)
- {
- remove_half_open(this, entry);
- }
- if (entry->my_id && entry->other_id)
- {
- remove_connected_peers(this, entry);
- }
- if (entry->init_hash.ptr)
- {
- remove_init_hash(this, entry->init_hash);
- }
- remove_entry_at((private_enumerator_t*)enumerator);
- entry_destroy(entry);
- }
- enumerator->destroy(enumerator);
- charon->bus->set_sa(charon->bus, NULL);
+ destroy_all_entries(this);
unlock_all_segments(this);
this->spi_lock->write_lock(this->spi_lock);
- this->rng->destroy(this->rng);
+ DESTROY_IF(this->rng);
this->rng = NULL;
this->spi_cb.cb = NULL;
this->spi_cb.data = NULL;
@@ -2189,7 +2201,11 @@ METHOD(ike_sa_manager_t, destroy, void,
{
u_int i;
- /* these are already cleared in flush() above */
+ /* in case new SAs were checked in after flush() was called */
+ lock_all_segments(this);
+ destroy_all_entries(this);
+ unlock_all_segments(this);
+
free(this->ike_sa_table);
free(this->half_open_table);
free(this->connected_peers_table);