controller: Optionally adhere to init limits also when initiating IKE_SAs
This commit is contained in:
@@ -434,7 +434,7 @@ static job_requeue_t initiate(private_cmd_connection_t *this)
|
|||||||
child_cfg = create_child_cfg(this, peer_cfg);
|
child_cfg = create_child_cfg(this, peer_cfg);
|
||||||
|
|
||||||
if (charon->controller->initiate(charon->controller, peer_cfg, child_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);
|
terminate(pid);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ static job_requeue_t initiate(char *config)
|
|||||||
{
|
{
|
||||||
DBG1(DBG_CFG, "initiating IKE_SA for CHILD_SA config '%s'", config);
|
DBG1(DBG_CFG, "initiating IKE_SA for CHILD_SA config '%s'", config);
|
||||||
charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
|
charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
|
||||||
NULL, NULL, 0);
|
NULL, NULL, 0, FALSE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ void start_connection(private_xpc_dispatch_t *this,
|
|||||||
peer_cfg->add_child_cfg(peer_cfg, child_cfg->get_ref(child_cfg));
|
peer_cfg->add_child_cfg(peer_cfg, child_cfg->get_ref(child_cfg));
|
||||||
|
|
||||||
if (charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
|
if (charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
|
||||||
(controller_cb_t)initiate_cb, &ike_sa, 0) == NEED_MORE)
|
(controller_cb_t)initiate_cb, &ike_sa, 0, FALSE) == NEED_MORE)
|
||||||
{
|
{
|
||||||
this->channels->add(this->channels, channel, ike_sa);
|
this->channels->add(this->channels, channel, ike_sa);
|
||||||
success = TRUE;
|
success = TRUE;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2011-2012 Tobias Brunner
|
* Copyright (C) 2011-2015 Tobias Brunner
|
||||||
* Copyright (C) 2007-2011 Martin Willi
|
* Copyright (C) 2007-2011 Martin Willi
|
||||||
* Copyright (C) 2011 revosec AG
|
* Copyright (C) 2011 revosec AG
|
||||||
* Hochschule fuer Technik Rapperswil
|
* Hochschule fuer Technik Rapperswil
|
||||||
@@ -116,6 +116,11 @@ struct interface_listener_t {
|
|||||||
* spinlock to update the IKE_SA handle properly
|
* spinlock to update the IKE_SA handle properly
|
||||||
*/
|
*/
|
||||||
spinlock_t *lock;
|
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);
|
listener->child_cfg->destroy(listener->child_cfg);
|
||||||
peer_cfg->destroy(peer_cfg);
|
peer_cfg->destroy(peer_cfg);
|
||||||
listener->status = FAILED;
|
listener->status = FAILED;
|
||||||
/* release listener */
|
|
||||||
listener_done(listener);
|
listener_done(listener);
|
||||||
return JOB_REQUEUE_NONE;
|
return JOB_REQUEUE_NONE;
|
||||||
}
|
}
|
||||||
@@ -372,6 +376,49 @@ METHOD(job_t, initiate_execute, job_requeue_t,
|
|||||||
}
|
}
|
||||||
peer_cfg->destroy(peer_cfg);
|
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 (ike_sa->initiate(ike_sa, listener->child_cfg, 0, NULL, NULL) == SUCCESS)
|
||||||
{
|
{
|
||||||
if (!listener->logger.callback)
|
if (!listener->logger.callback)
|
||||||
@@ -391,7 +438,7 @@ METHOD(job_t, initiate_execute, job_requeue_t,
|
|||||||
|
|
||||||
METHOD(controller_t, initiate, status_t,
|
METHOD(controller_t, initiate, status_t,
|
||||||
private_controller_t *this, peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
|
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;
|
interface_job_t *job;
|
||||||
status_t status;
|
status_t status;
|
||||||
@@ -414,6 +461,7 @@ METHOD(controller_t, initiate, status_t,
|
|||||||
.child_cfg = child_cfg,
|
.child_cfg = child_cfg,
|
||||||
.peer_cfg = peer_cfg,
|
.peer_cfg = peer_cfg,
|
||||||
.lock = spinlock_create(),
|
.lock = spinlock_create(),
|
||||||
|
.limits = limits,
|
||||||
},
|
},
|
||||||
.public = {
|
.public = {
|
||||||
.execute = _initiate_execute,
|
.execute = _initiate_execute,
|
||||||
|
|||||||
@@ -82,15 +82,18 @@ struct controller_t {
|
|||||||
* @param cb logging callback
|
* @param cb logging callback
|
||||||
* @param param parameter to include in each call of cb
|
* @param param parameter to include in each call of cb
|
||||||
* @param timeout timeout in ms to wait for callbacks, 0 to disable
|
* @param timeout timeout in ms to wait for callbacks, 0 to disable
|
||||||
|
* @param limits whether to check limits regarding IKE_SA initiation
|
||||||
* @return
|
* @return
|
||||||
* - SUCCESS, if CHILD_SA established
|
* - SUCCESS, if CHILD_SA established
|
||||||
* - FAILED, if setup failed
|
* - FAILED, if setup failed
|
||||||
* - NEED_MORE, if callback returned FALSE
|
* - NEED_MORE, if callback returned FALSE
|
||||||
* - OUT_OF_RES if timed out
|
* - OUT_OF_RES if timed out
|
||||||
|
* - INVALID_STATE if limits prevented initiation
|
||||||
*/
|
*/
|
||||||
status_t (*initiate)(controller_t *this,
|
status_t (*initiate)(controller_t *this,
|
||||||
peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
|
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.
|
* Terminate an IKE_SA and all of its CHILD_SAs.
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ static bool on_accept(private_load_tester_control_t *this, stream_t *io)
|
|||||||
|
|
||||||
switch (charon->controller->initiate(charon->controller,
|
switch (charon->controller->initiate(charon->controller,
|
||||||
peer_cfg, child_cfg->get_ref(child_cfg),
|
peer_cfg, child_cfg->get_ref(child_cfg),
|
||||||
(void*)initiate_cb, listener, 0))
|
(void*)initiate_cb, listener, 0, FALSE))
|
||||||
{
|
{
|
||||||
case NEED_MORE:
|
case NEED_MORE:
|
||||||
/* Callback returns FALSE once it got track of this IKE_SA.
|
/* Callback returns FALSE once it got track of this IKE_SA.
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ static job_requeue_t do_load_test(private_load_tester_plugin_t *this)
|
|||||||
|
|
||||||
charon->controller->initiate(charon->controller,
|
charon->controller->initiate(charon->controller,
|
||||||
peer_cfg, child_cfg->get_ref(child_cfg),
|
peer_cfg, child_cfg->get_ref(child_cfg),
|
||||||
NULL, NULL, 0);
|
NULL, NULL, 0, FALSE);
|
||||||
if (s)
|
if (s)
|
||||||
{
|
{
|
||||||
sleep(s);
|
sleep(s);
|
||||||
|
|||||||
@@ -314,7 +314,7 @@ static job_requeue_t initiate_config(peer_cfg_t *peer_cfg)
|
|||||||
peer_cfg->get_ref(peer_cfg);
|
peer_cfg->get_ref(peer_cfg);
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
charon->controller->initiate(charon->controller,
|
charon->controller->initiate(charon->controller,
|
||||||
peer_cfg, child_cfg, NULL, NULL, 0);
|
peer_cfg, child_cfg, NULL, NULL, 0, FALSE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -488,7 +488,7 @@ static void request_control_initiate(xmlTextReaderPtr reader,
|
|||||||
{
|
{
|
||||||
status = charon->controller->initiate(charon->controller,
|
status = charon->controller->initiate(charon->controller,
|
||||||
peer, child, (controller_cb_t)xml_callback,
|
peer, child, (controller_cb_t)xml_callback,
|
||||||
writer, 0);
|
writer, 0, FALSE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ static void charon_initiate(private_stroke_control_t *this, peer_cfg_t *peer_cfg
|
|||||||
if (msg->output_verbosity < 0)
|
if (msg->output_verbosity < 0)
|
||||||
{
|
{
|
||||||
charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
|
charon->controller->initiate(charon->controller, peer_cfg, child_cfg,
|
||||||
NULL, NULL, 0);
|
NULL, NULL, 0, FALSE);
|
||||||
}
|
}
|
||||||
else
|
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,
|
status = charon->controller->initiate(charon->controller,
|
||||||
peer_cfg, child_cfg, (controller_cb_t)stroke_log,
|
peer_cfg, child_cfg, (controller_cb_t)stroke_log,
|
||||||
&info, this->timeout);
|
&info, this->timeout, FALSE);
|
||||||
switch (status)
|
switch (status)
|
||||||
{
|
{
|
||||||
case SUCCESS:
|
case SUCCESS:
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ static void initiate(private_uci_control_t *this, char *name)
|
|||||||
if (enumerator->enumerate(enumerator, &child_cfg) &&
|
if (enumerator->enumerate(enumerator, &child_cfg) &&
|
||||||
charon->controller->initiate(charon->controller, peer_cfg,
|
charon->controller->initiate(charon->controller, peer_cfg,
|
||||||
child_cfg->get_ref(child_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);
|
write_fifo(this, "connection '%s' established\n", name);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1589,7 +1589,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));
|
DBG1(DBG_CFG, "initiating '%s'", child_cfg->get_name(child_cfg));
|
||||||
charon->controller->initiate(charon->controller,
|
charon->controller->initiate(charon->controller,
|
||||||
peer_cfg->get_ref(peer_cfg), child_cfg->get_ref(child_cfg),
|
peer_cfg->get_ref(peer_cfg), child_cfg->get_ref(child_cfg),
|
||||||
NULL, NULL, 0);
|
NULL, NULL, 0, FALSE);
|
||||||
break;
|
break;
|
||||||
case ACTION_ROUTE:
|
case ACTION_ROUTE:
|
||||||
DBG1(DBG_CFG, "installing '%s'", child_cfg->get_name(child_cfg));
|
DBG1(DBG_CFG, "installing '%s'", child_cfg->get_name(child_cfg));
|
||||||
|
|||||||
@@ -184,8 +184,8 @@ CALLBACK(initiate, vici_message_t*,
|
|||||||
{
|
{
|
||||||
return send_reply(this, "CHILD_SA config '%s' not found", child);
|
return send_reply(this, "CHILD_SA config '%s' not found", child);
|
||||||
}
|
}
|
||||||
switch (charon->controller->initiate(charon->controller,
|
switch (charon->controller->initiate(charon->controller, peer_cfg,
|
||||||
peer_cfg, child_cfg, (controller_cb_t)log_vici, &log, timeout))
|
child_cfg, (controller_cb_t)log_vici, &log, timeout, FALSE))
|
||||||
{
|
{
|
||||||
case SUCCESS:
|
case SUCCESS:
|
||||||
return send_reply(this, NULL);
|
return send_reply(this, NULL);
|
||||||
|
|||||||
@@ -119,8 +119,8 @@ METHOD(job_t, initiate, job_requeue_t,
|
|||||||
/* we need an additional reference because initiate consumes one */
|
/* we need an additional reference because initiate consumes one */
|
||||||
mediation_cfg->get_ref(mediation_cfg);
|
mediation_cfg->get_ref(mediation_cfg);
|
||||||
|
|
||||||
if (charon->controller->initiate(charon->controller, mediation_cfg,
|
if (charon->controller->initiate(charon->controller, mediation_cfg, NULL,
|
||||||
NULL, (controller_cb_t)initiate_callback, this, 0) != SUCCESS)
|
(controller_cb_t)initiate_callback, this, 0, FALSE) != SUCCESS)
|
||||||
{
|
{
|
||||||
mediation_cfg->destroy(mediation_cfg);
|
mediation_cfg->destroy(mediation_cfg);
|
||||||
mediated_cfg->destroy(mediated_cfg);
|
mediated_cfg->destroy(mediated_cfg);
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ METHOD(job_t, execute, job_requeue_t,
|
|||||||
charon->controller->initiate(charon->controller,
|
charon->controller->initiate(charon->controller,
|
||||||
peer_cfg->get_ref(peer_cfg),
|
peer_cfg->get_ref(peer_cfg),
|
||||||
child_cfg->get_ref(child_cfg),
|
child_cfg->get_ref(child_cfg),
|
||||||
NULL, NULL, 0);
|
NULL, NULL, 0, FALSE);
|
||||||
break;
|
break;
|
||||||
case ACTION_ROUTE:
|
case ACTION_ROUTE:
|
||||||
DBG1(DBG_JOB, "start action: route '%s'", name);
|
DBG1(DBG_JOB, "start action: route '%s'", name);
|
||||||
|
|||||||
Reference in New Issue
Block a user