From 2f3c08d268a6ead9e7d9e74b523600d76e3e5722 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Wed, 17 Feb 2016 17:31:51 +0100 Subject: [PATCH] ikev1: Allow immediate deletion of rekeyed CHILD_SAs When charon rekeys a CHILD_SA after a soft limit expired, it is only deleted after the hard limit is reached. In case of packet/byte limits this may not be the case for a long time since the packets/bytes are usually sent using the new SA. This may result in a very large number of stale CHILD_SAs and kernel states. With enough connections configured this will ultimately exhaust the memory of the system. This patch adds a strongswan.conf setting that, if enabled, causes the old CHILD_SA to be deleted by the initiator after a successful rekeying. Enabling this setting might create problems with implementations that continue to use rekeyed SAs (e.g. if the DELETE notify is lost). --- conf/options/charon.opt | 8 ++++++++ src/libcharon/sa/ikev1/tasks/quick_mode.c | 18 +++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/conf/options/charon.opt b/conf/options/charon.opt index a4e03d4..3820036 100644 --- a/conf/options/charon.opt +++ b/conf/options/charon.opt @@ -61,6 +61,14 @@ charon.crypto_test.required = no charon.crypto_test.rng_true = no Whether to test RNG with TRUE quality; requires a lot of entropy. +charon.delete_rekeyed = no + Delete CHILD_SAs right after they got successfully rekeyed (IKEv1 only). + + Delete CHILD_SAs right after they got successfully rekeyed (IKEv1 only). + Reduces the number of stale CHILD_SAs in scenarios with a lot of rekeyings. + However, this might cause problems with implementations that continue to + use rekeyed SAs until they expire. + charon.dh_exponent_ansi_x9_42 = yes Use ANSI X9.42 DH exponent size or optimum size matched to cryptographic strength. diff --git a/src/libcharon/sa/ikev1/tasks/quick_mode.c b/src/libcharon/sa/ikev1/tasks/quick_mode.c index e7d2644..b4fe046 100644 --- a/src/libcharon/sa/ikev1/tasks/quick_mode.c +++ b/src/libcharon/sa/ikev1/tasks/quick_mode.c @@ -171,6 +171,11 @@ struct private_quick_mode_t { u_int32_t rekey; /** + * Delete old child after successful rekey + */ + bool delete; + + /** * Negotiated mode, tunnel or transport */ ipsec_mode_t mode; @@ -406,8 +411,17 @@ static bool install(private_quick_mode_t *this) if (old) { charon->bus->child_rekey(charon->bus, old, this->child_sa); - /* rekeyed CHILD_SAs stay installed until they expire */ + /* rekeyed CHILD_SAs stay installed until they expire or are deleted + * by the other peer */ old->set_state(old, CHILD_REKEYED); + /* as initiator we delete the CHILD_SA if configured to do so */ + if (this->initiator && this->delete) + { + this->ike_sa->queue_task(this->ike_sa, + (task_t*)quick_delete_create(this->ike_sa, + this->proposal->get_protocol(this->proposal), + this->rekey, TRUE, FALSE)); + } } else { @@ -1450,6 +1464,8 @@ quick_mode_t *quick_mode_create(ike_sa_t *ike_sa, child_cfg_t *config, .tsi = tsi ? tsi->clone(tsi) : NULL, .tsr = tsr ? tsr->clone(tsr) : NULL, .proto = PROTO_ESP, + .delete = lib->settings->get_bool(lib->settings, + "%s.delete_rekeyed", FALSE, lib->ns), ); if (config) -- 2.7.4