Merge branch 'vici-reload-actions'

This improves the behavior when reloading or unloading connections that
have `start` included in their `start_actiton`.

Closes strongswan/strongswan#2324
This commit is contained in:
Tobias Brunner 2024-07-30 10:26:21 +02:00
commit 72f9a21b22
19 changed files with 741 additions and 119 deletions

View File

@ -2257,7 +2257,7 @@ static void run_start_action(private_vici_config_t *this, peer_cfg_t *peer_cfg,
if (action & ACTION_TRAP)
{
DBG1(DBG_CFG, "installing '%s'", child_cfg->get_name(child_cfg));
DBG1(DBG_CFG, "vici installing '%s'", child_cfg->get_name(child_cfg));
switch (child_cfg->get_mode(child_cfg))
{
case MODE_PASS:
@ -2274,7 +2274,7 @@ static void run_start_action(private_vici_config_t *this, peer_cfg_t *peer_cfg,
if (action & ACTION_START)
{
DBG1(DBG_CFG, "initiating '%s'", child_cfg->get_name(child_cfg));
DBG1(DBG_CFG, "vici 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, 0, FALSE);
@ -2282,25 +2282,116 @@ static void run_start_action(private_vici_config_t *this, peer_cfg_t *peer_cfg,
}
/**
* Undo start actions associated with a child config
* Type to keep track of unique IDs and names of CHILD_SAs to terminate.
*/
static void clear_start_action(private_vici_config_t *this, char *peer_name,
child_cfg_t *child_cfg)
typedef struct {
uint32_t id;
char *name;
} child_name_id_t;
/**
* Terminate given CHILD_SAs and optionally terminate any IKE_SA without other
* children.
*/
static void terminate_for_action(private_vici_config_t *this, char *peer_name,
hashtable_t *to_terminate, bool delete_ike)
{
enumerator_t *enumerator, *children;
child_sa_t *child_sa;
ike_sa_t *ike_sa;
uint32_t id = 0, others;
child_name_id_t child_id;
uint32_t id;
array_t *ids = NULL, *ikeids = NULL;
bool others;
enumerator = charon->controller->create_ike_sa_enumerator(
charon->controller, TRUE);
while (enumerator->enumerate(enumerator, &ike_sa))
{
if (!streq(ike_sa->get_name(ike_sa), peer_name))
{
continue;
}
others = FALSE;
children = ike_sa->create_child_sa_enumerator(ike_sa);
while (children->enumerate(children, &child_sa))
{
if (child_sa->get_state(child_sa) != CHILD_DELETING &&
child_sa->get_state(child_sa) != CHILD_DELETED &&
!to_terminate->get(to_terminate, child_sa->get_name(child_sa)))
{
others = TRUE;
break;
}
}
children->destroy(children);
if (delete_ike && (!others || !ike_sa->get_child_count(ike_sa)))
{
/* found no children or only matching, delete IKE_SA */
id = ike_sa->get_unique_id(ike_sa);
array_insert_create_value(&ikeids, sizeof(id),
ARRAY_TAIL, &id);
continue;
}
/* otherwise, delete only the matching CHILD_SAs */
children = ike_sa->create_child_sa_enumerator(ike_sa);
while (children->enumerate(children, &child_sa))
{
child_id.name = child_sa->get_name(child_sa);
if (child_sa->get_state(child_sa) != CHILD_DELETING &&
child_sa->get_state(child_sa) != CHILD_DELETED &&
to_terminate->get(to_terminate, child_id.name))
{
child_id.id = child_sa->get_unique_id(child_sa);
child_id.name = strdup(child_id.name);
array_insert_create_value(&ids, sizeof(child_id),
ARRAY_TAIL, &child_id);
}
}
children->destroy(children);
}
enumerator->destroy(enumerator);
while (array_remove(ids, ARRAY_HEAD, &child_id))
{
DBG1(DBG_CFG, "vici closing CHILD_SA '%s' #%u", child_id.name,
child_id.id);
charon->controller->terminate_child(charon->controller,
child_id.id, NULL, NULL, 0, 0);
free(child_id.name);
}
array_destroy(ids);
while (array_remove(ikeids, ARRAY_HEAD, &id))
{
DBG1(DBG_CFG, "vici closing IKE_SA '%s' #%u", peer_name, id);
charon->controller->terminate_ike(charon->controller, id,
FALSE, NULL, NULL, 0, 0);
}
array_destroy(ikeids);
}
/**
* Clear the start action associated with the given child config. To reduce the
* overhead when terminating active SAs, only collect the name.
*
* Note: The lock must be unlocked when calling this.
*/
static void clear_start_action(private_vici_config_t *this, char *peer_name,
child_cfg_t *child_cfg, hashtable_t *to_terminate)
{
action_t action;
char *name;
name = child_cfg->get_name(child_cfg);
action = child_cfg->get_start_action(child_cfg);
if (action & ACTION_TRAP)
{
DBG1(DBG_CFG, "uninstalling '%s'", name);
DBG1(DBG_CFG, "vici uninstalling '%s'", name);
switch (child_cfg->get_mode(child_cfg))
{
case MODE_PASS:
@ -2313,111 +2404,51 @@ static void clear_start_action(private_vici_config_t *this, char *peer_name,
break;
}
}
if (action & ACTION_START)
{
enumerator = charon->controller->create_ike_sa_enumerator(
charon->controller, TRUE);
while (enumerator->enumerate(enumerator, &ike_sa))
{
if (!streq(ike_sa->get_name(ike_sa), peer_name))
{
continue;
}
others = id = 0;
children = ike_sa->create_child_sa_enumerator(ike_sa);
while (children->enumerate(children, &child_sa))
{
if (child_sa->get_state(child_sa) != CHILD_DELETING &&
child_sa->get_state(child_sa) != CHILD_DELETED)
{
if (streq(name, child_sa->get_name(child_sa)))
{
id = child_sa->get_unique_id(child_sa);
}
else
{
others++;
}
}
}
children->destroy(children);
if (!ike_sa->get_child_count(ike_sa) || (id && !others))
{
/* found no children or only matching, delete IKE_SA */
id = ike_sa->get_unique_id(ike_sa);
array_insert_create_value(&ikeids, sizeof(id),
ARRAY_TAIL, &id);
}
else
{
children = ike_sa->create_child_sa_enumerator(ike_sa);
while (children->enumerate(children, &child_sa))
{
if (streq(name, child_sa->get_name(child_sa)))
{
id = child_sa->get_unique_id(child_sa);
array_insert_create_value(&ids, sizeof(id),
ARRAY_TAIL, &id);
}
}
children->destroy(children);
}
}
enumerator->destroy(enumerator);
if (array_count(ids))
{
while (array_remove(ids, ARRAY_HEAD, &id))
{
DBG1(DBG_CFG, "closing '%s' #%u", name, id);
charon->controller->terminate_child(charon->controller,
id, NULL, NULL, 0, 0);
}
array_destroy(ids);
}
if (array_count(ikeids))
{
while (array_remove(ikeids, ARRAY_HEAD, &id))
{
DBG1(DBG_CFG, "closing IKE_SA #%u", id);
charon->controller->terminate_ike(charon->controller, id,
FALSE, NULL, NULL, 0, 0);
}
array_destroy(ikeids);
}
to_terminate->put(to_terminate, name, name);
}
}
/**
* Run or undo a start actions associated with a child config
* Clear start actions associated with a list of child configs, optionally
* deletes empty IKE_SAs.
*/
static void handle_start_action(private_vici_config_t *this,
peer_cfg_t *peer_cfg, child_cfg_t *child_cfg,
bool undo)
static void clear_start_actions(private_vici_config_t *this,
peer_cfg_t *peer_cfg, array_t *child_cfgs,
bool delete_ike)
{
enumerator_t *enumerator;
hashtable_t *to_terminate;
child_cfg_t *child_cfg;
char *peer_name;
this->handling_actions = TRUE;
this->lock->unlock(this->lock);
if (undo)
to_terminate = hashtable_create(hashtable_hash_str,
hashtable_equals_str, 8);
peer_name = peer_cfg->get_name(peer_cfg);
enumerator = array_create_enumerator(child_cfgs);
while (enumerator->enumerate(enumerator, &child_cfg))
{
clear_start_action(this, peer_cfg->get_name(peer_cfg), child_cfg);
}
else
{
run_start_action(this, peer_cfg, child_cfg);
clear_start_action(this, peer_name, child_cfg, to_terminate);
}
enumerator->destroy(enumerator);
terminate_for_action(this, peer_name, to_terminate, delete_ike);
to_terminate->destroy(to_terminate);
this->lock->write_lock(this->lock);
this->handling_actions = FALSE;
}
/**
* Run or undo start actions associated with all child configs of a peer config
* Run start actions associated with a list of child configs.
*/
static void handle_start_actions(private_vici_config_t *this,
peer_cfg_t *peer_cfg, bool undo)
static void run_start_actions(private_vici_config_t *this,
peer_cfg_t *peer_cfg, array_t *child_cfgs)
{
enumerator_t *enumerator;
child_cfg_t *child_cfg;
@ -2425,17 +2456,10 @@ static void handle_start_actions(private_vici_config_t *this,
this->handling_actions = TRUE;
this->lock->unlock(this->lock);
enumerator = peer_cfg->create_child_cfg_enumerator(peer_cfg);
enumerator = array_create_enumerator(child_cfgs);
while (enumerator->enumerate(enumerator, &child_cfg))
{
if (undo)
{
clear_start_action(this, peer_cfg->get_name(peer_cfg), child_cfg);
}
else
{
run_start_action(this, peer_cfg, child_cfg);
}
run_start_action(this, peer_cfg, child_cfg);
}
enumerator->destroy(enumerator);
@ -2443,6 +2467,30 @@ static void handle_start_actions(private_vici_config_t *this,
this->handling_actions = FALSE;
}
/**
* Run or undo start actions for all child configs of the given peer config
* after it has changed.
*/
static void handle_start_actions(private_vici_config_t *this,
peer_cfg_t *peer_cfg, bool undo)
{
array_t *child_cfgs;
child_cfgs = array_create(0, 0);
array_insert_enumerator(child_cfgs, ARRAY_TAIL,
peer_cfg->create_child_cfg_enumerator(peer_cfg));
if (undo)
{
/* the peer config has changed, so allow IKE_SAs to get terminated */
clear_start_actions(this, peer_cfg, child_cfgs, TRUE);
}
else
{
run_start_actions(this, peer_cfg, child_cfgs);
}
array_destroy(child_cfgs);
}
/**
* Replace children of a peer config by a new config
*/
@ -2451,13 +2499,31 @@ static void replace_children(private_vici_config_t *this,
{
enumerator_t *enumerator;
child_cfg_t *child;
bool added;
array_t *to_run = NULL, *to_clear = NULL;
bool added, any_to_initiate = FALSE;
enumerator = to->replace_child_cfgs(to, from);
while (enumerator->enumerate(enumerator, &child, &added))
{
handle_start_action(this, to, child, !added);
if (added)
{
array_insert_create(&to_run, ARRAY_TAIL, child);
if (child->get_start_action(child) & ACTION_START)
{
any_to_initiate = TRUE;
}
}
else
{
array_insert_create(&to_clear, ARRAY_TAIL, child);
}
}
/* keep empty IKE_SAs only if we are to initiate any CHILD_SAs */
clear_start_actions(this, to, to_clear, !any_to_initiate);
run_start_actions(this, to, to_run);
array_destroy(to_clear);
array_destroy(to_run);
enumerator->destroy(enumerator);
}
@ -2796,6 +2862,7 @@ CALLBACK(unload_conn, vici_message_t*,
cfg = this->conns->remove(this->conns, conn_name);
if (cfg)
{
DBG1(DBG_CFG, "removed vici connection: %s", cfg->get_name(cfg));
handle_start_actions(this, cfg, TRUE);
cfg->destroy(cfg);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2006-2020 Tobias Brunner
* Copyright (C) 2006-2024 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
@ -2012,12 +2012,13 @@ static bool is_child_queued(private_ike_sa_t *this, task_queue_t queue)
this->version == IKEV1 ? TASK_QUICK_MODE : TASK_CHILD_CREATE);
}
/**
* Check if any tasks to delete the IKE_SA are queued in the given queue.
/*
* Described in header
*/
static bool is_delete_queued(private_ike_sa_t *this, task_queue_t queue)
bool ike_sa_is_delete_queued(ike_sa_t *ike_sa)
{
return is_task_queued(this, queue,
private_ike_sa_t *this = (private_ike_sa_t*)ike_sa;
return is_task_queued(this, TASK_QUEUE_QUEUED,
this->version == IKEV1 ? TASK_ISAKMP_DELETE : TASK_IKE_DELETE);
}
@ -2101,7 +2102,7 @@ METHOD(ike_sa_t, reestablish, status_t,
bool restart = FALSE;
status_t status = FAILED;
if (is_delete_queued(this, TASK_QUEUE_QUEUED))
if (ike_sa_is_delete_queued((ike_sa_t*)this))
{ /* don't reestablish IKE_SAs that have explicitly been deleted in the
* mean time */
return FAILED;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2006-2020 Tobias Brunner
* Copyright (C) 2006-2024 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2005 Jan Hutter
@ -1261,7 +1261,7 @@ struct ike_sa_t {
* @param ike_sa_id ike_sa_id_t to associate with new IKE_SA/ISAKMP_SA
* @param initiator TRUE to create this IKE_SA as initiator
* @param version IKE version of this SA
* @return ike_sa_t object
* @return ike_sa_t object
*/
ike_sa_t *ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator,
ike_version_t version);
@ -1271,16 +1271,24 @@ ike_sa_t *ike_sa_create(ike_sa_id_t *ike_sa_id, bool initiator,
* parameters or the authentication method prevent it.
*
* @param this IKE_SA to check
* @return TRUE if active reauthentication is possible
* @return TRUE if active reauthentication is possible
*/
bool ike_sa_can_reauthenticate(ike_sa_t *this);
/**
* Check if a task to delete this IKE_SA is queued.
*
* @param this IKE_SA to check
* @return TRUE if a task is queued
*/
bool ike_sa_is_delete_queued(ike_sa_t *this);
/**
* Get hosts, virtual or physical, for deriving dynamic traffic selectors.
*
* @param this IKE_SA to retrieve addresses from
* @param local TRUE to get local hosts
* @return list of hosts (internal objects)
* @return list of hosts (internal objects)
*/
linked_list_t *ike_sa_get_dynamic_hosts(ike_sa_t *this, bool local);

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2008-2022 Tobias Brunner
* Copyright (C) 2008-2024 Tobias Brunner
* Copyright (C) 2005-2011 Martin Willi
* Copyright (C) 2005 Jan Hutter
*
@ -1562,7 +1562,8 @@ METHOD(ike_sa_manager_t, checkout_by_config, ike_sa_t*,
continue;
}
if (entry->ike_sa->get_state(entry->ike_sa) == IKE_DELETING ||
entry->ike_sa->get_state(entry->ike_sa) == IKE_REKEYED)
entry->ike_sa->get_state(entry->ike_sa) == IKE_REKEYED ||
ike_sa_is_delete_queued(entry->ike_sa))
{ /* skip IKE_SAs which are not usable, wake other waiting threads */
entry->condvar->signal(entry->condvar);
continue;

View File

@ -1,4 +1,4 @@
<network>
<network ipv6='yes'>
<name>vnet1</name>
<uuid>1d6ac7c7-60d9-56c1-a7df-210d3d0cc6d1</uuid>
<forward dev='lo' mode='route'>

View File

@ -1,4 +1,4 @@
<network>
<network ipv6='yes'>
<name>vnet2</name>
<uuid>b5147a7d-e184-5c9e-3838-4621796ba95c</uuid>
<forward dev='lo' mode='route'>

View File

@ -1,4 +1,4 @@
<network>
<network ipv6='yes'>
<name>vnet3</name>
<uuid>5c537abc-c116-90e9-a0ef-886340d4c356</uuid>
<forward dev='lo' mode='route'>

View File

@ -0,0 +1,3 @@
This scenario tests <b>start_action=start</b> and its behavior when reloading the
config. To distinguish the different CHILD_SAs, arbitrary TCP ports are used in
the traffic selectors.

View File

@ -0,0 +1,56 @@
moon::cat /var/log/daemon.log::vici initiating 'one-start'::YES
moon::cat /var/log/daemon.log::vici initiating 'two-start-.'::2
moon::cat /var/log/daemon.log::vici initiating 'four-start-.'::4
moon::cat /var/log/daemon.log::vici initiating 'one-start-child'::YES
moon::cat /var/log/daemon.log::vici initiating 'two-start-child-.'::2
moon::cat /var/log/daemon.log::vici initiating 'four-start-child-.'::4
moon::mv /etc/swanctl/swanctl-update.conf /etc/swanctl/conf.d/
moon::systemctl reload strongswan
moon::sleep 3
moon::cat /var/log/daemon.log::replaced vici connection: one-start::YES
moon::cat /var/log/daemon.log::vici closing IKE_SA 'one-start'::YES
moon::cat /var/log/daemon.log::replaced vici connection: two-start::YES
moon::cat /var/log/daemon.log::vici closing IKE_SA 'two-start'::YES
moon::cat /var/log/daemon.log::replaced vici connection: four-start::YES
moon::cat /var/log/daemon.log::vici closing IKE_SA 'four-start'::YES
moon::cat /var/log/daemon.log::updated vici connection: one-start-child::YES
moon::cat /var/log/daemon.log::vici closing IKE_SA 'one-start-child'::NO
moon::cat /var/log/daemon.log::vici closing CHILD_SA 'one-start-child'::YES
moon::cat /var/log/daemon.log::updated vici connection: two-start-child::YES
moon::cat /var/log/daemon.log::vici closing IKE_SA 'two-start-child'::NO
moon::cat /var/log/daemon.log::vici closing CHILD_SA 'two-start-child-.'::2
moon::cat /var/log/daemon.log::updated vici connection: four-start-child::YES
moon::cat /var/log/daemon.log::vici closing IKE_SA 'four-start-child'::NO
moon::cat /var/log/daemon.log::vici closing CHILD_SA 'four-start-child-.'::4
moon::cat /var/log/daemon.log::vici initiating 'one-start'::2
moon::cat /var/log/daemon.log::vici initiating 'two-start-.'::4
moon::cat /var/log/daemon.log::vici initiating 'four-start-.'::8
moon::cat /var/log/daemon.log::vici initiating 'one-start-child'::2
moon::cat /var/log/daemon.log::vici initiating 'two-start-child-.'::4
moon::cat /var/log/daemon.log::vici initiating 'four-start-child-.'::8
moon::rm /etc/swanctl/conf.d/*
moon::mv /etc/swanctl/swanctl-remove.conf /etc/swanctl/conf.d/
moon::systemctl reload strongswan
moon::sleep 3
moon::cat /var/log/daemon.log::removed vici connection: one-start::YES
moon::cat /var/log/daemon.log::vici closing IKE_SA 'one-start'::2
moon::cat /var/log/daemon.log::removed vici connection: two-start::YES
moon::cat /var/log/daemon.log::vici closing IKE_SA 'two-start'::2
moon::cat /var/log/daemon.log::removed vici connection: four-start::YES
moon::cat /var/log/daemon.log::vici closing IKE_SA 'four-start'::2
moon::cat /var/log/daemon.log::updated vici connection: one-start-child::2
moon::cat /var/log/daemon.log::vici closing IKE_SA 'one-start-child'::YES
moon::cat /var/log/daemon.log::updated vici connection: two-start-child::2
moon::cat /var/log/daemon.log::vici closing IKE_SA 'two-start-child'::NO
moon::cat /var/log/daemon.log::vici closing CHILD_SA 'two-start-child-1' #..::NO
moon::cat /var/log/daemon.log::vici closing CHILD_SA 'two-start-child-2' #..::YES
moon::cat /var/log/daemon.log::updated vici connection: four-start-child::2
moon::cat /var/log/daemon.log::vici closing IKE_SA 'four-start-child'::NO
moon::cat /var/log/daemon.log::vici closing CHILD_SA 'four-start-child-.'::8
# only the last one here should change
moon::cat /var/log/daemon.log::vici initiating 'one-start'::2
moon::cat /var/log/daemon.log::vici initiating 'two-start-.'::4
moon::cat /var/log/daemon.log::vici initiating 'four-start-.'::8
moon::cat /var/log/daemon.log::vici initiating 'one-start-child'::2
moon::cat /var/log/daemon.log::vici initiating 'two-start-child-.'::4
moon::cat /var/log/daemon.log::vici initiating 'four-start-child-.'::10

View File

@ -0,0 +1,5 @@
# /etc/strongswan.conf - strongSwan configuration file
charon-systemd {
load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac kdf vici kernel-netlink socket-default updown
}

View File

@ -0,0 +1,161 @@
# basic settings for these test configs
base-conn {
local_addrs = 192.168.0.1
remote_addrs = 192.168.0.2
local {
auth = psk
}
remote {
auth = psk
}
}
connections {
# when updating, we'll change ike/peer parameters for these
one-start : base-conn {
local {
id = moon-one
}
remote {
id = sun-one
}
children {
one-start {
local_ts = dynamic[tcp/1001]
remote_ts = dynamic[tcp/1001]
start_action = start
}
}
}
two-start : base-conn {
local {
id = moon-two
}
remote {
id = sun-two
}
children {
two-start-1 {
local_ts = dynamic[tcp/2001]
remote_ts = dynamic[tcp/2001]
start_action = start
}
two-start-2 {
local_ts = dynamic[tcp/2002]
remote_ts = dynamic[tcp/2002]
start_action = start
}
}
}
four-start : base-conn {
local {
id = moon-four
}
remote {
id = sun-four
}
children {
four-start-1 {
local_ts = dynamic[tcp/4001]
remote_ts = dynamic[tcp/4001]
start_action = start
}
four-start-2 {
local_ts = dynamic[tcp/4002]
remote_ts = dynamic[tcp/4002]
start_action = start
}
four-start-3 {
local_ts = dynamic[tcp/4003]
remote_ts = dynamic[tcp/4003]
start_action = start
}
four-start-4 {
local_ts = dynamic[tcp/4004]
remote_ts = dynamic[tcp/4004]
start_action = start
}
}
}
# when updating, we'll change only child parameters for these
one-start-child : base-conn {
local {
id = moon-one-child
}
remote {
id = sun-one-child
}
children {
one-start-child {
local_ts = dynamic[tcp/1101]
remote_ts = dynamic[tcp/1101]
start_action = start
}
}
}
two-start-child : base-conn {
local {
id = moon-two-child
}
remote {
id = sun-two-child
}
children {
two-start-child-1 {
local_ts = dynamic[tcp/2201]
remote_ts = dynamic[tcp/2201]
start_action = start
}
two-start-child-2 {
local_ts = dynamic[tcp/2202]
remote_ts = dynamic[tcp/2202]
start_action = start
}
}
}
four-start-child : base-conn {
local {
id = moon-four-child
}
remote {
id = sun-four-child
}
children {
four-start-child-1 {
local_ts = dynamic[tcp/4401]
remote_ts = dynamic[tcp/4401]
start_action = start
}
four-start-child-2 {
local_ts = dynamic[tcp/4402]
remote_ts = dynamic[tcp/4402]
start_action = start
}
four-start-child-3 {
local_ts = dynamic[tcp/4403]
remote_ts = dynamic[tcp/4403]
start_action = start
}
four-start-child-4 {
local_ts = dynamic[tcp/4404]
remote_ts = dynamic[tcp/4404]
start_action = start
}
}
}
}
secrets {
ike {
secret = 0sv+NkxY9LLZvwj4qCC2o/gGrWDF2d21jL
}
}

View File

@ -0,0 +1,75 @@
# basic settings for these test configs
base-conn {
local_addrs = 192.168.0.1
remote_addrs = 192.168.0.2
local {
auth = psk
}
remote {
auth = psk
}
}
connections {
# the initial connections are removed completely
# here all child configs are removed
one-start-child : base-conn {
local {
id = moon-one-child
}
remote {
id = sun-one-child
}
}
# here only one is removed, the other remains unchanged
two-start-child : base-conn {
local {
id = moon-two-child
}
remote {
id = sun-two-child
}
children {
two-start-child-1 {
local_ts = dynamic[tcp/2201]
remote_ts = dynamic[tcp/2201]
rekey_time = 42m
start_action = start
}
}
}
# here two are removed, the others are updated
four-start-child : base-conn {
local {
id = moon-four-child
}
remote {
id = sun-four-child
}
children {
four-start-child-1 {
local_ts = dynamic[tcp/4401]
remote_ts = dynamic[tcp/4401]
rekey_time = 420m
start_action = start
}
four-start-child-2 {
local_ts = dynamic[tcp/4402]
remote_ts = dynamic[tcp/4402]
rekey_time = 420m
start_action = start
}
}
}
}
secrets {
ike {
secret = 0sv+NkxY9LLZvwj4qCC2o/gGrWDF2d21jL
}
}

View File

@ -0,0 +1,56 @@
connections {
# update the rekey time for the IKE_SA for the first connections, so they
# get replaced completely
one-start {
rekey_time = 42m
}
two-start {
rekey_time = 42m
}
four-start {
rekey_time = 42m
}
# for these connections, the rekey time for the children is updated, so the
# IKE_SAs should remain
one-start-child {
children {
one-start-child {
rekey_time = 42m
}
}
}
two-start-child {
children {
two-start-child-1 {
rekey_time = 42m
}
two-start-child-2 {
rekey_time = 42m
}
}
}
four-start-child {
children {
four-start-child-1 {
rekey_time = 42m
}
four-start-child-2 {
rekey_time = 42m
}
four-start-child-3 {
rekey_time = 42m
}
four-start-child-4 {
rekey_time = 42m
}
}
}
}

View File

@ -0,0 +1,2 @@
# include config files from conf.d/
include conf.d/*.conf

View File

@ -0,0 +1,8 @@
# /etc/strongswan.conf - strongSwan configuration file
charon-systemd {
load = random nonce aes sha1 sha2 pem pkcs1 curve25519 gmp x509 curl revocation hmac kdf vici kernel-netlink socket-default updown
# disable DoS protection as the initator will create a lot of IKE_SAs in this scenario
dos_protection = no
}

View File

@ -0,0 +1,143 @@
# basic settings for these test configs
base-conn {
local_addrs = 192.168.0.2
remote_addrs = 192.168.0.1
local {
auth = psk
}
remote {
auth = psk
}
}
connections {
one-start : base-conn {
local {
id = sun-one
}
remote {
id = moon-one
}
children {
one-start {
local_ts = dynamic[tcp/1001]
remote_ts = dynamic[tcp/1001]
}
}
}
two-start : base-conn {
local {
id = sun-two
}
remote {
id = moon-two
}
children {
two-start-1 {
local_ts = dynamic[tcp/2001]
remote_ts = dynamic[tcp/2001]
}
two-start-2 {
local_ts = dynamic[tcp/2002]
remote_ts = dynamic[tcp/2002]
}
}
}
four-start : base-conn {
local {
id = sun-four
}
remote {
id = moon-four
}
children {
four-start-1 {
local_ts = dynamic[tcp/4001]
remote_ts = dynamic[tcp/4001]
}
four-start-2 {
local_ts = dynamic[tcp/4002]
remote_ts = dynamic[tcp/4002]
}
four-start-3 {
local_ts = dynamic[tcp/4003]
remote_ts = dynamic[tcp/4003]
}
four-start-4 {
local_ts = dynamic[tcp/4004]
remote_ts = dynamic[tcp/4004]
}
}
}
one-start-child : base-conn {
local {
id = sun-one-child
}
remote {
id = moon-one-child
}
children {
one-start-child {
local_ts = dynamic[tcp/1101]
remote_ts = dynamic[tcp/1101]
}
}
}
two-start-child : base-conn {
local {
id = sun-two-child
}
remote {
id = moon-two-child
}
children {
two-start-child-1 {
local_ts = dynamic[tcp/2201]
remote_ts = dynamic[tcp/2201]
}
two-start-child-2 {
local_ts = dynamic[tcp/2202]
remote_ts = dynamic[tcp/2202]
}
}
}
four-start-child : base-conn {
local {
id = sun-four-child
}
remote {
id = moon-four-child
}
children {
four-start-child-1 {
local_ts = dynamic[tcp/4401]
remote_ts = dynamic[tcp/4401]
}
four-start-child-2 {
local_ts = dynamic[tcp/4402]
remote_ts = dynamic[tcp/4402]
}
four-start-child-3 {
local_ts = dynamic[tcp/4403]
remote_ts = dynamic[tcp/4403]
}
four-start-child-4 {
local_ts = dynamic[tcp/4404]
remote_ts = dynamic[tcp/4404]
}
}
}
}
secrets {
ike {
secret = 0sv+NkxY9LLZvwj4qCC2o/gGrWDF2d21jL
}
}

View File

@ -0,0 +1,5 @@
sun::systemctl stop strongswan
moon::systemctl stop strongswan
moon::iptables-restore < /etc/iptables.flush
sun::iptables-restore < /etc/iptables.flush
moon::rm -rf /etc/swanctl/conf.d/

View File

@ -0,0 +1,6 @@
moon::iptables-restore < /etc/iptables.rules
sun::iptables-restore < /etc/iptables.rules
sun::systemctl start strongswan
sun::expect-connection four-start-child
moon::systemctl start strongswan
moon::sleep 3

View File

@ -0,0 +1,25 @@
#!/bin/bash
#
# This configuration file provides information on the
# guest instances used for this test
# All guest instances that are required for this test
#
VIRTHOSTS="alice moon winnetou sun bob"
# Corresponding block diagram
#
DIAGRAM="a-m-w-s-b.png"
# Guest instances on which tcpdump is to be started
#
TCPDUMPHOSTS=""
# Guest instances on which IPsec is started
# Used for IPsec logging purposes
#
IPSECHOSTS="moon sun"
# charon controlled by swanctl
#
SWANCTL=1