[strongSwan-dev] [PATCH 1/4] ike: Adhere to IKE_SA limit when checking out by config
Timo Teräs
timo.teras at iki.fi
Wed Mar 30 09:00:04 CEST 2016
From: Tobias Brunner <tobias at strongswan.org>
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 | 69 ++++++++++++++++++++-------------------
1 file changed, 36 insertions(+), 33 deletions(-)
diff --git a/src/libcharon/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c
index 307ea3b..e8190a9 100644
--- a/src/libcharon/sa/ike_sa_manager.c
+++ b/src/libcharon/sa/ike_sa_manager.c
@@ -1401,47 +1401,50 @@ 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)
- { /* 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)
+ { /* 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.7.4
More information about the Dev
mailing list