diff options
author | Timo Teräs <timo.teras@iki.fi> | 2015-07-28 11:33:38 +0300 |
---|---|---|
committer | Timo Teräs <timo.teras@iki.fi> | 2015-07-28 11:35:47 +0300 |
commit | fc1ceeb02b3e149645205e67bcc009e742140590 (patch) | |
tree | b559837b40485a7c0f77ce6459c03f131191283d /main/strongswan/0202-controller-Optionally-adhere-to-init-limits-also-whe.patch | |
parent | c3aa1460dbeb4e1e10972fc00314d7a80413707e (diff) | |
download | aports-fc1ceeb02b3e149645205e67bcc009e742140590.tar.bz2 aports-fc1ceeb02b3e149645205e67bcc009e742140590.tar.xz |
main/strongswan: cherry-pick upstream fixes
also fixes a minor memory leak in patch 1001 (the offending hunk is
now just deleted, as other upstream commits fixed the issue it tried
to address)
Diffstat (limited to 'main/strongswan/0202-controller-Optionally-adhere-to-init-limits-also-whe.patch')
-rw-r--r-- | main/strongswan/0202-controller-Optionally-adhere-to-init-limits-also-whe.patch | 317 |
1 files changed, 317 insertions, 0 deletions
diff --git a/main/strongswan/0202-controller-Optionally-adhere-to-init-limits-also-whe.patch b/main/strongswan/0202-controller-Optionally-adhere-to-init-limits-also-whe.patch new file mode 100644 index 0000000000..fbc54c11c4 --- /dev/null +++ b/main/strongswan/0202-controller-Optionally-adhere-to-init-limits-also-whe.patch @@ -0,0 +1,317 @@ +From 0d6412ab81fbf0376cc99e9419de417e58dc0e72 Mon Sep 17 00:00:00 2001 +From: Tobias Brunner <tobias@strongswan.org> +Date: Thu, 16 Jul 2015 17:21:54 +0200 +Subject: [PATCH] controller: Optionally adhere to init limits also when + initiating IKE_SAs + +--- + src/charon-cmd/cmd/cmd_connection.c | 2 +- + src/conftest/actions.c | 2 +- + src/libcharon/control/controller.c | 54 ++++++++++++++++++++-- + src/libcharon/control/controller.h | 5 +- + .../plugins/load_tester/load_tester_control.c | 2 +- + .../plugins/load_tester/load_tester_plugin.c | 2 +- + src/libcharon/plugins/medcli/medcli_config.c | 2 +- + src/libcharon/plugins/smp/smp.c | 2 +- + src/libcharon/plugins/stroke/stroke_control.c | 4 +- + src/libcharon/plugins/uci/uci_control.c | 2 +- + src/libcharon/plugins/vici/vici_config.c | 2 +- + src/libcharon/plugins/vici/vici_control.c | 4 +- + .../processing/jobs/initiate_mediation_job.c | 4 +- + src/libcharon/processing/jobs/start_action_job.c | 2 +- + 15 files changed, 71 insertions(+), 20 deletions(-) + +diff --git a/src/charon-cmd/cmd/cmd_connection.c b/src/charon-cmd/cmd/cmd_connection.c +index 2c0b7b9..0c6a504 100644 +--- a/src/charon-cmd/cmd/cmd_connection.c ++++ b/src/charon-cmd/cmd/cmd_connection.c +@@ -434,7 +434,7 @@ static job_requeue_t initiate(private_cmd_connection_t *this) + child_cfg = create_child_cfg(this, peer_cfg); + + if (charon->controller->initiate(charon->controller, peer_cfg, child_cfg, +- controller_cb_empty, NULL, 0) != SUCCESS) ++ controller_cb_empty, NULL, 0, FALSE) != SUCCESS) + { + terminate(pid); + } +diff --git a/src/conftest/actions.c b/src/conftest/actions.c +index 474672c..256b63d 100644 +--- a/src/conftest/actions.c ++++ b/src/conftest/actions.c +@@ -65,7 +65,7 @@ static job_requeue_t initiate(char *config) + { + DBG1(DBG_CFG, "initiating IKE_SA for CHILD_SA config '%s'", config); + charon->controller->initiate(charon->controller, peer_cfg, child_cfg, +- NULL, NULL, 0); ++ NULL, NULL, 0, FALSE); + } + else + { +diff --git a/src/libcharon/control/controller.c b/src/libcharon/control/controller.c +index fd8349e..097f5ac 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); ++ 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 02f4ebb..5ffeac5 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. +diff --git a/src/libcharon/plugins/load_tester/load_tester_control.c b/src/libcharon/plugins/load_tester/load_tester_control.c +index 5f089f5..24076d4 100644 +--- a/src/libcharon/plugins/load_tester/load_tester_control.c ++++ b/src/libcharon/plugins/load_tester/load_tester_control.c +@@ -239,7 +239,7 @@ static bool on_accept(private_load_tester_control_t *this, stream_t *io) + + switch (charon->controller->initiate(charon->controller, + peer_cfg, child_cfg->get_ref(child_cfg), +- (void*)initiate_cb, listener, 0)) ++ (void*)initiate_cb, listener, 0, FALSE)) + { + case NEED_MORE: + /* Callback returns FALSE once it got track of this IKE_SA. +diff --git a/src/libcharon/plugins/load_tester/load_tester_plugin.c b/src/libcharon/plugins/load_tester/load_tester_plugin.c +index e684f22..c7380b9 100644 +--- a/src/libcharon/plugins/load_tester/load_tester_plugin.c ++++ b/src/libcharon/plugins/load_tester/load_tester_plugin.c +@@ -152,7 +152,7 @@ static job_requeue_t do_load_test(private_load_tester_plugin_t *this) + + charon->controller->initiate(charon->controller, + peer_cfg, child_cfg->get_ref(child_cfg), +- NULL, NULL, 0); ++ NULL, NULL, 0, FALSE); + if (s) + { + sleep(s); +diff --git a/src/libcharon/plugins/medcli/medcli_config.c b/src/libcharon/plugins/medcli/medcli_config.c +index 1fb57b9..25b1383 100644 +--- a/src/libcharon/plugins/medcli/medcli_config.c ++++ b/src/libcharon/plugins/medcli/medcli_config.c +@@ -314,7 +314,7 @@ static job_requeue_t initiate_config(peer_cfg_t *peer_cfg) + peer_cfg->get_ref(peer_cfg); + enumerator->destroy(enumerator); + charon->controller->initiate(charon->controller, +- peer_cfg, child_cfg, NULL, NULL, 0); ++ peer_cfg, child_cfg, NULL, NULL, 0, FALSE); + } + else + { +diff --git a/src/libcharon/plugins/smp/smp.c b/src/libcharon/plugins/smp/smp.c +index 04bf382..2aa061f 100644 +--- a/src/libcharon/plugins/smp/smp.c ++++ b/src/libcharon/plugins/smp/smp.c +@@ -488,7 +488,7 @@ static void request_control_initiate(xmlTextReaderPtr reader, + { + status = charon->controller->initiate(charon->controller, + peer, child, (controller_cb_t)xml_callback, +- writer, 0); ++ writer, 0, FALSE); + } + else + { +diff --git a/src/libcharon/plugins/stroke/stroke_control.c b/src/libcharon/plugins/stroke/stroke_control.c +index 0084fbf..0125d17 100644 +--- a/src/libcharon/plugins/stroke/stroke_control.c ++++ b/src/libcharon/plugins/stroke/stroke_control.c +@@ -109,7 +109,7 @@ static void charon_initiate(private_stroke_control_t *this, peer_cfg_t *peer_cfg + if (msg->output_verbosity < 0) + { + charon->controller->initiate(charon->controller, peer_cfg, child_cfg, +- NULL, NULL, 0); ++ NULL, NULL, 0, FALSE); + } + else + { +@@ -118,7 +118,7 @@ static void charon_initiate(private_stroke_control_t *this, peer_cfg_t *peer_cfg + + status = charon->controller->initiate(charon->controller, + peer_cfg, child_cfg, (controller_cb_t)stroke_log, +- &info, this->timeout); ++ &info, this->timeout, FALSE); + switch (status) + { + case SUCCESS: +diff --git a/src/libcharon/plugins/uci/uci_control.c b/src/libcharon/plugins/uci/uci_control.c +index cebc389..a7d26e6 100644 +--- a/src/libcharon/plugins/uci/uci_control.c ++++ b/src/libcharon/plugins/uci/uci_control.c +@@ -147,7 +147,7 @@ static void initiate(private_uci_control_t *this, char *name) + if (enumerator->enumerate(enumerator, &child_cfg) && + charon->controller->initiate(charon->controller, peer_cfg, + child_cfg->get_ref(child_cfg), +- controller_cb_empty, NULL, 0) == SUCCESS) ++ controller_cb_empty, NULL, 0, FALSE) == SUCCESS) + { + write_fifo(this, "connection '%s' established\n", name); + } +diff --git a/src/libcharon/plugins/vici/vici_config.c b/src/libcharon/plugins/vici/vici_config.c +index d232599..dfea2ab 100644 +--- a/src/libcharon/plugins/vici/vici_config.c ++++ b/src/libcharon/plugins/vici/vici_config.c +@@ -1558,7 +1558,7 @@ static void run_start_action(private_vici_config_t *this, peer_cfg_t *peer_cfg, + DBG1(DBG_CFG, "initiating '%s'", child_cfg->get_name(child_cfg)); + charon->controller->initiate(charon->controller, + peer_cfg->get_ref(peer_cfg), child_cfg->get_ref(child_cfg), +- NULL, NULL, 0); ++ NULL, NULL, 0, FALSE); + break; + case ACTION_ROUTE: + DBG1(DBG_CFG, "installing '%s'", child_cfg->get_name(child_cfg)); +diff --git a/src/libcharon/plugins/vici/vici_control.c b/src/libcharon/plugins/vici/vici_control.c +index 01d5036..e568239 100644 +--- a/src/libcharon/plugins/vici/vici_control.c ++++ b/src/libcharon/plugins/vici/vici_control.c +@@ -184,8 +184,8 @@ CALLBACK(initiate, vici_message_t*, + { + return send_reply(this, "CHILD_SA config '%s' not found", child); + } +- switch (charon->controller->initiate(charon->controller, +- peer_cfg, child_cfg, (controller_cb_t)log_vici, &log, timeout)) ++ switch (charon->controller->initiate(charon->controller, peer_cfg, ++ child_cfg, (controller_cb_t)log_vici, &log, timeout, FALSE)) + { + case SUCCESS: + return send_reply(this, NULL); +diff --git a/src/libcharon/processing/jobs/initiate_mediation_job.c b/src/libcharon/processing/jobs/initiate_mediation_job.c +index 17ab830..5b5fb9d 100644 +--- a/src/libcharon/processing/jobs/initiate_mediation_job.c ++++ b/src/libcharon/processing/jobs/initiate_mediation_job.c +@@ -119,8 +119,8 @@ METHOD(job_t, initiate, job_requeue_t, + /* we need an additional reference because initiate consumes one */ + mediation_cfg->get_ref(mediation_cfg); + +- if (charon->controller->initiate(charon->controller, mediation_cfg, +- NULL, (controller_cb_t)initiate_callback, this, 0) != SUCCESS) ++ if (charon->controller->initiate(charon->controller, mediation_cfg, NULL, ++ (controller_cb_t)initiate_callback, this, 0, FALSE) != SUCCESS) + { + mediation_cfg->destroy(mediation_cfg); + mediated_cfg->destroy(mediated_cfg); +diff --git a/src/libcharon/processing/jobs/start_action_job.c b/src/libcharon/processing/jobs/start_action_job.c +index 981473b..5e88ac2 100644 +--- a/src/libcharon/processing/jobs/start_action_job.c ++++ b/src/libcharon/processing/jobs/start_action_job.c +@@ -61,7 +61,7 @@ METHOD(job_t, execute, job_requeue_t, + charon->controller->initiate(charon->controller, + peer_cfg->get_ref(peer_cfg), + child_cfg->get_ref(child_cfg), +- NULL, NULL, 0); ++ NULL, NULL, 0, FALSE); + break; + case ACTION_ROUTE: + DBG1(DBG_JOB, "start action: route '%s'", name); +-- +2.4.6 + |