summaryrefslogtreecommitdiff
path: root/user/strongswan/0205-ike-Adhere-to-IKE_SA-limit-when-checking-out-by-conf.patch
diff options
context:
space:
mode:
Diffstat (limited to 'user/strongswan/0205-ike-Adhere-to-IKE_SA-limit-when-checking-out-by-conf.patch')
-rw-r--r--user/strongswan/0205-ike-Adhere-to-IKE_SA-limit-when-checking-out-by-conf.patch104
1 files changed, 104 insertions, 0 deletions
diff --git a/user/strongswan/0205-ike-Adhere-to-IKE_SA-limit-when-checking-out-by-conf.patch b/user/strongswan/0205-ike-Adhere-to-IKE_SA-limit-when-checking-out-by-conf.patch
new file mode 100644
index 000000000..cc14dab02
--- /dev/null
+++ b/user/strongswan/0205-ike-Adhere-to-IKE_SA-limit-when-checking-out-by-conf.patch
@@ -0,0 +1,104 @@
+From 5a5b26a7dce4c112f62882cfe16dc37659d766e8 Mon Sep 17 00:00:00 2001
+From: Tobias Brunner <tobias@strongswan.org>
+Date: Fri, 17 Jul 2015 11:53:58 +0200
+Subject: [PATCH 1/5] ike: Adhere to IKE_SA limit when checking out by config
+
+This prevents new SAs from getting created if we hit the global IKE_SA
+limit (we still allow checkout_new(), which is used for rekeying).
+---
+ src/libcharon/sa/ike_sa_manager.c | 71 ++++++++++++++++++++-------------------
+ 1 file changed, 37 insertions(+), 34 deletions(-)
+
+diff --git a/src/libcharon/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c
+index ce44207..37d49da 100644
+--- a/src/libcharon/sa/ike_sa_manager.c
++++ b/src/libcharon/sa/ike_sa_manager.c
+@@ -1419,48 +1419,51 @@ METHOD(ike_sa_manager_t, checkout_by_config, ike_sa_t*,
+
+ DBG2(DBG_MGR, "checkout IKE_SA by config");
+
+- if (!this->reuse_ikesa && peer_cfg->get_ike_version(peer_cfg) != IKEV1)
+- { /* IKE_SA reuse disabled by config (not possible for IKEv1) */
+- ike_sa = checkout_new(this, peer_cfg->get_ike_version(peer_cfg), TRUE);
+- charon->bus->set_sa(charon->bus, ike_sa);
+- goto out;
+- }
+-
+- enumerator = create_table_enumerator(this);
+- while (enumerator->enumerate(enumerator, &entry, &segment))
++ if (this->reuse_ikesa || peer_cfg->get_ike_version(peer_cfg) == IKEV1)
+ {
+- if (!wait_for_entry(this, entry, segment))
++ enumerator = create_table_enumerator(this);
++ while (enumerator->enumerate(enumerator, &entry, &segment))
+ {
+- continue;
+- }
+- 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;
+- }
+-
+- current_peer = entry->ike_sa->get_peer_cfg(entry->ike_sa);
+- if (current_peer && current_peer->equals(current_peer, peer_cfg))
+- {
+- current_ike = current_peer->get_ike_cfg(current_peer);
+- if (current_ike->equals(current_ike, peer_cfg->get_ike_cfg(peer_cfg)))
++ if (!wait_for_entry(this, entry, segment))
+ {
+- entry->checked_out = thread_current();
+- ike_sa = entry->ike_sa;
+- DBG2(DBG_MGR, "found existing IKE_SA %u with a '%s' config",
+- ike_sa->get_unique_id(ike_sa),
+- current_peer->get_name(current_peer));
+- break;
++ continue;
+ }
++ 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;
++ }
++ current_peer = entry->ike_sa->get_peer_cfg(entry->ike_sa);
++ if (current_peer && current_peer->equals(current_peer, peer_cfg))
++ {
++ current_ike = current_peer->get_ike_cfg(current_peer);
++ if (current_ike->equals(current_ike,
++ peer_cfg->get_ike_cfg(peer_cfg)))
++ {
++ entry->checked_out = thread_current();
++ ike_sa = entry->ike_sa;
++ DBG2(DBG_MGR, "found existing IKE_SA %u with a '%s' config",
++ ike_sa->get_unique_id(ike_sa),
++ current_peer->get_name(current_peer));
++ break;
++ }
++ }
++ /* other threads might be waiting for this entry */
++ entry->condvar->signal(entry->condvar);
+ }
+- /* other threads might be waiting for this entry */
+- entry->condvar->signal(entry->condvar);
++ enumerator->destroy(enumerator);
+ }
+- enumerator->destroy(enumerator);
+
+ if (!ike_sa)
+- { /* no IKE_SA using such a config, hand out a new */
++ { /* no IKE_SA using such a config, or reuse disabled, hand out a new */
++ if (this->ikesa_limit &&
++ this->public.get_count(&this->public) >= this->ikesa_limit)
++ {
++ DBG1(DBG_MGR, "IKE_SA creation failed, hitting IKE_SA limit (%u)",
++ this->ikesa_limit);
++ return NULL;
++ }
+ ike_sa = checkout_new(this, peer_cfg->get_ike_version(peer_cfg), TRUE);
+ }
+ charon->bus->set_sa(charon->bus, ike_sa);
+--
+2.5.0
+