child-create: Abort initiating a duplicate CHILD_SA
This could happen if an acquire is triggered while we respond to a CREATE_CHILD_SA request from the peer, or if an acquire is triggered while an IKE_SA (with its existing CHILD_SAs) is reestablished (also with break-before-make reauthentication). Also catches multiple manual initiations. Note that this ignores the traffic selectors from acquires (narrowing to them seems rare in practice anyway). Duplicates can still get created if e.g. both peers initiate them concurrently.
This commit is contained in:
@@ -21,6 +21,47 @@
|
||||
#include <tests/utils/job_asserts.h>
|
||||
#include <tests/utils/sa_asserts.h>
|
||||
|
||||
/**
|
||||
* The peers try to create a new CHILD_SA that looks exactly the same
|
||||
* as the existing one, so it won't get initiated.
|
||||
*/
|
||||
START_TEST(test_duplicate)
|
||||
{
|
||||
child_cfg_t *child_cfg;
|
||||
child_cfg_create_t child = {
|
||||
.mode = MODE_TUNNEL,
|
||||
};
|
||||
ike_sa_t *a, *b;
|
||||
|
||||
exchange_test_helper->establish_sa(exchange_test_helper,
|
||||
&a, &b, NULL);
|
||||
|
||||
assert_no_jobs_scheduled();
|
||||
assert_hook_not_called(child_updown);
|
||||
assert_hook_not_called(message);
|
||||
child_cfg = child_cfg_create("child", &child);
|
||||
child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
|
||||
child_cfg->add_traffic_selector(child_cfg, TRUE,
|
||||
traffic_selector_create_dynamic(0, 0, 65535));
|
||||
child_cfg->add_traffic_selector(child_cfg, FALSE,
|
||||
traffic_selector_create_dynamic(0, 0, 65535));
|
||||
child_cfg->get_ref(child_cfg);
|
||||
call_ikesa(a, initiate, child_cfg, NULL);
|
||||
assert_child_sa_count(a, 1);
|
||||
assert_sa_idle(a);
|
||||
|
||||
call_ikesa(b, initiate, child_cfg, NULL);
|
||||
assert_child_sa_count(b, 1);
|
||||
assert_sa_idle(b);
|
||||
assert_hook();
|
||||
assert_hook();
|
||||
assert_scheduler();
|
||||
|
||||
call_ikesa(a, destroy);
|
||||
call_ikesa(b, destroy);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
/**
|
||||
* One of the peers tries to create a new CHILD_SA while the other concurrently
|
||||
* started to rekey the IKE_SA. TEMPORARY_FAILURE should be returned on both
|
||||
@@ -31,6 +72,8 @@ START_TEST(test_collision_ike_rekey)
|
||||
child_cfg_t *child_cfg;
|
||||
child_cfg_create_t child = {
|
||||
.mode = MODE_TUNNEL,
|
||||
/* make sure this is not a duplicate of the initial CHILD_SA */
|
||||
.mark_out = { .value = 42, .mask = 0xffffffff },
|
||||
};
|
||||
ike_sa_t *a, *b;
|
||||
|
||||
@@ -98,6 +141,10 @@ Suite *child_create_suite_create()
|
||||
|
||||
s = suite_create("child create");
|
||||
|
||||
tc = tcase_create("initiate duplicate");
|
||||
tcase_add_test(tc, test_duplicate);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("collisions ike rekey");
|
||||
tcase_add_test(tc, test_collision_ike_rekey);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
Reference in New Issue
Block a user