Merge branch 'ikesa-force-destroy'
Adds new options to force the local destruction of an IKE_SA (after trying to send a DELETE first). This might be useful in situations where it's known the other end is not reachable or already deleted the IKE_SA so there is no point in retransmitting the DELETE and waiting for a response.
This commit is contained in:
@@ -741,7 +741,7 @@ static gboolean do_disconnect(gpointer plugin)
|
|||||||
{
|
{
|
||||||
id = ike_sa->get_unique_id(ike_sa);
|
id = ike_sa->get_unique_id(ike_sa);
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
charon->controller->terminate_ike(charon->controller, id,
|
charon->controller->terminate_ike(charon->controller, id, FALSE,
|
||||||
controller_cb_empty, NULL, 0);
|
controller_cb_empty, NULL, 0);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -209,7 +209,8 @@ static job_requeue_t close_ike(char *config)
|
|||||||
if (id)
|
if (id)
|
||||||
{
|
{
|
||||||
DBG1(DBG_CFG, "closing IKE_SA '%s'", config);
|
DBG1(DBG_CFG, "closing IKE_SA '%s'", config);
|
||||||
charon->controller->terminate_ike(charon->controller, id, NULL, NULL, 0);
|
charon->controller->terminate_ike(charon->controller, id, FALSE, NULL,
|
||||||
|
NULL, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -401,7 +401,7 @@ static void close_tun_device(private_android_service_t *this)
|
|||||||
CALLBACK(terminate, job_requeue_t,
|
CALLBACK(terminate, job_requeue_t,
|
||||||
uint32_t *id)
|
uint32_t *id)
|
||||||
{
|
{
|
||||||
charon->controller->terminate_ike(charon->controller, *id,
|
charon->controller->terminate_ike(charon->controller, *id, FALSE,
|
||||||
controller_cb_empty, NULL, 0);
|
controller_cb_empty, NULL, 0);
|
||||||
return JOB_REQUEUE_NONE;
|
return JOB_REQUEUE_NONE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ static void stop_connection(private_xpc_channels_t *this, uint32_t ike_sa,
|
|||||||
{
|
{
|
||||||
status_t status;
|
status_t status;
|
||||||
|
|
||||||
status = charon->controller->terminate_ike(charon->controller, ike_sa,
|
status = charon->controller->terminate_ike(charon->controller, ike_sa, FALSE,
|
||||||
NULL, NULL, 0);
|
NULL, NULL, 0);
|
||||||
xpc_dictionary_set_bool(reply, "success", status != NOT_FOUND);
|
xpc_dictionary_set_bool(reply, "success", status != NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -117,10 +117,17 @@ struct interface_listener_t {
|
|||||||
*/
|
*/
|
||||||
spinlock_t *lock;
|
spinlock_t *lock;
|
||||||
|
|
||||||
/**
|
union {
|
||||||
* whether to check limits
|
/**
|
||||||
*/
|
* whether to check limits during initiation
|
||||||
bool limits;
|
*/
|
||||||
|
bool limits;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* whether to force termination
|
||||||
|
*/
|
||||||
|
bool force;
|
||||||
|
} options;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -423,7 +430,7 @@ 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)
|
if (listener->options.limits && ike_sa->get_state(ike_sa) == IKE_CREATED)
|
||||||
{ /* only check if we are not reusing an IKE_SA */
|
{ /* only check if we are not reusing an IKE_SA */
|
||||||
u_int half_open, limit_half_open, limit_job_load;
|
u_int half_open, limit_half_open, limit_job_load;
|
||||||
|
|
||||||
@@ -508,7 +515,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,
|
.options.limits = limits,
|
||||||
},
|
},
|
||||||
.public = {
|
.public = {
|
||||||
.execute = _initiate_execute,
|
.execute = _initiate_execute,
|
||||||
@@ -557,8 +564,8 @@ METHOD(job_t, terminate_ike_execute, job_requeue_t,
|
|||||||
listener->ike_sa = ike_sa;
|
listener->ike_sa = ike_sa;
|
||||||
listener->lock->unlock(listener->lock);
|
listener->lock->unlock(listener->lock);
|
||||||
|
|
||||||
if (ike_sa->delete(ike_sa) != DESTROY_ME)
|
if (ike_sa->delete(ike_sa, listener->options.force) != DESTROY_ME)
|
||||||
{ /* delete failed */
|
{ /* delete queued */
|
||||||
listener->status = FAILED;
|
listener->status = FAILED;
|
||||||
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
|
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
|
||||||
}
|
}
|
||||||
@@ -575,7 +582,7 @@ METHOD(job_t, terminate_ike_execute, job_requeue_t,
|
|||||||
}
|
}
|
||||||
|
|
||||||
METHOD(controller_t, terminate_ike, status_t,
|
METHOD(controller_t, terminate_ike, status_t,
|
||||||
controller_t *this, uint32_t unique_id,
|
controller_t *this, uint32_t unique_id, bool force,
|
||||||
controller_cb_t callback, void *param, u_int timeout)
|
controller_cb_t callback, void *param, u_int timeout)
|
||||||
{
|
{
|
||||||
interface_job_t *job;
|
interface_job_t *job;
|
||||||
@@ -610,13 +617,24 @@ METHOD(controller_t, terminate_ike, status_t,
|
|||||||
|
|
||||||
if (callback == NULL)
|
if (callback == NULL)
|
||||||
{
|
{
|
||||||
|
job->listener.options.force = force;
|
||||||
terminate_ike_execute(job);
|
terminate_ike_execute(job);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (!timeout)
|
||||||
|
{
|
||||||
|
job->listener.options.force = force;
|
||||||
|
}
|
||||||
if (wait_for_listener(job, timeout))
|
if (wait_for_listener(job, timeout))
|
||||||
{
|
{
|
||||||
job->listener.status = OUT_OF_RES;
|
job->listener.status = OUT_OF_RES;
|
||||||
|
|
||||||
|
if (force)
|
||||||
|
{ /* force termination once timeout is reached */
|
||||||
|
job->listener.options.force = TRUE;
|
||||||
|
terminate_ike_execute(job);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
status = job->listener.status;
|
status = job->listener.status;
|
||||||
|
|||||||
@@ -102,6 +102,11 @@ struct controller_t {
|
|||||||
* until the IKE_SA is properly deleted, or the call timed out.
|
* until the IKE_SA is properly deleted, or the call timed out.
|
||||||
*
|
*
|
||||||
* @param unique_id unique id of the IKE_SA to terminate.
|
* @param unique_id unique id of the IKE_SA to terminate.
|
||||||
|
* @param force whether to immediately destroy the IKE_SA without
|
||||||
|
* waiting for a response or retransmitting the delete,
|
||||||
|
* if a callback is provided and timeout is > 0 the
|
||||||
|
* IKE_SA is destroyed once the timeout is reached but
|
||||||
|
* retransmits are sent until then
|
||||||
* @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
|
||||||
@@ -112,7 +117,7 @@ struct controller_t {
|
|||||||
* - OUT_OF_RES if timed out
|
* - OUT_OF_RES if timed out
|
||||||
*/
|
*/
|
||||||
status_t (*terminate_ike)(controller_t *this, uint32_t unique_id,
|
status_t (*terminate_ike)(controller_t *this, uint32_t unique_id,
|
||||||
controller_cb_t callback, void *param,
|
bool force, controller_cb_t callback, void *param,
|
||||||
u_int timeout);
|
u_int timeout);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -415,7 +415,7 @@ static void request_control_terminate(xmlTextReaderPtr reader,
|
|||||||
if (ike)
|
if (ike)
|
||||||
{
|
{
|
||||||
status = charon->controller->terminate_ike(
|
status = charon->controller->terminate_ike(
|
||||||
charon->controller, id,
|
charon->controller, id, FALSE,
|
||||||
(controller_cb_t)xml_callback, writer, 0);
|
(controller_cb_t)xml_callback, writer, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -316,7 +316,8 @@ static void charon_terminate(private_stroke_control_t *this, uint32_t id,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
status = charon->controller->terminate_ike(charon->controller, id,
|
status = charon->controller->terminate_ike(charon->controller, id,
|
||||||
(controller_cb_t)stroke_log, &info, this->timeout);
|
FALSE, (controller_cb_t)stroke_log, &info,
|
||||||
|
this->timeout);
|
||||||
}
|
}
|
||||||
report_terminate_status(this, status, out, id, child);
|
report_terminate_status(this, status, out, id, child);
|
||||||
}
|
}
|
||||||
@@ -327,7 +328,7 @@ static void charon_terminate(private_stroke_control_t *this, uint32_t id,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
charon->controller->terminate_ike(charon->controller, id,
|
charon->controller->terminate_ike(charon->controller, id, FALSE,
|
||||||
NULL, NULL, 0);
|
NULL, NULL, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ static void terminate(private_uci_control_t *this, char *name)
|
|||||||
{
|
{
|
||||||
id = ike_sa->get_unique_id(ike_sa);
|
id = ike_sa->get_unique_id(ike_sa);
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
charon->controller->terminate_ike(charon->controller, id,
|
charon->controller->terminate_ike(charon->controller, id, FALSE,
|
||||||
controller_cb_empty, NULL, 0);
|
controller_cb_empty, NULL, 0);
|
||||||
write_fifo(this, "connection '%s' terminated\n", name);
|
write_fifo(this, "connection '%s' terminated\n", name);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -279,7 +279,9 @@ Terminates an SA while streaming _control-log_ events.
|
|||||||
ike = <terminate an IKE_SA by configuration name>
|
ike = <terminate an IKE_SA by configuration name>
|
||||||
child-id = <terminate a CHILD_SA by its reqid>
|
child-id = <terminate a CHILD_SA by its reqid>
|
||||||
ike-id = <terminate an IKE_SA by its unique id>
|
ike-id = <terminate an IKE_SA by its unique id>
|
||||||
timeout = <timeout in ms before returning>
|
force = <terminate IKE_SA without waiting for proper DELETE, if timeout
|
||||||
|
is given, waits for a response until it is reached>
|
||||||
|
timeout = <timeout in ms before returning, see below>
|
||||||
loglevel = <loglevel to issue "control-log" events for>
|
loglevel = <loglevel to issue "control-log" events for>
|
||||||
} => {
|
} => {
|
||||||
success = <yes or no>
|
success = <yes or no>
|
||||||
|
|||||||
@@ -2083,7 +2083,7 @@ static void clear_start_action(private_vici_config_t *this, char *peer_name,
|
|||||||
while (array_remove(ikeids, ARRAY_HEAD, &id))
|
while (array_remove(ikeids, ARRAY_HEAD, &id))
|
||||||
{
|
{
|
||||||
DBG1(DBG_CFG, "closing IKE_SA #%u", id);
|
DBG1(DBG_CFG, "closing IKE_SA #%u", id);
|
||||||
charon->controller->terminate_ike(charon->controller,
|
charon->controller->terminate_ike(charon->controller, FALSE,
|
||||||
id, NULL, NULL, 0);
|
id, NULL, NULL, 0);
|
||||||
}
|
}
|
||||||
array_destroy(ikeids);
|
array_destroy(ikeids);
|
||||||
|
|||||||
@@ -225,6 +225,7 @@ CALLBACK(terminate, vici_message_t*,
|
|||||||
enumerator_t *enumerator, *isas, *csas;
|
enumerator_t *enumerator, *isas, *csas;
|
||||||
char *child, *ike, *errmsg = NULL;
|
char *child, *ike, *errmsg = NULL;
|
||||||
u_int child_id, ike_id, current, *del, done = 0;
|
u_int child_id, ike_id, current, *del, done = 0;
|
||||||
|
bool force;
|
||||||
int timeout;
|
int timeout;
|
||||||
ike_sa_t *ike_sa;
|
ike_sa_t *ike_sa;
|
||||||
child_sa_t *child_sa;
|
child_sa_t *child_sa;
|
||||||
@@ -240,6 +241,7 @@ CALLBACK(terminate, vici_message_t*,
|
|||||||
ike = request->get_str(request, NULL, "ike");
|
ike = request->get_str(request, NULL, "ike");
|
||||||
child_id = request->get_int(request, 0, "child-id");
|
child_id = request->get_int(request, 0, "child-id");
|
||||||
ike_id = request->get_int(request, 0, "ike-id");
|
ike_id = request->get_int(request, 0, "ike-id");
|
||||||
|
force = request->get_bool(request, FALSE, "force");
|
||||||
timeout = request->get_int(request, 0, "timeout");
|
timeout = request->get_int(request, 0, "timeout");
|
||||||
log.level = request->get_int(request, 1, "loglevel");
|
log.level = request->get_int(request, 1, "loglevel");
|
||||||
|
|
||||||
@@ -326,7 +328,7 @@ CALLBACK(terminate, vici_message_t*,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (charon->controller->terminate_ike(charon->controller, *del,
|
if (charon->controller->terminate_ike(charon->controller, *del, force,
|
||||||
log_cb, &log, timeout) == SUCCESS)
|
log_cb, &log, timeout) == SUCCESS)
|
||||||
{
|
{
|
||||||
done++;
|
done++;
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ METHOD(job_t, execute, job_requeue_t,
|
|||||||
}
|
}
|
||||||
if (this->delete_if_established)
|
if (this->delete_if_established)
|
||||||
{
|
{
|
||||||
if (ike_sa->delete(ike_sa) == DESTROY_ME)
|
if (ike_sa->delete(ike_sa, FALSE) == DESTROY_ME)
|
||||||
{
|
{
|
||||||
charon->ike_sa_manager->checkin_and_destroy(
|
charon->ike_sa_manager->checkin_and_destroy(
|
||||||
charon->ike_sa_manager, ike_sa);
|
charon->ike_sa_manager, ike_sa);
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ METHOD(job_t, execute, job_requeue_t,
|
|||||||
{
|
{
|
||||||
DBG1(DBG_JOB, "deleting IKE_SA after %d seconds "
|
DBG1(DBG_JOB, "deleting IKE_SA after %d seconds "
|
||||||
"of CHILD_SA inactivity", this->timeout);
|
"of CHILD_SA inactivity", this->timeout);
|
||||||
status = ike_sa->delete(ike_sa);
|
status = ike_sa->delete(ike_sa, FALSE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2017 Tobias Brunner
|
* Copyright (C) 2006-2018 Tobias Brunner
|
||||||
* Copyright (C) 2006 Daniel Roethlisberger
|
* Copyright (C) 2006 Daniel Roethlisberger
|
||||||
* Copyright (C) 2005-2009 Martin Willi
|
* Copyright (C) 2005-2009 Martin Willi
|
||||||
* Copyright (C) 2005 Jan Hutter
|
* Copyright (C) 2005 Jan Hutter
|
||||||
@@ -1793,8 +1793,10 @@ METHOD(ike_sa_t, destroy_child_sa, status_t,
|
|||||||
}
|
}
|
||||||
|
|
||||||
METHOD(ike_sa_t, delete_, status_t,
|
METHOD(ike_sa_t, delete_, status_t,
|
||||||
private_ike_sa_t *this)
|
private_ike_sa_t *this, bool force)
|
||||||
{
|
{
|
||||||
|
status_t status = DESTROY_ME;
|
||||||
|
|
||||||
switch (this->state)
|
switch (this->state)
|
||||||
{
|
{
|
||||||
case IKE_ESTABLISHED:
|
case IKE_ESTABLISHED:
|
||||||
@@ -1806,19 +1808,38 @@ METHOD(ike_sa_t, delete_, status_t,
|
|||||||
charon->bus->alert(charon->bus, ALERT_IKE_SA_EXPIRED);
|
charon->bus->alert(charon->bus, ALERT_IKE_SA_EXPIRED);
|
||||||
}
|
}
|
||||||
this->task_manager->queue_ike_delete(this->task_manager);
|
this->task_manager->queue_ike_delete(this->task_manager);
|
||||||
return this->task_manager->initiate(this->task_manager);
|
status = this->task_manager->initiate(this->task_manager);
|
||||||
|
break;
|
||||||
case IKE_CREATED:
|
case IKE_CREATED:
|
||||||
DBG1(DBG_IKE, "deleting unestablished IKE_SA");
|
DBG1(DBG_IKE, "deleting unestablished IKE_SA");
|
||||||
break;
|
break;
|
||||||
case IKE_PASSIVE:
|
case IKE_PASSIVE:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DBG1(DBG_IKE, "destroying IKE_SA in state %N "
|
DBG1(DBG_IKE, "destroying IKE_SA in state %N without notification",
|
||||||
"without notification", ike_sa_state_names, this->state);
|
ike_sa_state_names, this->state);
|
||||||
charon->bus->ike_updown(charon->bus, &this->public, FALSE);
|
force = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return DESTROY_ME;
|
|
||||||
|
if (force)
|
||||||
|
{
|
||||||
|
status = DESTROY_ME;
|
||||||
|
|
||||||
|
if (this->version == IKEV2)
|
||||||
|
{ /* for IKEv1 we trigger this in the ISAKMP delete task */
|
||||||
|
switch (this->state)
|
||||||
|
{
|
||||||
|
case IKE_ESTABLISHED:
|
||||||
|
case IKE_REKEYING:
|
||||||
|
case IKE_DELETING:
|
||||||
|
charon->bus->ike_updown(charon->bus, &this->public, FALSE);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(ike_sa_t, rekey, status_t,
|
METHOD(ike_sa_t, rekey, status_t,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2017 Tobias Brunner
|
* Copyright (C) 2006-2018 Tobias Brunner
|
||||||
* Copyright (C) 2006 Daniel Roethlisberger
|
* Copyright (C) 2006 Daniel Roethlisberger
|
||||||
* Copyright (C) 2005-2009 Martin Willi
|
* Copyright (C) 2005-2009 Martin Willi
|
||||||
* Copyright (C) 2005 Jan Hutter
|
* Copyright (C) 2005 Jan Hutter
|
||||||
@@ -776,15 +776,18 @@ struct ike_sa_t {
|
|||||||
*
|
*
|
||||||
* Sends a delete message to the remote peer and waits for
|
* Sends a delete message to the remote peer and waits for
|
||||||
* its response. If the response comes in, or a timeout occurs,
|
* its response. If the response comes in, or a timeout occurs,
|
||||||
* the IKE SA gets deleted.
|
* the IKE SA gets destroyed, unless force is TRUE then the IKE_SA is
|
||||||
|
* destroyed immediately without waiting for a response.
|
||||||
*
|
*
|
||||||
|
* @param force whether to immediately destroy the IKE_SA afterwards
|
||||||
|
* without waiting for a response
|
||||||
* @return
|
* @return
|
||||||
* - SUCCESS if deletion is initialized
|
* - SUCCESS if deletion is initialized
|
||||||
* - DESTROY_ME, if the IKE_SA is not in
|
* - DESTROY_ME, if destroying is forced, or the IKE_SA
|
||||||
* an established state and can not be
|
* is not in an established state and can not be
|
||||||
* deleted (but destroyed).
|
* deleted (but destroyed)
|
||||||
*/
|
*/
|
||||||
status_t (*delete) (ike_sa_t *this);
|
status_t (*delete) (ike_sa_t *this, bool force);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update IKE_SAs after network interfaces have changed.
|
* Update IKE_SAs after network interfaces have changed.
|
||||||
|
|||||||
@@ -2021,7 +2021,7 @@ static status_t enforce_replace(private_ike_sa_manager_t *this,
|
|||||||
}
|
}
|
||||||
DBG1(DBG_IKE, "deleting duplicate IKE_SA for peer '%Y' due to "
|
DBG1(DBG_IKE, "deleting duplicate IKE_SA for peer '%Y' due to "
|
||||||
"uniqueness policy", other);
|
"uniqueness policy", other);
|
||||||
return duplicate->delete(duplicate);
|
return duplicate->delete(duplicate, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(ike_sa_manager_t, check_uniqueness, bool,
|
METHOD(ike_sa_manager_t, check_uniqueness, bool,
|
||||||
@@ -2266,20 +2266,7 @@ METHOD(ike_sa_manager_t, flush, void,
|
|||||||
while (enumerator->enumerate(enumerator, &entry, &segment))
|
while (enumerator->enumerate(enumerator, &entry, &segment))
|
||||||
{
|
{
|
||||||
charon->bus->set_sa(charon->bus, entry->ike_sa);
|
charon->bus->set_sa(charon->bus, entry->ike_sa);
|
||||||
if (entry->ike_sa->get_version(entry->ike_sa) == IKEV2)
|
entry->ike_sa->delete(entry->ike_sa, TRUE);
|
||||||
{ /* as the delete never gets processed, fire down events */
|
|
||||||
switch (entry->ike_sa->get_state(entry->ike_sa))
|
|
||||||
{
|
|
||||||
case IKE_ESTABLISHED:
|
|
||||||
case IKE_REKEYING:
|
|
||||||
case IKE_DELETING:
|
|
||||||
charon->bus->ike_updown(charon->bus, entry->ike_sa, FALSE);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
entry->ike_sa->delete(entry->ike_sa);
|
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
|
|||||||
@@ -363,7 +363,7 @@ METHOD(task_t, process_i, status_t,
|
|||||||
/* IKE_SAs in state IKE_REKEYED are silently deleted, so we use
|
/* IKE_SAs in state IKE_REKEYED are silently deleted, so we use
|
||||||
* IKE_REKEYING */
|
* IKE_REKEYING */
|
||||||
this->new_sa->set_state(this->new_sa, IKE_REKEYING);
|
this->new_sa->set_state(this->new_sa, IKE_REKEYING);
|
||||||
if (this->new_sa->delete(this->new_sa) == DESTROY_ME)
|
if (this->new_sa->delete(this->new_sa, FALSE) == DESTROY_ME)
|
||||||
{
|
{
|
||||||
this->new_sa->destroy(this->new_sa);
|
this->new_sa->destroy(this->new_sa);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -290,7 +290,7 @@ START_TEST(test_collision_ike_delete)
|
|||||||
}
|
}
|
||||||
call_ikesa(a, delete_child_sa, PROTO_ESP, spi_a, FALSE);
|
call_ikesa(a, delete_child_sa, PROTO_ESP, spi_a, FALSE);
|
||||||
assert_child_sa_state(a, spi_a, CHILD_DELETING);
|
assert_child_sa_state(a, spi_a, CHILD_DELETING);
|
||||||
call_ikesa(b, delete);
|
call_ikesa(b, delete, FALSE);
|
||||||
assert_ike_sa_state(b, IKE_DELETING);
|
assert_ike_sa_state(b, IKE_DELETING);
|
||||||
|
|
||||||
/* RFC 7296, 2.25.2 does not explicitly state what the behavior SHOULD be if
|
/* RFC 7296, 2.25.2 does not explicitly state what the behavior SHOULD be if
|
||||||
|
|||||||
@@ -1906,7 +1906,7 @@ START_TEST(test_collision_ike_delete)
|
|||||||
&a, &b, NULL);
|
&a, &b, NULL);
|
||||||
}
|
}
|
||||||
initiate_rekey(a, spi_a);
|
initiate_rekey(a, spi_a);
|
||||||
call_ikesa(b, delete);
|
call_ikesa(b, delete, FALSE);
|
||||||
assert_ike_sa_state(b, IKE_DELETING);
|
assert_ike_sa_state(b, IKE_DELETING);
|
||||||
|
|
||||||
/* this should never get called as there is no successful rekeying on
|
/* this should never get called as there is no successful rekeying on
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ START_TEST(test_regular)
|
|||||||
}
|
}
|
||||||
assert_hook_not_called(ike_updown);
|
assert_hook_not_called(ike_updown);
|
||||||
assert_hook_not_called(child_updown);
|
assert_hook_not_called(child_updown);
|
||||||
call_ikesa(a, delete);
|
call_ikesa(a, delete, FALSE);
|
||||||
assert_ike_sa_state(a, IKE_DELETING);
|
assert_ike_sa_state(a, IKE_DELETING);
|
||||||
assert_hook();
|
assert_hook();
|
||||||
assert_hook();
|
assert_hook();
|
||||||
@@ -81,9 +81,9 @@ START_TEST(test_collision)
|
|||||||
|
|
||||||
assert_hook_not_called(ike_updown);
|
assert_hook_not_called(ike_updown);
|
||||||
assert_hook_not_called(child_updown);
|
assert_hook_not_called(child_updown);
|
||||||
call_ikesa(a, delete);
|
call_ikesa(a, delete, FALSE);
|
||||||
assert_ike_sa_state(a, IKE_DELETING);
|
assert_ike_sa_state(a, IKE_DELETING);
|
||||||
call_ikesa(b, delete);
|
call_ikesa(b, delete, FALSE);
|
||||||
assert_ike_sa_state(b, IKE_DELETING);
|
assert_ike_sa_state(b, IKE_DELETING);
|
||||||
assert_hook();
|
assert_hook();
|
||||||
assert_hook();
|
assert_hook();
|
||||||
|
|||||||
@@ -1319,7 +1319,7 @@ START_TEST(test_collision_delete)
|
|||||||
assert_hook_not_called(ike_rekey);
|
assert_hook_not_called(ike_rekey);
|
||||||
|
|
||||||
initiate_rekey(a);
|
initiate_rekey(a);
|
||||||
call_ikesa(b, delete);
|
call_ikesa(b, delete, FALSE);
|
||||||
assert_ike_sa_state(b, IKE_DELETING);
|
assert_ike_sa_state(b, IKE_DELETING);
|
||||||
|
|
||||||
/* RFC 7296, 2.25.2: If a peer receives a request to rekey an IKE SA that
|
/* RFC 7296, 2.25.2: If a peer receives a request to rekey an IKE SA that
|
||||||
@@ -1401,7 +1401,7 @@ START_TEST(test_collision_delete_drop_delete)
|
|||||||
assert_hook_not_called(ike_rekey);
|
assert_hook_not_called(ike_rekey);
|
||||||
|
|
||||||
initiate_rekey(a);
|
initiate_rekey(a);
|
||||||
call_ikesa(b, delete);
|
call_ikesa(b, delete, FALSE);
|
||||||
assert_ike_sa_state(b, IKE_DELETING);
|
assert_ike_sa_state(b, IKE_DELETING);
|
||||||
|
|
||||||
/* RFC 7296, 2.25.2: If a peer receives a request to rekey an IKE SA that
|
/* RFC 7296, 2.25.2: If a peer receives a request to rekey an IKE SA that
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ static int terminate(vici_conn_t *conn)
|
|||||||
command_format_options_t format = COMMAND_FORMAT_NONE;
|
command_format_options_t format = COMMAND_FORMAT_NONE;
|
||||||
char *arg, *child = NULL, *ike = NULL;
|
char *arg, *child = NULL, *ike = NULL;
|
||||||
int ret = 0, timeout = 0, level = 1, child_id = 0, ike_id = 0;
|
int ret = 0, timeout = 0, level = 1, child_id = 0, ike_id = 0;
|
||||||
|
bool force = FALSE;
|
||||||
|
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
@@ -55,6 +56,9 @@ static int terminate(vici_conn_t *conn)
|
|||||||
case 'c':
|
case 'c':
|
||||||
child = arg;
|
child = arg;
|
||||||
continue;
|
continue;
|
||||||
|
case 'f':
|
||||||
|
force = TRUE;
|
||||||
|
continue;
|
||||||
case 'i':
|
case 'i':
|
||||||
ike = arg;
|
ike = arg;
|
||||||
continue;
|
continue;
|
||||||
@@ -101,6 +105,10 @@ static int terminate(vici_conn_t *conn)
|
|||||||
{
|
{
|
||||||
vici_add_key_valuef(req, "ike-id", "%d", ike_id);
|
vici_add_key_valuef(req, "ike-id", "%d", ike_id);
|
||||||
}
|
}
|
||||||
|
if (force)
|
||||||
|
{
|
||||||
|
vici_add_key_valuef(req, "force", "yes");
|
||||||
|
}
|
||||||
if (timeout)
|
if (timeout)
|
||||||
{
|
{
|
||||||
vici_add_key_valuef(req, "timeout", "%d", timeout * 1000);
|
vici_add_key_valuef(req, "timeout", "%d", timeout * 1000);
|
||||||
@@ -150,6 +158,7 @@ static void __attribute__ ((constructor))reg()
|
|||||||
{"ike", 'i', 1, "terminate by IKE_SA name"},
|
{"ike", 'i', 1, "terminate by IKE_SA name"},
|
||||||
{"child-id", 'C', 1, "terminate by CHILD_SA reqid"},
|
{"child-id", 'C', 1, "terminate by CHILD_SA reqid"},
|
||||||
{"ike-id", 'I', 1, "terminate by IKE_SA unique identifier"},
|
{"ike-id", 'I', 1, "terminate by IKE_SA unique identifier"},
|
||||||
|
{"force", 'f', 0, "terminate IKE_SA without waiting, unless timeout is set"},
|
||||||
{"timeout", 't', 1, "timeout in seconds before detaching"},
|
{"timeout", 't', 1, "timeout in seconds before detaching"},
|
||||||
{"raw", 'r', 0, "dump raw response message"},
|
{"raw", 'r', 0, "dump raw response message"},
|
||||||
{"pretty", 'P', 0, "dump raw response message in pretty print"},
|
{"pretty", 'P', 0, "dump raw response message in pretty print"},
|
||||||
|
|||||||
Reference in New Issue
Block a user