]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
unit-tests: Ensure listeners can track SAs via ike/child_updown/rekey()
authorTobias Brunner <tobias@strongswan.org>
Fri, 9 Sep 2022 16:34:29 +0000 (18:34 +0200)
committerTobias Brunner <tobias@strongswan.org>
Wed, 7 Aug 2024 14:20:19 +0000 (16:20 +0200)
Previously, it could happen that child_rekey() was triggered twice for
the same "old" SA.  For listeners that would mean they'd loose track as
they'd be tracking a new SA that wasn't relevant anymore and for which
no updown event would ever get triggered (it was the redundant SA in a
collision).  This new assert ensures that events are triggered in a
predictable way and listeners can track SAs properly.

src/libcharon/tests/suites/test_child_rekey.c
src/libcharon/tests/suites/test_ike_rekey.c
src/libcharon/tests/utils/exchange_test_asserts.c
src/libcharon/tests/utils/exchange_test_asserts.h

index 4b10e92053f4550c1db7cb939c9069fc31037e58..b61f31c7cb179d8475ada76d2261821281bb3336 100644 (file)
@@ -60,6 +60,8 @@ START_TEST(test_regular)
        ike_sa_t *a, *b;
        uint32_t spi_a = _i+1, spi_b = 2-_i;
 
+       assert_track_sas_start();
+
        if (_i)
        {       /* responder rekeys the CHILD_SA (SPI 2) */
                exchange_test_helper->establish_sa(exchange_test_helper,
@@ -127,6 +129,7 @@ START_TEST(test_regular)
 
        /* child_updown */
        assert_hook();
+       assert_track_sas(2, 2);
 
        call_ikesa(a, destroy);
        call_ikesa(b, destroy);
@@ -154,6 +157,8 @@ START_TEST(test_regular_multi_ke)
        ike_sa_t *a, *b;
        uint32_t spi_a = _i+1, spi_b = 2-_i;
 
+       assert_track_sas_start();
+
        if (_i)
        {       /* responder rekeys the CHILD_SA (SPI 2) */
                exchange_test_helper->establish_sa(exchange_test_helper,
@@ -239,6 +244,7 @@ START_TEST(test_regular_multi_ke)
 
        /* child_updown */
        assert_hook();
+       assert_track_sas(2, 2);
 
        call_ikesa(a, destroy);
        call_ikesa(b, destroy);
@@ -263,6 +269,8 @@ START_TEST(test_regular_ke_invalid)
        ike_sa_t *a, *b;
        uint32_t spi_a = _i+1, spi_b = 2-_i;
 
+       assert_track_sas_start();
+
        if (_i)
        {       /* responder rekeys the CHILD_SA (SPI 2) */
                exchange_test_helper->establish_sa(exchange_test_helper,
@@ -399,6 +407,7 @@ START_TEST(test_regular_ke_invalid)
 
        /* child_updown */
        assert_hook();
+       assert_track_sas(2, 2);
 
        call_ikesa(a, destroy);
        call_ikesa(b, destroy);
@@ -423,6 +432,8 @@ START_TEST(test_regular_ke_invalid_multi_ke)
        ike_sa_t *a, *b;
        uint32_t spi_a = _i+1, spi_b = 2-_i;
 
+       assert_track_sas_start();
+
        if (_i)
        {       /* responder rekeys the CHILD_SA (SPI 2) */
                exchange_test_helper->establish_sa(exchange_test_helper,
@@ -596,6 +607,7 @@ START_TEST(test_regular_ke_invalid_multi_ke)
 
        /* child_updown */
        assert_hook();
+       assert_track_sas(2, 2);
 
        call_ikesa(a, destroy);
        call_ikesa(b, destroy);
@@ -610,6 +622,8 @@ START_TEST(test_regular_responder_ignore_soft_expire)
 {
        ike_sa_t *a, *b;
 
+       assert_track_sas_start();
+
        exchange_test_helper->establish_sa(exchange_test_helper,
                                                                           &a, &b, NULL);
        initiate_rekey(a, 1);
@@ -676,6 +690,7 @@ START_TEST(test_regular_responder_ignore_soft_expire)
        /* child_rekey/child_updown */
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        call_ikesa(a, destroy);
        call_ikesa(b, destroy);
@@ -691,6 +706,8 @@ START_TEST(test_regular_responder_handle_hard_expire)
 {
        ike_sa_t *a, *b;
 
+       assert_track_sas_start();
+
        exchange_test_helper->establish_sa(exchange_test_helper,
                                                                           &a, &b, NULL);
        initiate_rekey(a, 1);
@@ -755,6 +772,7 @@ START_TEST(test_regular_responder_handle_hard_expire)
        /* child_rekey/child_updown */
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        call_ikesa(a, destroy);
        call_ikesa(b, destroy);
@@ -770,6 +788,8 @@ START_TEST(test_regular_responder_delete)
 {
        ike_sa_t *a, *b;
 
+       assert_track_sas_start();
+
        exchange_test_helper->establish_sa(exchange_test_helper,
                                                                           &a, &b, NULL);
        initiate_rekey(a, 1);
@@ -869,6 +889,7 @@ START_TEST(test_regular_responder_delete)
        /* child_rekey/child_updown */
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 0);
 
        call_ikesa(a, destroy);
        call_ikesa(b, destroy);
@@ -883,6 +904,8 @@ START_TEST(test_regular_responder_lost_sa)
 {
        ike_sa_t *a, *b;
 
+       assert_track_sas_start();
+
        exchange_test_helper->establish_sa(exchange_test_helper,
                                                                           &a, &b, NULL);
        initiate_rekey(a, 1);
@@ -925,6 +948,9 @@ START_TEST(test_regular_responder_lost_sa)
 
        /* child_rekey */
        assert_hook();
+       /* the additional CHILD_SA here is the one we destroyed on b without
+        * triggering an event */
+       assert_track_sas(2, 3);
 
        assert_sa_idle(a);
        assert_sa_idle(b);
@@ -985,6 +1011,8 @@ START_TEST(test_regular_responder_incorrect_delete)
        ike_sa_t *a, *b;
        message_t *msg;
 
+       assert_track_sas_start();
+
        exchange_test_helper->establish_sa(exchange_test_helper,
                                                                           &a, &b, NULL);
        initiate_rekey(a, 1);
@@ -1054,6 +1082,7 @@ START_TEST(test_regular_responder_incorrect_delete)
        /* child_rekey/child_updown */
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        call_ikesa(a, destroy);
        call_ikesa(b, destroy);
@@ -1068,6 +1097,8 @@ START_TEST(test_collision)
 {
        ike_sa_t *a, *b;
 
+       assert_track_sas_start();
+
        exchange_test_helper->establish_sa(exchange_test_helper,
                                                                           &a, &b, NULL);
 
@@ -1279,6 +1310,7 @@ START_TEST(test_collision)
        /* child_rekey/child_updown */
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        call_ikesa(a, destroy);
        call_ikesa(b, destroy);
@@ -1293,6 +1325,8 @@ START_TEST(test_collision_multi_ke)
 {
        ike_sa_t *a, *b;
 
+       assert_track_sas_start();
+
        exchange_test_helper->establish_sa(exchange_test_helper,
                                                                           &a, &b, &multi_ke_conf);
 
@@ -1481,6 +1515,7 @@ START_TEST(test_collision_multi_ke)
        /* child_rekey/child_updown */
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        call_ikesa(a, destroy);
        call_ikesa(b, destroy);
@@ -1504,6 +1539,8 @@ START_TEST(test_collision_mixed)
        };
        ike_sa_t *a, *b;
 
+       assert_track_sas_start();
+
        /* let's accept what the peer proposes first */
        lib->settings->set_bool(lib->settings, "%s.prefer_configured_proposals",
                                                        FALSE, lib->ns);
@@ -1742,6 +1779,7 @@ START_TEST(test_collision_mixed)
        /* child_rekey/child_updown */
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        call_ikesa(a, destroy);
        call_ikesa(b, destroy);
@@ -1769,6 +1807,8 @@ START_TEST(test_collision_delayed_response)
        ike_sa_t *a, *b;
        message_t *msg;
 
+       assert_track_sas_start();
+
        exchange_test_helper->establish_sa(exchange_test_helper,
                                                                           &a, &b, NULL);
 
@@ -1980,6 +2020,7 @@ START_TEST(test_collision_delayed_response)
        /* child_rekey/child_updown */
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        call_ikesa(a, destroy);
        call_ikesa(b, destroy);
@@ -2007,6 +2048,8 @@ START_TEST(test_collision_delayed_response_delete)
        ike_sa_t *a, *b;
        message_t *msg;
 
+       assert_track_sas_start();
+
        exchange_test_helper->establish_sa(exchange_test_helper,
                                                                           &a, &b, NULL);
 
@@ -2258,6 +2301,7 @@ START_TEST(test_collision_delayed_response_delete)
        /* child_rekey/child_updown */
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 0);
 
        call_ikesa(a, destroy);
        call_ikesa(b, destroy);
@@ -2296,6 +2340,8 @@ START_TEST(test_collision_delayed_response_multi_ke)
 
        _i %= 2;
 
+       assert_track_sas_start();
+
        exchange_test_helper->establish_sa(exchange_test_helper,
                                                                           &a, &b, &multi_ke_conf);
 
@@ -2435,6 +2481,7 @@ START_TEST(test_collision_delayed_response_multi_ke)
        /* child_rekey/child_updown */
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        call_ikesa(a, destroy);
        call_ikesa(b, destroy);
@@ -2473,6 +2520,8 @@ START_TEST(test_collision_delayed_request)
 
        _i %= 3;
 
+       assert_track_sas_start();
+
        exchange_test_helper->establish_sa(exchange_test_helper,
                                                                           &a, &b, NULL);
 
@@ -2610,6 +2659,7 @@ START_TEST(test_collision_delayed_request)
        /* child_rekey/child_updown */
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        assert_sa_idle(a);
        assert_sa_idle(b);
@@ -2638,6 +2688,8 @@ START_TEST(test_collision_delayed_request_more)
        ike_sa_t *a, *b;
        message_t *msg;
 
+       assert_track_sas_start();
+
        exchange_test_helper->establish_sa(exchange_test_helper,
                                                                           &a, &b, NULL);
 
@@ -2737,6 +2789,7 @@ START_TEST(test_collision_delayed_request_more)
        /* child_rekey/child_updown */
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        assert_sa_idle(a);
        assert_sa_idle(b);
@@ -2767,6 +2820,8 @@ START_TEST(test_collision_delayed_request_more_delete)
        ike_sa_t *a, *b;
        message_t *msg;
 
+       assert_track_sas_start();
+
        exchange_test_helper->establish_sa(exchange_test_helper,
                                                                           &a, &b, NULL);
 
@@ -2902,6 +2957,7 @@ START_TEST(test_collision_delayed_request_more_delete)
        /* child_rekey/child_updown */
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 0);
 
        assert_sa_idle(a);
        assert_sa_idle(b);
@@ -2938,6 +2994,8 @@ START_TEST(test_collision_delayed_request_multi_ke)
 
        _i %= 3;
 
+       assert_track_sas_start();
+
        exchange_test_helper->establish_sa(exchange_test_helper,
                                                                           &a, &b, &multi_ke_conf);
 
@@ -3075,6 +3133,7 @@ START_TEST(test_collision_delayed_request_multi_ke)
        /* child_rekey/child_updown */
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        assert_sa_idle(a);
        assert_sa_idle(b);
@@ -3101,6 +3160,8 @@ START_TEST(test_collision_ke_invalid)
        };
        ike_sa_t *a, *b;
 
+       assert_track_sas_start();
+
        exchange_test_helper->establish_sa(exchange_test_helper,
                                                                           &a, &b, &conf);
 
@@ -3312,6 +3373,7 @@ START_TEST(test_collision_ke_invalid)
        /* child_rekey/child_updown */
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        assert_sa_idle(a);
        assert_sa_idle(b);
@@ -3338,6 +3400,8 @@ START_TEST(test_collision_ke_invalid_delayed_retry)
        ike_sa_t *a, *b;
        message_t *msg;
 
+       assert_track_sas_start();
+
        exchange_test_helper->establish_sa(exchange_test_helper,
                                                                           &a, &b, &conf);
 
@@ -3468,6 +3532,7 @@ START_TEST(test_collision_ke_invalid_delayed_retry)
        /* child_rekey/child_updown */
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        assert_sa_idle(a);
        assert_sa_idle(b);
@@ -3489,6 +3554,8 @@ START_TEST(test_collision_responder_incorrect_delete)
        ike_sa_t *a, *b;
        message_t *msg;
 
+       assert_track_sas_start();
+
        exchange_test_helper->establish_sa(exchange_test_helper,
                                                                           &a, &b, NULL);
 
@@ -3612,6 +3679,7 @@ START_TEST(test_collision_responder_incorrect_delete)
        /* child_rekey/child_updown */
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        call_ikesa(a, destroy);
        call_ikesa(b, destroy);
@@ -3634,6 +3702,8 @@ START_TEST(test_collision_delete)
        ike_sa_t *a, *b;
        uint32_t spi_a = _i+1, spi_b = 2-_i;
 
+       assert_track_sas_start();
+
        if (_i)
        {       /* responder rekeys the CHILD_SA (SPI 2) */
                exchange_test_helper->establish_sa(exchange_test_helper,
@@ -3696,6 +3766,7 @@ START_TEST(test_collision_delete)
 
        /* child_rekey */
        assert_hook();
+       assert_track_sas(2, 0);
 
        assert_sa_idle(a);
        assert_sa_idle(b);
@@ -3722,6 +3793,8 @@ START_TEST(test_collision_delete_multi_ke)
        ike_sa_t *a, *b;
        uint32_t spi_a = _i+1, spi_b = 2-_i;
 
+       assert_track_sas_start();
+
        if (_i)
        {       /* responder rekeys the CHILD_SA (SPI 2) */
                exchange_test_helper->establish_sa(exchange_test_helper,
@@ -3786,6 +3859,7 @@ START_TEST(test_collision_delete_multi_ke)
 
        /* child_rekey */
        assert_hook();
+       assert_track_sas(2, 0);
 
        assert_sa_idle(a);
        assert_sa_idle(b);
@@ -3814,6 +3888,8 @@ START_TEST(test_collision_delete_drop_delete)
        message_t *msg;
        uint32_t spi_a = _i+1, spi_b = 2-_i;
 
+       assert_track_sas_start();
+
        if (_i)
        {       /* responder rekeys the CHILD_SA (SPI 2) */
                exchange_test_helper->establish_sa(exchange_test_helper,
@@ -3872,6 +3948,7 @@ START_TEST(test_collision_delete_drop_delete)
 
        /* child_rekey */
        assert_hook();
+       assert_track_sas(2, 0);
 
        assert_sa_idle(a);
        assert_sa_idle(b);
@@ -3899,6 +3976,8 @@ START_TEST(test_collision_delete_drop_rekey)
        message_t *msg;
        uint32_t spi_a = _i+1, spi_b = 2-_i;
 
+       assert_track_sas_start();
+
        if (_i)
        {       /* responder rekeys the CHILD_SA (SPI 2) */
                exchange_test_helper->establish_sa(exchange_test_helper,
@@ -3962,6 +4041,7 @@ START_TEST(test_collision_delete_drop_rekey)
 
        /* child_rekey */
        assert_hook();
+       assert_track_sas(2, 0);
 
        assert_sa_idle(a);
        assert_sa_idle(b);
@@ -3989,6 +4069,8 @@ START_TEST(test_collision_delete_delayed_response)
        message_t *msg;
        uint32_t spi_a = _i+1, spi_b = 2-_i;
 
+       assert_track_sas_start();
+
        if (_i)
        {       /* responder rekeys the CHILD_SA (SPI 2) */
                exchange_test_helper->establish_sa(exchange_test_helper,
@@ -4091,6 +4173,7 @@ START_TEST(test_collision_delete_delayed_response)
 
        /* child_rekey */
        assert_hook();
+       assert_track_sas(2, 0);
 
        assert_sa_idle(a);
        assert_sa_idle(b);
@@ -4116,6 +4199,8 @@ START_TEST(test_collision_ike_rekey)
        ike_sa_t *a, *b;
        uint32_t spi_a = _i+1;
 
+       assert_track_sas_start();
+
        if (_i)
        {       /* responder rekeys the CHILD_SA (SPI 2) */
                exchange_test_helper->establish_sa(exchange_test_helper,
@@ -4172,6 +4257,7 @@ START_TEST(test_collision_ike_rekey)
        /* ike_rekey/child_rekey */
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        assert_sa_idle(a);
        assert_sa_idle(b);
@@ -4199,6 +4285,8 @@ START_TEST(test_collision_ike_delete)
        message_t *msg;
        status_t s;
 
+       assert_track_sas_start();
+
        if (_i)
        {       /* responder rekeys the CHILD_SA (SPI 2) */
                exchange_test_helper->establish_sa(exchange_test_helper,
@@ -4259,6 +4347,7 @@ START_TEST(test_collision_ike_delete)
 
        /* child_rekey */
        assert_hook();
+       assert_track_sas(0, 0);
 }
 END_TEST
 
index 98c588b1eb2c42c8cdcc2e677a719043306a8281..c6691acf44aa040e68c61079eebcccce476a57c7 100644 (file)
@@ -40,6 +40,8 @@ START_TEST(test_regular)
        ike_sa_t *a, *b, *new_sa;
        status_t s;
 
+       assert_track_sas_start();
+
        if (_i)
        {       /* responder rekeys the IKE_SA */
                exchange_test_helper->establish_sa(exchange_test_helper,
@@ -98,6 +100,7 @@ START_TEST(test_regular)
        assert_hook();
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        charon->ike_sa_manager->flush(charon->ike_sa_manager);
 }
@@ -124,6 +127,8 @@ START_TEST(test_regular_multi_ke)
        ike_sa_t *a, *b, *new_sa;
        status_t s;
 
+       assert_track_sas_start();
+
        if (_i)
        {       /* responder rekeys the IKE_SA */
                exchange_test_helper->establish_sa(exchange_test_helper,
@@ -202,6 +207,7 @@ START_TEST(test_regular_multi_ke)
        assert_hook();
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        charon->ike_sa_manager->flush(charon->ike_sa_manager);
 }
@@ -225,6 +231,8 @@ START_TEST(test_regular_ke_invalid)
        ike_sa_t *a, *b, *sa;
        status_t s;
 
+       assert_track_sas_start();
+
        lib->settings->set_bool(lib->settings, "%s.prefer_configured_proposals",
                                                        FALSE, lib->ns);
        if (_i)
@@ -303,6 +311,7 @@ START_TEST(test_regular_ke_invalid)
        assert_hook();
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        charon->ike_sa_manager->flush(charon->ike_sa_manager);
 }
@@ -326,6 +335,8 @@ START_TEST(test_regular_ke_invalid_multi_ke)
        ike_sa_t *a, *b, *sa;
        status_t s;
 
+       assert_track_sas_start();
+
        lib->settings->set_bool(lib->settings, "%s.prefer_configured_proposals",
                                                        FALSE, lib->ns);
        if (_i)
@@ -423,6 +434,7 @@ START_TEST(test_regular_ke_invalid_multi_ke)
        assert_hook();
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        charon->ike_sa_manager->flush(charon->ike_sa_manager);
 }
@@ -437,6 +449,8 @@ START_TEST(test_collision)
        ike_sa_t *a, *b, *sa;
        status_t status;
 
+       assert_track_sas_start();
+
        exchange_test_helper->establish_sa(exchange_test_helper,
                                                                           &a, &b, NULL);
 
@@ -578,6 +592,7 @@ START_TEST(test_collision)
        assert_hook();
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        charon->ike_sa_manager->flush(charon->ike_sa_manager);
 }
@@ -593,6 +608,8 @@ START_TEST(test_collision_multi_ke)
        ike_sa_t *a, *b, *sa;
        status_t status;
 
+       assert_track_sas_start();
+
        exchange_test_helper->establish_sa(exchange_test_helper,
                                                                           &a, &b, &multi_ke_conf);
 
@@ -729,6 +746,7 @@ START_TEST(test_collision_multi_ke)
        assert_hook();
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        charon->ike_sa_manager->flush(charon->ike_sa_manager);
 }
@@ -752,6 +770,8 @@ START_TEST(test_collision_mixed)
        ike_sa_t *a, *b, *sa;
        status_t status;
 
+       assert_track_sas_start();
+
        /* let's accept what the peer proposes first */
        lib->settings->set_bool(lib->settings, "%s.prefer_configured_proposals",
                                                        FALSE, lib->ns);
@@ -953,6 +973,7 @@ START_TEST(test_collision_mixed)
        assert_hook();
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        charon->ike_sa_manager->flush(charon->ike_sa_manager);
 }
@@ -976,6 +997,8 @@ START_TEST(test_collision_ke_invalid)
        ike_sa_t *a, *b, *sa;
        status_t status;
 
+       assert_track_sas_start();
+
        lib->settings->set_bool(lib->settings, "%s.prefer_configured_proposals",
                                                        FALSE, lib->ns);
 
@@ -1165,6 +1188,7 @@ START_TEST(test_collision_ke_invalid)
        assert_hook();
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        charon->ike_sa_manager->flush(charon->ike_sa_manager);
 }
@@ -1187,6 +1211,8 @@ START_TEST(test_collision_ke_invalid_delayed_retry)
        message_t *msg;
        status_t s;
 
+       assert_track_sas_start();
+
        lib->settings->set_bool(lib->settings, "%s.prefer_configured_proposals",
                                                        FALSE, lib->ns);
 
@@ -1325,6 +1351,7 @@ START_TEST(test_collision_ke_invalid_delayed_retry)
        /* ike_updown/child_updown */
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        charon->ike_sa_manager->flush(charon->ike_sa_manager);
 }
@@ -1366,6 +1393,8 @@ START_TEST(test_collision_delayed_response)
        message_t *msg, *d;
        status_t s;
 
+       assert_track_sas_start();
+
        exchange_test_helper->establish_sa(exchange_test_helper,
                                                                           &a, &b, NULL);
 
@@ -1545,6 +1574,7 @@ START_TEST(test_collision_delayed_response)
        /* ike_updown/child_updown */
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        charon->ike_sa_manager->flush(charon->ike_sa_manager);
 }
@@ -1584,6 +1614,8 @@ START_TEST(test_collision_delayed_response_multi_ke)
 
        _i %= 2;
 
+       assert_track_sas_start();
+
        exchange_test_helper->establish_sa(exchange_test_helper,
                                                                           &a, &b, &multi_ke_conf);
 
@@ -1746,6 +1778,7 @@ START_TEST(test_collision_delayed_response_multi_ke)
        /* ike_updown/child_updown */
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        charon->ike_sa_manager->flush(charon->ike_sa_manager);
 }
@@ -1769,6 +1802,8 @@ START_TEST(test_collision_dropped_request)
        message_t *msg;
        status_t s;
 
+       assert_track_sas_start();
+
        exchange_test_helper->establish_sa(exchange_test_helper,
                                                                           &a, &b, NULL);
 
@@ -1848,6 +1883,7 @@ START_TEST(test_collision_dropped_request)
        /* ike_updown/child_updown */
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        charon->ike_sa_manager->flush(charon->ike_sa_manager);
 }
@@ -1874,6 +1910,8 @@ START_TEST(test_collision_delayed_request)
        message_t *msg;
        status_t s;
 
+       assert_track_sas_start();
+
        exchange_test_helper->establish_sa(exchange_test_helper,
                                                                           &a, &b, NULL);
 
@@ -1963,6 +2001,7 @@ START_TEST(test_collision_delayed_request)
        /* ike_updown/child_updown */
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        charon->ike_sa_manager->flush(charon->ike_sa_manager);
 }
@@ -1989,6 +2028,8 @@ START_TEST(test_collision_delayed_request_and_delete)
        message_t *msg;
        status_t s;
 
+       assert_track_sas_start();
+
        exchange_test_helper->establish_sa(exchange_test_helper,
                                                                           &a, &b, NULL);
 
@@ -2083,6 +2124,7 @@ START_TEST(test_collision_delayed_request_and_delete)
        /* ike_updown/child_updown */
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        charon->ike_sa_manager->flush(charon->ike_sa_manager);
 }
@@ -2117,6 +2159,8 @@ START_TEST(test_collision_delayed_request_multi_ke)
 
        _i %= 3;
 
+       assert_track_sas_start();
+
        exchange_test_helper->establish_sa(exchange_test_helper,
                                                                           &a, &b, &multi_ke_conf);
 
@@ -2256,6 +2300,7 @@ START_TEST(test_collision_delayed_request_multi_ke)
        /* ike_updown/child_updown */
        assert_hook();
        assert_hook();
+       assert_track_sas(2, 2);
 
        charon->ike_sa_manager->flush(charon->ike_sa_manager);
 }
@@ -2278,6 +2323,8 @@ START_TEST(test_collision_delete)
        message_t *msg;
        status_t s;
 
+       assert_track_sas_start();
+
        if (_i)
        {       /* responder rekeys the IKE_SA */
                exchange_test_helper->establish_sa(exchange_test_helper,
@@ -2340,6 +2387,7 @@ START_TEST(test_collision_delete)
 
        /* ike_rekey */
        assert_hook();
+       assert_track_sas(0, 0);
 }
 END_TEST
 
@@ -2361,6 +2409,8 @@ START_TEST(test_collision_delete_multi_ke)
        message_t *msg;
        status_t s;
 
+       assert_track_sas_start();
+
        if (_i)
        {       /* responder rekeys the IKE_SA */
                exchange_test_helper->establish_sa(exchange_test_helper,
@@ -2425,6 +2475,7 @@ START_TEST(test_collision_delete_multi_ke)
 
        /* ike_rekey */
        assert_hook();
+       assert_track_sas(0, 0);
 }
 END_TEST
 
@@ -2445,6 +2496,8 @@ START_TEST(test_collision_delete_drop_delete)
        message_t *msg;
        status_t s;
 
+       assert_track_sas_start();
+
        if (_i)
        {       /* responder rekeys the IKE_SA */
                exchange_test_helper->establish_sa(exchange_test_helper,
@@ -2511,6 +2564,7 @@ START_TEST(test_collision_delete_drop_delete)
 
        /* ike_rekey */
        assert_hook();
+       assert_track_sas(0, 0);
 }
 END_TEST
 
index 1a4fdda837f04ca4b73d2876c7c82f92ff025a6a..1db0215df5c906b69f684eb4f9de4d1ec63f81c5 100644 (file)
@@ -105,6 +105,129 @@ bool exchange_test_asserts_child_rekey(listener_t *listener, ike_sa_t *ike_sa,
        return TRUE;
 }
 
+/**
+ * Track SAs via updown event.
+ */
+static void track_sa_updown(listener_track_sas_assert_t *this, char *event,
+                                                       array_t *sas, uint32_t id, bool up)
+{
+       uint32_t existing;
+       bool found = FALSE;
+       int i;
+
+       if (up)
+       {
+               for (i = 0; i < array_count(sas); i++)
+               {
+                       array_get(sas, i, &existing);
+                       assert_listener_msg(id != existing, this, "duplicate %s(up) event "
+                                                               "for SA %u", event, id);
+               }
+               array_insert(sas, ARRAY_TAIL, &id);
+       }
+       else
+       {
+               for (i = 0; i < array_count(sas); i++)
+               {
+                       array_get(sas, i, &existing);
+                       if (id == existing)
+                       {
+                               array_remove(sas, i, NULL);
+                               found = TRUE;
+                               break;
+                       }
+               }
+               assert_listener_msg(found, this, "%s(down) event for unknown SA %u",
+                                                       event, id);
+       }
+}
+
+/**
+ * Track SAs via a rekey event.
+ */
+static void track_sa_rekey(listener_track_sas_assert_t *this, char *event,
+                                                  array_t *sas, uint32_t old_id, uint32_t new_id)
+{
+       uint32_t existing;
+       bool found = FALSE;
+       int i;
+
+       for (i = 0; i < array_count(sas); i++)
+       {
+               array_get(sas, i, &existing);
+               if (old_id == existing)
+               {
+                       array_remove(sas, i, NULL);
+                       found = TRUE;
+                       break;
+               }
+       }
+       assert_listener_msg(found, this, "%s() event for unknown old SA %u", event,
+                                               old_id);
+
+       for (i = 0; i < array_count(sas); i++)
+       {
+               array_get(sas, i, &existing);
+               assert_listener_msg(new_id != existing, this, "%s() event for "
+                                                       "already up new SA %u", event, new_id);
+       }
+       array_insert(sas, ARRAY_TAIL, &new_id);
+}
+
+/*
+ * Described in header
+ */
+bool exchange_test_asserts_track_ike_updown(listener_t *listener,
+                                                                                       ike_sa_t *ike_sa, bool up)
+{
+       listener_track_sas_assert_t *this = (listener_track_sas_assert_t*)listener;
+
+       track_sa_updown(this, "ike_updown", this->ike_sas,
+                                       ike_sa->get_unique_id(ike_sa), up);
+       return TRUE;
+}
+
+/*
+ * Described in header
+ */
+bool exchange_test_asserts_track_child_updown(listener_t *listener,
+                                                                                         ike_sa_t *ike_sa,
+                                                                                         child_sa_t *child_sa, bool up)
+{
+       listener_track_sas_assert_t *this = (listener_track_sas_assert_t*)listener;
+
+       track_sa_updown(this, "child_updown", this->child_sas,
+                                       child_sa->get_unique_id(child_sa), up);
+       return TRUE;
+}
+
+/*
+ * Described in header
+ */
+bool exchange_test_asserts_track_ike_rekey(listener_t *listener, ike_sa_t *old,
+                                                                                  ike_sa_t *new)
+{
+       listener_track_sas_assert_t *this = (listener_track_sas_assert_t*)listener;
+
+       track_sa_rekey(this, "ike_rekey", this->ike_sas, old->get_unique_id(old),
+                                  new->get_unique_id(new));
+       return TRUE;
+}
+
+/*
+ * Described in header
+ */
+bool exchange_test_asserts_track_child_rekey(listener_t *listener,
+                                                                                        ike_sa_t *ike_sa, child_sa_t *old,
+                                                                                        child_sa_t *new)
+{
+       listener_track_sas_assert_t *this = (listener_track_sas_assert_t*)listener;
+
+       track_sa_rekey(this, "child_rekey", this->child_sas, old->get_unique_id(old),
+                                  new->get_unique_id(new));
+       return TRUE;
+}
+
 /**
  * Assert a given message rule
  */
index e4ce81040379124c25f6d5a55b7272b4acc9e64d..c37f1c3bb91c9742c6d15256479412d82f8b843a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2016-2017 Tobias Brunner
+ * Copyright (C) 2016-2022 Tobias Brunner
  *
  * Copyright (C) secunet Security Networks AG
  *
@@ -27,6 +27,7 @@
 #include <bus/listeners/listener.h>
 
 typedef struct listener_hook_assert_t listener_hook_assert_t;
+typedef struct listener_track_sas_assert_t listener_track_sas_assert_t;
 typedef struct listener_message_assert_t listener_message_assert_t;
 typedef struct listener_message_rule_t listener_message_rule_t;
 typedef struct ipsec_sas_assert_t ipsec_sas_assert_t;
@@ -209,6 +210,99 @@ do { \
        } \
 } while(FALSE)
 
+/**
+ * Track SAs by following events.
+ */
+struct listener_track_sas_assert_t {
+
+       /**
+        * Implemented interface
+        */
+       listener_t listener;
+
+       /**
+        * Original source file
+        */
+       const char *file;
+
+       /**
+        * Source line
+        */
+       int line;
+
+       /**
+        * Tracked IKE_SAs.
+        */
+       array_t *ike_sas;
+
+       /**
+        * Tracked CHILD_SAs.
+        */
+       array_t *child_sas;
+};
+
+
+/**
+ * Implementation of listener_t::ike_updown.
+ */
+bool exchange_test_asserts_track_ike_updown(listener_t *this, ike_sa_t *ike_sa,
+                                                                                       bool up);
+
+/**
+ * Implementation of listener_t::child_updown.
+ */
+bool exchange_test_asserts_track_child_updown(listener_t *this, ike_sa_t *ike_sa,
+                                                                                         child_sa_t *child_sa, bool up);
+
+/**
+ * Implementation of listener_t::ike_rekey.
+ */
+bool exchange_test_asserts_track_ike_rekey(listener_t *this, ike_sa_t *old,
+                                                                                  ike_sa_t *new);
+
+/**
+ * Implementation of listener_t::child_rekey.
+ */
+bool exchange_test_asserts_track_child_rekey(listener_t *this, ike_sa_t *ike_sa,
+                                                                                        child_sa_t *old, child_sa_t *new);
+
+/**
+ * Start tracking SAs via their hooks.
+ */
+#define assert_track_sas_start() \
+do { \
+       listener_track_sas_assert_t _track_sas_listener = { \
+               .listener = { \
+                       .ike_updown = exchange_test_asserts_track_ike_updown, \
+                       .ike_rekey = exchange_test_asserts_track_ike_rekey, \
+                       .child_updown = exchange_test_asserts_track_child_updown, \
+                       .child_rekey = exchange_test_asserts_track_child_rekey, \
+               }, \
+               .file = __FILE__, \
+               .line = __LINE__, \
+               .ike_sas = array_create(sizeof(uint32_t), 8), \
+               .child_sas = array_create(sizeof(uint32_t), 8), \
+       }; \
+       exchange_test_helper->add_listener(exchange_test_helper, &_track_sas_listener.listener)
+
+/**
+ * Check if there are the right number of SAs still up.
+ *
+ * @param ike          the expected number of IKE_SAs
+ * @param child                the expected number of CHILD_SAs
+ */
+#define assert_track_sas(ike, child) \
+       charon->bus->remove_listener(charon->bus, &_track_sas_listener.listener); \
+       u_int _up_ike = array_count(_track_sas_listener.ike_sas); \
+       u_int _up_child = array_count(_track_sas_listener.child_sas); \
+       array_destroy(_track_sas_listener.ike_sas); \
+       array_destroy(_track_sas_listener.child_sas); \
+       assert_listener_msg(_up_ike == (ike), &_track_sas_listener, \
+                                               "%d IKE_SAs without matching down event", _up_ike); \
+       assert_listener_msg(_up_child == (child), &_track_sas_listener, \
+                                               "%d CHILD_SAs without matching down event", _up_child); \
+} while(FALSE)
+
 /**
  * Rules regarding payloads/notifies to expect/not expect in a message
  */