diff options
author | Yves-Alexis Perez <corsac@debian.org> | 2015-10-22 11:43:58 +0200 |
---|---|---|
committer | Yves-Alexis Perez <corsac@debian.org> | 2015-10-22 11:43:58 +0200 |
commit | 5dca9ea0e2931f0e2a056c7964d311bcc30a01b8 (patch) | |
tree | 037f1ec5bb860846938ddcf29771c24e9c529be0 /src/libcharon/control | |
parent | b238cf34df3fe4476ae6b7012e7cb3e9769d4d51 (diff) | |
download | vyos-strongswan-5dca9ea0e2931f0e2a056c7964d311bcc30a01b8.tar.gz vyos-strongswan-5dca9ea0e2931f0e2a056c7964d311bcc30a01b8.zip |
Imported Upstream version 5.3.3
Diffstat (limited to 'src/libcharon/control')
-rw-r--r-- | src/libcharon/control/controller.c | 54 | ||||
-rw-r--r-- | src/libcharon/control/controller.h | 5 |
2 files changed, 55 insertions, 4 deletions
diff --git a/src/libcharon/control/controller.c b/src/libcharon/control/controller.c index fd8349e2f..6dd54b473 100644 --- a/src/libcharon/control/controller.c +++ b/src/libcharon/control/controller.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2012 Tobias Brunner + * Copyright (C) 2011-2015 Tobias Brunner * Copyright (C) 2007-2011 Martin Willi * Copyright (C) 2011 revosec AG * Hochschule fuer Technik Rapperswil @@ -116,6 +116,11 @@ struct interface_listener_t { * spinlock to update the IKE_SA handle properly */ spinlock_t *lock; + + /** + * whether to check limits + */ + bool limits; }; @@ -358,7 +363,6 @@ METHOD(job_t, initiate_execute, job_requeue_t, listener->child_cfg->destroy(listener->child_cfg); peer_cfg->destroy(peer_cfg); listener->status = FAILED; - /* release listener */ listener_done(listener); return JOB_REQUEUE_NONE; } @@ -372,6 +376,49 @@ METHOD(job_t, initiate_execute, job_requeue_t, } peer_cfg->destroy(peer_cfg); + if (listener->limits && ike_sa->get_state(ike_sa) == IKE_CREATED) + { /* only check if we are not reusing an IKE_SA */ + u_int half_open, limit_half_open, limit_job_load; + + half_open = charon->ike_sa_manager->get_half_open_count( + charon->ike_sa_manager, NULL, FALSE); + limit_half_open = lib->settings->get_int(lib->settings, + "%s.init_limit_half_open", 0, lib->ns); + limit_job_load = lib->settings->get_int(lib->settings, + "%s.init_limit_job_load", 0, lib->ns); + if (limit_half_open && half_open >= limit_half_open) + { + DBG1(DBG_IKE, "abort IKE_SA initiation, half open IKE_SA count of " + "%d exceeds limit of %d", half_open, limit_half_open); + charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, + ike_sa); + listener->child_cfg->destroy(listener->child_cfg); + listener->status = INVALID_STATE; + listener_done(listener); + return JOB_REQUEUE_NONE; + } + if (limit_job_load) + { + u_int jobs = 0, i; + + for (i = 0; i < JOB_PRIO_MAX; i++) + { + jobs += lib->processor->get_job_load(lib->processor, i); + } + if (jobs > limit_job_load) + { + DBG1(DBG_IKE, "abort IKE_SA initiation, job load of %d exceeds " + "limit of %d", jobs, limit_job_load); + charon->ike_sa_manager->checkin_and_destroy( + charon->ike_sa_manager, ike_sa); + listener->child_cfg->destroy(listener->child_cfg); + listener->status = INVALID_STATE; + listener_done(listener); + return JOB_REQUEUE_NONE; + } + } + } + if (ike_sa->initiate(ike_sa, listener->child_cfg, 0, NULL, NULL) == SUCCESS) { if (!listener->logger.callback) @@ -391,7 +438,7 @@ METHOD(job_t, initiate_execute, job_requeue_t, METHOD(controller_t, initiate, status_t, private_controller_t *this, peer_cfg_t *peer_cfg, child_cfg_t *child_cfg, - controller_cb_t callback, void *param, u_int timeout) + controller_cb_t callback, void *param, u_int timeout, bool limits) { interface_job_t *job; status_t status; @@ -414,6 +461,7 @@ METHOD(controller_t, initiate, status_t, .child_cfg = child_cfg, .peer_cfg = peer_cfg, .lock = spinlock_create(), + .limits = limits, }, .public = { .execute = _initiate_execute, diff --git a/src/libcharon/control/controller.h b/src/libcharon/control/controller.h index 02f4ebb2b..5ffeac522 100644 --- a/src/libcharon/control/controller.h +++ b/src/libcharon/control/controller.h @@ -82,15 +82,18 @@ struct controller_t { * @param cb logging callback * @param param parameter to include in each call of cb * @param timeout timeout in ms to wait for callbacks, 0 to disable + * @param limits whether to check limits regarding IKE_SA initiation * @return * - SUCCESS, if CHILD_SA established * - FAILED, if setup failed * - NEED_MORE, if callback returned FALSE * - OUT_OF_RES if timed out + * - INVALID_STATE if limits prevented initiation */ status_t (*initiate)(controller_t *this, peer_cfg_t *peer_cfg, child_cfg_t *child_cfg, - controller_cb_t callback, void *param, u_int timeout); + controller_cb_t callback, void *param, u_int timeout, + bool limits); /** * Terminate an IKE_SA and all of its CHILD_SAs. |