From: Tobias Brunner <[email protected]>

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

_______________________________________________
Dev mailing list
[email protected]
https://lists.strongswan.org/mailman/listinfo/dev

Reply via email to