diff --git a/src/security/core/include/dds/security/core/dds_security_fsm.h b/src/security/core/include/dds/security/core/dds_security_fsm.h index 96f24d9..dfa547c 100644 --- a/src/security/core/include/dds/security/core/dds_security_fsm.h +++ b/src/security/core/include/dds/security/core/dds_security_fsm.h @@ -142,10 +142,10 @@ dds_security_fsm_dispatch(struct dds_security_fsm *fsm, int32_t event_id, bool p * * @param fsm The state machine * - * @return The current state of the given state machine + * @return true iff fsm not in initial or final state */ -DDS_EXPORT const dds_security_fsm_state* -dds_security_fsm_current_state(struct dds_security_fsm *fsm); +DDS_EXPORT bool +dds_security_fsm_running(struct dds_security_fsm *fsm); /** * Stops the state machine. diff --git a/src/security/core/src/dds_security_fsm.c b/src/security/core/src/dds_security_fsm.c index 03bd287..d96b97e 100644 --- a/src/security/core/src/dds_security_fsm.c +++ b/src/security/core/src/dds_security_fsm.c @@ -363,17 +363,13 @@ void dds_security_fsm_dispatch (struct dds_security_fsm *fsm, int32_t event_id, ddsrt_mutex_unlock (&fsm->control->lock); } -const dds_security_fsm_state * dds_security_fsm_current_state (struct dds_security_fsm *fsm) +bool dds_security_fsm_running (struct dds_security_fsm *fsm) { - const dds_security_fsm_state *state; - assert(fsm); - ddsrt_mutex_lock (&fsm->control->lock); - state = fsm->current; + const bool running = (fsm->current != NULL || fsm->busy); ddsrt_mutex_unlock (&fsm->control->lock); - - return state; + return running; } void dds_security_fsm_set_debug (struct dds_security_fsm *fsm, dds_security_fsm_debug func) diff --git a/src/security/core/tests/fsm.c b/src/security/core/tests/fsm.c index e947dfe..ad38996 100644 --- a/src/security/core/tests/fsm.c +++ b/src/security/core/tests/fsm.c @@ -26,6 +26,7 @@ static dds_entity_t g_participant = 0; static ddsrt_mutex_t g_lock; +static ddsrt_cond_t g_cond; static struct dds_security_fsm_control *g_fsm_control = NULL; #define DO_SIMPLE(name, var, bit) static void name(struct dds_security_fsm *fsm, void *arg) { \ @@ -34,9 +35,91 @@ static struct dds_security_fsm_control *g_fsm_control = NULL; printf("Transition %s\n", __FUNCTION__); \ ddsrt_mutex_lock(&g_lock); \ visited_##var |= 1u << (bit); \ + ddsrt_cond_broadcast(&g_cond); \ ddsrt_mutex_unlock(&g_lock); \ } +static struct dds_security_fsm *fsm_auth; +static uint32_t visited_auth; +static uint32_t correct_fsm; +static uint32_t correct_arg; +static int validate_remote_identity_first; +static int begin_handshake_reply_first; +static bool in_handshake_init_message_wait; + +static struct dds_security_fsm *fsm_test; +static uint32_t visited_test; +static int do_stuff_counter; +static int do_other_stuff_counter; + +static struct dds_security_fsm *fsm_timeout; +static uint32_t visited_timeout; +static uint32_t correct_fsm_timeout; +static uint32_t correct_arg_timeout; + +static struct ddsi_domaingv *get_entity_gv (dds_entity_t handle) +{ + struct dds_entity *e; + dds_return_t rc = dds_entity_pin (handle, &e); + CU_ASSERT_FATAL (rc == 0); + struct ddsi_domaingv * const gv = &e->m_domain->gv; + dds_entity_unpin (e); + return gv; +} + +static void fsm_control_init(void) +{ + g_participant = dds_create_participant (DDS_DOMAIN_DEFAULT, NULL, NULL); + CU_ASSERT_FATAL (g_participant > 0); + ddsrt_mutex_init (&g_lock); + ddsrt_cond_init (&g_cond); + + g_fsm_control = dds_security_fsm_control_create (get_entity_gv (g_participant)); + dds_return_t rc = dds_security_fsm_control_start (g_fsm_control, NULL); + CU_ASSERT_EQUAL_FATAL (rc, 0); + + validate_remote_identity_first = 1; + begin_handshake_reply_first = 1; + visited_auth = 0; + visited_test = 0; + visited_timeout = 0; + in_handshake_init_message_wait = false; + do_stuff_counter = 0; + do_other_stuff_counter = 0; + visited_timeout = 0; + correct_fsm_timeout = 0; + correct_arg_timeout = 0; +} + +static void fsm_control_fini (void) +{ + dds_security_fsm_control_stop (g_fsm_control); + dds_security_fsm_control_free (g_fsm_control); + ddsrt_mutex_destroy (&g_lock); + ddsrt_cond_destroy (&g_cond); + dds_delete (g_participant); +} + +static void a (struct dds_security_fsm *fsm, void *arg) +{ + printf ("[%p] Transition %s\n", fsm, __FUNCTION__); + ddsrt_mutex_lock (&g_lock); + if (arg != NULL) + correct_arg = *((int *) arg) == FSM_AUTH_ARG ? 1 : 0; + correct_fsm = (fsm == fsm_auth) ? 1 : 0; + visited_auth |= 1u << 0; + ddsrt_cond_broadcast (&g_cond); + ddsrt_mutex_unlock (&g_lock); +} + +DO_SIMPLE (b, auth, 1) +DO_SIMPLE (c, auth, 2) +DO_SIMPLE (d, auth, 3) +DO_SIMPLE (e, auth, 4) +DO_SIMPLE (f, auth, 5) +DO_SIMPLE (g, auth, 6) +DO_SIMPLE (h, auth, 7) + typedef enum { VALIDATION_PENDING_RETRY, VALIDATION_FAILED, @@ -46,18 +129,11 @@ typedef enum { VALIDATION_PENDING_HANDSHAKE_REQUEST, plugin_ret_MAX } plugin_ret; +#define SHM_MSG_RECEIVED (plugin_ret_MAX + 1) -static struct dds_security_fsm *fsm_auth; -static uint32_t visited_auth = 0; -static uint32_t correct_fsm = 0; -static uint32_t correct_arg = 0; -static int validate_remote_identity_first = 1; -static int begin_handshake_reply_first = 1; - - -static plugin_ret validate_remote_identity(void) +static plugin_ret validate_remote_identity (void) { - printf("validate_remote_identity - %d\n", validate_remote_identity_first); + printf ("validate_remote_identity - %d\n", validate_remote_identity_first); if (validate_remote_identity_first) { validate_remote_identity_first = 0; @@ -66,9 +142,9 @@ static plugin_ret validate_remote_identity(void) return VALIDATION_PENDING_HANDSHAKE_MESSAGE; } -static plugin_ret begin_handshake_reply(void) +static plugin_ret begin_handshake_reply (void) { - printf("begin_handshake_reply - %d\n", begin_handshake_reply_first); + printf ("begin_handshake_reply - %d\n", begin_handshake_reply_first); if (begin_handshake_reply_first) { begin_handshake_reply_first = 0; @@ -77,59 +153,41 @@ static plugin_ret begin_handshake_reply(void) return VALIDATION_OK_FINAL_MESSAGE; } -static plugin_ret get_shared_secret(void) +static plugin_ret get_shared_secret (void) { return VALIDATION_OK; } /* State actions */ -static void fsm_validate_remote_identity(struct dds_security_fsm *fsm, void *arg) +static void fsm_validate_remote_identity (struct dds_security_fsm *fsm, void *arg) { DDSRT_UNUSED_ARG(arg); - plugin_ret ret = validate_remote_identity(); - printf("[%p] State %s (ret %d)\n", fsm, __FUNCTION__, (int) ret); - dds_security_fsm_dispatch(fsm, (int32_t) ret, false); + plugin_ret ret = validate_remote_identity (); + printf ("[%p] State %s (ret %d)\n", fsm, __FUNCTION__, (int) ret); + dds_security_fsm_dispatch (fsm, (int32_t) ret, false); } -static void fsm_begin_handshake_reply(struct dds_security_fsm *fsm, void *arg) +static void fsm_begin_handshake_reply (struct dds_security_fsm *fsm, void *arg) { - DDSRT_UNUSED_ARG(arg); - plugin_ret ret = begin_handshake_reply(); + DDSRT_UNUSED_ARG (arg); + plugin_ret ret = begin_handshake_reply (); if (ret == VALIDATION_OK_FINAL_MESSAGE) - ret = get_shared_secret(); - printf("[%p] State %s (ret %d)\n", fsm, __FUNCTION__, (int) ret); - dds_security_fsm_dispatch(fsm, (int32_t) ret, false); + ret = get_shared_secret (); + printf ("[%p] State %s (ret %d)\n", fsm, __FUNCTION__, (int) ret); + dds_security_fsm_dispatch (fsm, (int32_t) ret, false); } -/* A few states from the handshake state-machine. */ -static dds_security_fsm_state StateValidateRemoteIdentity = {fsm_validate_remote_identity, 0}; -static dds_security_fsm_state StateValRemIdentityRetryWait = {NULL, 100000000}; -static dds_security_fsm_state StateHandshakeInitMessageWait = {NULL, 0}; -static dds_security_fsm_state state_beginHandshakeReply = {fsm_begin_handshake_reply, 0}; -static dds_security_fsm_state state_beginHsReplyWait = {NULL, 100000000}; - -static void a(struct dds_security_fsm *fsm, void *arg) +static void on_handshake_init_message_wait (struct dds_security_fsm *fsm, void *arg) { - printf("[%p] Transition %s\n", fsm, __FUNCTION__); + (void) fsm; (void) arg; ddsrt_mutex_lock (&g_lock); - if (arg != NULL) - correct_arg = *((int *)arg) == FSM_AUTH_ARG ? 1 : 0; - correct_fsm = (fsm == fsm_auth) ? 1 : 0; - visited_auth |= 1u << 0; + in_handshake_init_message_wait = true; + ddsrt_cond_broadcast (&g_cond); ddsrt_mutex_unlock (&g_lock); } -DO_SIMPLE(b, auth, 1) -DO_SIMPLE(c, auth, 2) -DO_SIMPLE(d, auth, 3) -DO_SIMPLE(e, auth, 4) -DO_SIMPLE(f, auth, 5) -DO_SIMPLE(g, auth, 6) -DO_SIMPLE(h, auth, 7) - -#define SHM_MSG_RECEIVED (plugin_ret_MAX + 1) - -/* +/* A few states from the handshake state-machine + * * .--. * |##|--------------------------------------. * '--' a() v @@ -163,136 +221,131 @@ DO_SIMPLE(h, auth, 7) * .-. * '-' */ -static dds_security_fsm_transition HandshakeTransistions[] = { - {NULL, DDS_SECURITY_FSM_EVENT_AUTO, a, &StateValidateRemoteIdentity}, // NULL state is the start state - {&StateValidateRemoteIdentity, VALIDATION_PENDING_RETRY, b, &StateValRemIdentityRetryWait}, - {&StateValidateRemoteIdentity, VALIDATION_PENDING_HANDSHAKE_MESSAGE, c, &StateHandshakeInitMessageWait}, - {&StateValRemIdentityRetryWait, DDS_SECURITY_FSM_EVENT_TIMEOUT, d, &StateValidateRemoteIdentity}, - {&StateHandshakeInitMessageWait, SHM_MSG_RECEIVED, e, &state_beginHandshakeReply}, - {&state_beginHandshakeReply, VALIDATION_PENDING_RETRY, f, &state_beginHsReplyWait}, - {&state_beginHandshakeReply, VALIDATION_OK, g, NULL}, // Reaching NULL means end of state-diagram - {&state_beginHsReplyWait, DDS_SECURITY_FSM_EVENT_TIMEOUT, h, &state_beginHandshakeReply} +static const dds_security_fsm_state StateValidateRemoteIdentity = { fsm_validate_remote_identity, 0 }; +static const dds_security_fsm_state StateValRemIdentityRetryWait = { NULL, 100000000 }; +static const dds_security_fsm_state StateHandshakeInitMessageWait = { on_handshake_init_message_wait, 0 }; +static const dds_security_fsm_state state_beginHandshakeReply = { fsm_begin_handshake_reply, 0 }; +static const dds_security_fsm_state state_beginHsReplyWait = { NULL, 100000000 }; +static const dds_security_fsm_transition HandshakeTransistions[] = { + { NULL, DDS_SECURITY_FSM_EVENT_AUTO, a, &StateValidateRemoteIdentity }, // NULL state is the start state + { &StateValidateRemoteIdentity, VALIDATION_PENDING_RETRY, b, &StateValRemIdentityRetryWait }, + { &StateValidateRemoteIdentity, VALIDATION_PENDING_HANDSHAKE_MESSAGE, c, &StateHandshakeInitMessageWait }, + { &StateValRemIdentityRetryWait, DDS_SECURITY_FSM_EVENT_TIMEOUT, d, &StateValidateRemoteIdentity }, + { &StateHandshakeInitMessageWait, SHM_MSG_RECEIVED, e, &state_beginHandshakeReply }, + { &state_beginHandshakeReply, VALIDATION_PENDING_RETRY, f, &state_beginHsReplyWait}, + { &state_beginHandshakeReply, VALIDATION_OK, g, NULL }, // Reaching NULL means end of state-diagram + { &state_beginHsReplyWait, DDS_SECURITY_FSM_EVENT_TIMEOUT, h, &state_beginHandshakeReply } }; -static const uint32_t HandshakeTransistionsSize = sizeof(HandshakeTransistions)/sizeof(HandshakeTransistions[0]); +static const uint32_t HandshakeTransistionsSize = sizeof (HandshakeTransistions) / sizeof (HandshakeTransistions[0]); - -/* Example State Machine properties and methods */ typedef enum { - eventX, eventY, eventZ, + eventX, eventY, eventZ, } test_events; -static struct dds_security_fsm *fsm_test; -static uint32_t visited_test = 0; -static int do_stuff_counter = 0; -static int do_other_stuff_counter = 0; +DO_SIMPLE (do_start, test, 0) +DO_SIMPLE (do_restart, test, 1) +DO_SIMPLE (do_event_stuff, test, 4) -DO_SIMPLE(do_start, test, 0) -DO_SIMPLE(do_restart, test, 1) -DO_SIMPLE(do_event_stuff, test, 4) - -static void do_stuff(struct dds_security_fsm *fsm, void *arg) +static void do_stuff (struct dds_security_fsm *fsm, void *arg) { - DDSRT_UNUSED_ARG(fsm); - DDSRT_UNUSED_ARG(arg); - printf("Transition %s - %d\n", __FUNCTION__, do_stuff_counter); + DDSRT_UNUSED_ARG (fsm); + DDSRT_UNUSED_ARG (arg); + printf ("Transition %s - %d\n", __FUNCTION__, do_stuff_counter); ddsrt_mutex_lock (&g_lock); visited_test |= 1u << 2; + ddsrt_cond_broadcast (&g_cond); ddsrt_mutex_unlock (&g_lock); if (do_stuff_counter < 2) - dds_security_fsm_dispatch(fsm, eventZ, false); + dds_security_fsm_dispatch (fsm, eventZ, false); else if (do_stuff_counter == 2) - dds_security_fsm_dispatch(fsm, eventY, false); + dds_security_fsm_dispatch (fsm, eventY, false); ++do_stuff_counter; } -static void do_other_stuff(struct dds_security_fsm *fsm, void *arg) +static void do_other_stuff (struct dds_security_fsm *fsm, void *arg) { - DDSRT_UNUSED_ARG(fsm); - DDSRT_UNUSED_ARG(arg); - printf("Transition %s - %d\n", __FUNCTION__, do_other_stuff_counter); + DDSRT_UNUSED_ARG (fsm); + DDSRT_UNUSED_ARG (arg); + printf ("Transition %s - %d\n", __FUNCTION__, do_other_stuff_counter); ddsrt_mutex_lock (&g_lock); visited_test |= 1u << 3; + ddsrt_cond_broadcast (&g_cond); ddsrt_mutex_unlock (&g_lock); if (do_other_stuff_counter == 0) - dds_security_fsm_dispatch(fsm, DDS_SECURITY_FSM_EVENT_AUTO, false); + dds_security_fsm_dispatch (fsm, DDS_SECURITY_FSM_EVENT_AUTO, false); else if (do_other_stuff_counter == 1) - dds_security_fsm_dispatch(fsm, eventY, false); + dds_security_fsm_dispatch (fsm, eventY, false); else if (do_other_stuff_counter == 2) - dds_security_fsm_dispatch(fsm, eventX, false); + dds_security_fsm_dispatch (fsm, eventX, false); ++do_other_stuff_counter; } -static dds_security_fsm_state state_a = {do_stuff, 0}; -static dds_security_fsm_state state_b = {do_stuff, 100000000}; -static dds_security_fsm_state state_c = {NULL, 0}; -static dds_security_fsm_state state_d = {do_other_stuff, 0}; - -static dds_security_fsm_transition Transitions[] = { - {NULL, DDS_SECURITY_FSM_EVENT_AUTO, do_start, &state_a}, // NULL state is the start state - {&state_a, eventZ, NULL, &state_b}, - {&state_a, eventY, do_other_stuff, &state_c}, - {&state_b, eventX, NULL, NULL}, // Reaching NULL means end of state-diagram - {&state_b, eventZ, do_restart, &state_a}, - {&state_c, DDS_SECURITY_FSM_EVENT_AUTO, do_event_stuff, &state_d}, - {&state_d, eventY, do_event_stuff, &state_d}, - {&state_d, eventX, do_stuff, NULL}, // Reaching NULL means end of sttimeoutate-diagram +static const dds_security_fsm_state state_a = { do_stuff, 0 }; +static const dds_security_fsm_state state_b = { do_stuff, 100000000 }; +static const dds_security_fsm_state state_c = { NULL, 0 }; +static const dds_security_fsm_state state_d = { do_other_stuff, 0 }; +static const dds_security_fsm_transition Transitions[] = { + { NULL, DDS_SECURITY_FSM_EVENT_AUTO, do_start, &state_a }, // NULL state is the start state + { &state_a, eventZ, NULL, &state_b }, + { &state_a, eventY, do_other_stuff, &state_c }, + { &state_b, eventX, NULL, NULL }, // Reaching NULL means end of state-diagram + { &state_b, eventZ, do_restart, &state_a }, + { &state_c, DDS_SECURITY_FSM_EVENT_AUTO, do_event_stuff, &state_d }, + { &state_d, eventY, do_event_stuff, &state_d }, + { &state_d, eventX, do_stuff, NULL }, // Reaching NULL means end of sttimeoutate-diagram }; -static const uint32_t TransitionsSize = sizeof(Transitions)/sizeof(Transitions[0]); - +static const uint32_t TransitionsSize = sizeof (Transitions) / sizeof (Transitions[0]); /* Timeout State Machine properties and methods */ typedef enum { - event_to_timeout, event_to_interrupt, event_to_end, + event_to_timeout, event_to_interrupt, event_to_end, } timeout_events; struct fsm_timeout_arg { int id; }; -static struct dds_security_fsm *fsm_timeout; -static uint32_t visited_timeout = 0; -static uint32_t correct_fsm_timeout = 0; -static uint32_t correct_arg_timeout = 0; static struct fsm_timeout_arg fsm_arg = { .id = FSM_AUTH_ARG }; -DO_SIMPLE(do_interrupt, timeout, 0) -DO_SIMPLE(timeout_cb2, timeout, 3) +DO_SIMPLE (do_interrupt, timeout, 0) +DO_SIMPLE (timeout_cb2, timeout, 3) -static void do_timeout(struct dds_security_fsm *fsm, void *arg) +static void do_timeout (struct dds_security_fsm *fsm, void *arg) { - DDSRT_UNUSED_ARG(arg); - printf("Transition >>>> %s\n", __FUNCTION__); + DDSRT_UNUSED_ARG (arg); + printf ("Transition >>>> %s\n", __FUNCTION__); ddsrt_mutex_lock (&g_lock); visited_timeout |= 1u << 1; + ddsrt_cond_broadcast (&g_cond); ddsrt_mutex_unlock (&g_lock); - printf("Transition <<<< %s\n", __FUNCTION__); - dds_security_fsm_dispatch(fsm, event_to_timeout, false); + printf ("Transition <<<< %s\n", __FUNCTION__); + dds_security_fsm_dispatch (fsm, event_to_timeout, false); } -static void timeout_cb(struct dds_security_fsm *fsm, void *arg) +static void timeout_cb (struct dds_security_fsm *fsm, void *arg) { struct fsm_timeout_arg *farg = arg; - printf("timeout_cb\n"); + printf ("timeout_cb\n"); ddsrt_mutex_lock (&g_lock); visited_timeout |= 1u << 2; if (farg != NULL) - correct_arg_timeout = farg->id == FSM_AUTH_ARG ? 1 : 0; - correct_fsm_timeout = fsm == fsm_timeout ? 1 : 0; + correct_arg_timeout = (farg->id == FSM_AUTH_ARG ? 1 : 0); + correct_fsm_timeout = (fsm == fsm_timeout ? 1 : 0); + ddsrt_cond_broadcast (&g_cond); ddsrt_mutex_unlock (&g_lock); } -static dds_security_fsm_state state_initial = {do_timeout, 0}; -static dds_security_fsm_state state_wait_timeout = {NULL, DDS_SECS(4)}; -static dds_security_fsm_state state_interrupt = {do_interrupt, 0}; - +static const dds_security_fsm_state state_initial = { do_timeout, 0 }; +static const dds_security_fsm_state state_wait_timeout = { NULL, DDS_SECS (4) }; +static const dds_security_fsm_state state_interrupt = { do_interrupt, 0 }; static const dds_security_fsm_transition timeout_transitions[] = { - {NULL, DDS_SECURITY_FSM_EVENT_AUTO, NULL, &state_initial}, // NULL state is the start state - {&state_initial, event_to_timeout, NULL, &state_wait_timeout}, - {&state_wait_timeout, DDS_SECURITY_FSM_EVENT_TIMEOUT, NULL, &state_interrupt}, - {&state_wait_timeout, event_to_interrupt, NULL, &state_interrupt}, - {&state_interrupt, event_to_end, NULL, NULL}, // Reaching NULL means end of state-diagram + { NULL, DDS_SECURITY_FSM_EVENT_AUTO, NULL, &state_initial }, // NULL state is the start state + { &state_initial, event_to_timeout, NULL, &state_wait_timeout }, + { &state_wait_timeout, DDS_SECURITY_FSM_EVENT_TIMEOUT, NULL, &state_interrupt }, + { &state_wait_timeout, event_to_interrupt, NULL, &state_interrupt }, + { &state_interrupt, event_to_end, NULL, NULL }, // Reaching NULL means end of state-diagram }; -static const uint32_t timeout_transitionsSize = sizeof(timeout_transitions)/sizeof(timeout_transitions[0]); +static const uint32_t timeout_transitionsSize = sizeof (timeout_transitions) / sizeof (timeout_transitions[0]); /* Parallel Timeout State Machines properties and methods */ static struct dds_security_fsm *fsm_timeout1; @@ -304,104 +357,81 @@ static dds_time_t time1 = 0; static dds_time_t time2 = 0; static dds_time_t time3 = 0; -static void state_par_time1(struct dds_security_fsm *fsm, void *arg) +static void state_par_time1 (struct dds_security_fsm *fsm, void *arg) { - DDSRT_UNUSED_ARG(fsm); - DDSRT_UNUSED_ARG(arg); - time1 = dds_time(); + DDSRT_UNUSED_ARG (fsm); + DDSRT_UNUSED_ARG (arg); + time1 = dds_time (); } -static void state_par_time2(struct dds_security_fsm *fsm, void *arg) +static void state_par_time2 (struct dds_security_fsm *fsm, void *arg) { - DDSRT_UNUSED_ARG(fsm); - DDSRT_UNUSED_ARG(arg); - time2 = dds_time(); + DDSRT_UNUSED_ARG (fsm); + DDSRT_UNUSED_ARG (arg); + time2 = dds_time (); } -static void state_par_time3(struct dds_security_fsm *fsm, void *arg) +static void state_par_time3 (struct dds_security_fsm *fsm, void *arg) { - DDSRT_UNUSED_ARG(fsm); - DDSRT_UNUSED_ARG(arg); - time3 = dds_time(); + DDSRT_UNUSED_ARG (fsm); + DDSRT_UNUSED_ARG (arg); + time3 = dds_time (); } -static dds_security_fsm_state state_par_timeout1 = {NULL, DDS_SECS(1)}; -static dds_security_fsm_state state_par_timeout2 = {NULL, DDS_SECS(2)}; -static dds_security_fsm_state state_par_timeout3 = {NULL, DDS_SECS(1)}; +static const dds_security_fsm_state state_par_timeout1 = { NULL, DDS_SECS (1) }; +static const dds_security_fsm_state state_par_timeout2 = { NULL, DDS_SECS (2) }; +static const dds_security_fsm_state state_par_timeout3 = { NULL, DDS_SECS (1) }; -static dds_security_fsm_transition parallel_timeout_transitions_1[] = { - {NULL, DDS_SECURITY_FSM_EVENT_AUTO, NULL, &state_par_timeout1}, // NULL state is the startfsm_control_thread state - {&state_par_timeout1, DDS_SECURITY_FSM_EVENT_TIMEOUT, &state_par_time1, NULL}, // Reaching NULL means end of state-diagram +static const dds_security_fsm_transition parallel_timeout_transitions_1[] = { + { NULL, DDS_SECURITY_FSM_EVENT_AUTO, NULL, &state_par_timeout1 }, // NULL state is the startfsm_control_thread state + { &state_par_timeout1, DDS_SECURITY_FSM_EVENT_TIMEOUT, &state_par_time1, NULL }, // Reaching NULL means end of state-diagram }; -static const uint32_t parallel_timeout_transitionsSize_1 = sizeof(parallel_timeout_transitions_1) / sizeof(parallel_timeout_transitions_1[0]); +static const uint32_t parallel_timeout_transitionsSize_1 = sizeof (parallel_timeout_transitions_1) / sizeof (parallel_timeout_transitions_1[0]); -static dds_security_fsm_transition parallel_timeout_transitions_2[] = { - {NULL, DDS_SECURITY_FSM_EVENT_AUTO, NULL, &state_par_timeout2}, // NULL state is the start state - {&state_par_timeout2, DDS_SECURITY_FSM_EVENT_TIMEOUT, &state_par_time2, NULL}, // Reaching NULL means end of state-diagram +static const dds_security_fsm_transition parallel_timeout_transitions_2[] = { + { NULL, DDS_SECURITY_FSM_EVENT_AUTO, NULL, &state_par_timeout2 }, // NULL state is the start state + { &state_par_timeout2, DDS_SECURITY_FSM_EVENT_TIMEOUT, &state_par_time2, NULL }, // Reaching NULL means end of state-diagram }; -static const uint32_t parallel_timeout_transitionsSize_2 = sizeof(parallel_timeout_transitions_2) / sizeof(parallel_timeout_transitions_2[0]); +static const uint32_t parallel_timeout_transitionsSize_2 = sizeof (parallel_timeout_transitions_2) / sizeof (parallel_timeout_transitions_2[0]); -static dds_security_fsm_transition parallel_timeout_transitions_3[] = { - {NULL, DDS_SECURITY_FSM_EVENT_AUTO, NULL, &state_par_timeout3}, // NULL state is the start state - {&state_par_timeout3, DDS_SECURITY_FSM_EVENT_TIMEOUT, &state_par_time3, NULL}, // Reaching NULL means end of state-diagram +static const dds_security_fsm_transition parallel_timeout_transitions_3[] = { + { NULL, DDS_SECURITY_FSM_EVENT_AUTO, NULL, &state_par_timeout3 }, // NULL state is the start state + { &state_par_timeout3, DDS_SECURITY_FSM_EVENT_TIMEOUT, &state_par_time3, NULL }, // Reaching NULL means end of state-diagram }; -static const uint32_t parallel_timeout_transitionsSize_3 = sizeof(parallel_timeout_transitions_3) / sizeof(parallel_timeout_transitions_3[0]); - -static void fsm_control_init(void) -{ - struct dds_entity *e; - g_participant = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL); - CU_ASSERT_FATAL(g_participant > 0); - ddsrt_mutex_init(&g_lock); - dds_return_t rc = dds_entity_pin(g_participant, &e); - CU_ASSERT_FATAL(rc == 0); - g_fsm_control = dds_security_fsm_control_create(&e->m_domain->gv); - CU_ASSERT_FATAL(g_fsm_control != NULL); - dds_entity_unpin(e); - rc = dds_security_fsm_control_start(g_fsm_control, NULL); - CU_ASSERT_EQUAL_FATAL(rc, 0); -} - -static void fsm_control_fini(void) -{ - dds_security_fsm_control_stop(g_fsm_control); - dds_security_fsm_control_free(g_fsm_control); - ddsrt_mutex_destroy (&g_lock); - dds_delete(g_participant); -} +static const uint32_t parallel_timeout_transitionsSize_3 = sizeof (parallel_timeout_transitions_3) / sizeof (parallel_timeout_transitions_3[0]); CU_Test(ddssec_fsm, create, .init = fsm_control_init, .fini = fsm_control_fini) { /* Test single running state machine. Check creation of a single State Machine */ - fsm_auth = dds_security_fsm_create(g_fsm_control, HandshakeTransistions, HandshakeTransistionsSize, &fsm_arg); - CU_ASSERT_FATAL(fsm_auth != NULL) + fsm_auth = dds_security_fsm_create (g_fsm_control, HandshakeTransistions, HandshakeTransistionsSize, &fsm_arg); + CU_ASSERT_FATAL (fsm_auth != NULL) /* set a delay that doesn't expire. Should be terminate when fsm is freed. */ - dds_security_fsm_set_timeout(fsm_auth, timeout_cb, DDS_SECS(30)); - dds_security_fsm_start(fsm_auth); - - int n = 100; - while (dds_security_fsm_current_state(fsm_auth) != &StateHandshakeInitMessageWait && n-- > 0) - dds_sleepfor(DDS_MSECS(100)); - CU_ASSERT(n > 0); - dds_security_fsm_dispatch(fsm_auth, SHM_MSG_RECEIVED, false); - - n = 100; - while (dds_security_fsm_current_state(fsm_auth) != NULL && n-- > 0) - dds_sleepfor(DDS_MSECS(100)); - CU_ASSERT(n > 0); + dds_security_fsm_set_timeout (fsm_auth, timeout_cb, DDS_SECS(30)); + dds_security_fsm_start (fsm_auth); ddsrt_mutex_lock (&g_lock); - CU_ASSERT(visited_auth == 0xff); + while (!in_handshake_init_message_wait) + { + printf ("waiting until handshake_init_message_wait state reached\n"); + ddsrt_cond_wait (&g_cond, &g_lock); + } + ddsrt_mutex_unlock (&g_lock); + dds_security_fsm_dispatch (fsm_auth, SHM_MSG_RECEIVED, false); + while (dds_security_fsm_running (fsm_auth)) + dds_sleepfor (DDS_MSECS (10)); + ddsrt_mutex_lock (&g_lock); + printf ("visited_auth == 0x%x\n", visited_auth); + CU_ASSERT (visited_auth == 0xff); ddsrt_mutex_unlock (&g_lock); /* Check correct callback parameter passing (from fsm to user defined methods) */ CU_ASSERT(correct_arg && correct_fsm); - dds_security_fsm_free(fsm_auth); + dds_security_fsm_free (fsm_auth); /* Check whether timeout callback has NOT been invoked */ ddsrt_mutex_lock (&g_lock); - CU_ASSERT(visited_timeout == 0); + CU_ASSERT (visited_timeout == 0); ddsrt_mutex_unlock (&g_lock); } @@ -410,48 +440,42 @@ CU_Test(ddssec_fsm, multiple, .init = fsm_control_init, .fini = fsm_control_fini { validate_remote_identity_first = 0; begin_handshake_reply_first = 0; - visited_auth = 0; - visited_test = 0; - fsm_auth = dds_security_fsm_create(g_fsm_control, HandshakeTransistions, HandshakeTransistionsSize, NULL); - CU_ASSERT_FATAL(fsm_auth != NULL); + fsm_auth = dds_security_fsm_create (g_fsm_control, HandshakeTransistions, HandshakeTransistionsSize, NULL); + CU_ASSERT_FATAL (fsm_auth != NULL); - fsm_test = dds_security_fsm_create(g_fsm_control, Transitions, TransitionsSize, NULL); - CU_ASSERT_FATAL(fsm_test != NULL); + fsm_test = dds_security_fsm_create (g_fsm_control, Transitions, TransitionsSize, NULL); + CU_ASSERT_FATAL (fsm_test != NULL); - dds_security_fsm_start(fsm_auth); - dds_security_fsm_start(fsm_test); + dds_security_fsm_start (fsm_auth); + dds_security_fsm_start (fsm_test); /* Check the results of multiple running State Machines */ - int n = 100; /* 10 sec */ - while (dds_security_fsm_current_state(fsm_auth) != &StateHandshakeInitMessageWait && n-- > 0) - dds_sleepfor(DDS_MSECS(100)); - CU_ASSERT_FATAL(n > 0); - - n = 100; /* 10 sec */ - dds_security_fsm_dispatch(fsm_auth, SHM_MSG_RECEIVED, false); - while (dds_security_fsm_current_state(fsm_auth) != NULL && n-- > 0) - dds_sleepfor(DDS_MSECS(100)); - CU_ASSERT_FATAL(n > 0); - - // not all bits are set since we're running the state machine a second time ddsrt_mutex_lock (&g_lock); - CU_ASSERT_FATAL(visited_auth == 0x55); + while (!in_handshake_init_message_wait) + { + printf ("waiting until handshake_init_message_wait state reached\n"); + ddsrt_cond_wait (&g_cond, &g_lock); + } + ddsrt_mutex_unlock (&g_lock); + dds_security_fsm_dispatch (fsm_auth, SHM_MSG_RECEIVED, false); + while (dds_security_fsm_running (fsm_auth)) + dds_sleepfor (DDS_MSECS (10)); + ddsrt_mutex_lock (&g_lock); + printf ("visited_auth == 0x%x\n", visited_auth); + CU_ASSERT (visited_auth == 0x55); ddsrt_mutex_unlock (&g_lock); /* Wait for the last state to occur */ - n = 100; /* 10 sec */ - while (dds_security_fsm_current_state(fsm_test) != NULL && n-- > 0) - dds_sleepfor(DDS_MSECS(100)); - CU_ASSERT_FATAL(n > 0); - + while (dds_security_fsm_running (fsm_auth)) + dds_sleepfor (DDS_MSECS (10)); ddsrt_mutex_lock (&g_lock); - CU_ASSERT(visited_test == 0x1f); + printf ("visited_test == 0x%x\n", visited_test); + CU_ASSERT (visited_test == 0x1f); ddsrt_mutex_unlock (&g_lock); - dds_security_fsm_free(fsm_auth); - dds_security_fsm_free(fsm_test); - + dds_security_fsm_free (fsm_auth); + dds_security_fsm_free (fsm_test); } /** @@ -459,123 +483,89 @@ CU_Test(ddssec_fsm, multiple, .init = fsm_control_init, .fini = fsm_control_fini */ CU_Test(ddssec_fsm, timeout, .init = fsm_control_init, .fini = fsm_control_fini) { - visited_timeout = 0; /* Test timeout monitoring of state machines */ - fsm_timeout = dds_security_fsm_create(g_fsm_control, timeout_transitions, timeout_transitionsSize, &fsm_arg); - CU_ASSERT(fsm_timeout != NULL); - dds_security_fsm_set_timeout(fsm_timeout, timeout_cb, DDS_SECS(1)); - dds_security_fsm_start(fsm_timeout); - - int n = 100; /* 10 sec */ + fsm_timeout = dds_security_fsm_create (g_fsm_control, timeout_transitions, timeout_transitionsSize, &fsm_arg); + CU_ASSERT_FATAL (fsm_timeout != NULL); + dds_security_fsm_set_timeout (fsm_timeout, timeout_cb, DDS_SECS(1)); + dds_security_fsm_start (fsm_timeout); ddsrt_mutex_lock (&g_lock); - while (visited_timeout != 0x7 && n-- > 0) - { - ddsrt_mutex_unlock (&g_lock); - dds_sleepfor(DDS_MSECS(100)); - ddsrt_mutex_lock (&g_lock); - } - CU_ASSERT(n > 0); - CU_ASSERT(visited_timeout == 0x7); - CU_ASSERT(correct_arg_timeout && correct_fsm_timeout); + while (visited_timeout != 0x7) + ddsrt_cond_wait (&g_cond, &g_lock); + CU_ASSERT (correct_arg_timeout && correct_fsm_timeout); ddsrt_mutex_unlock (&g_lock); - dds_security_fsm_free(fsm_timeout); + dds_security_fsm_free (fsm_timeout); } /* Check the double global timeout */ CU_Test(ddssec_fsm, double_timeout, .init = fsm_control_init, .fini = fsm_control_fini) { - visited_timeout = 0; - fsm_timeout = dds_security_fsm_create(g_fsm_control, timeout_transitions, timeout_transitionsSize, &fsm_arg); - CU_ASSERT(fsm_timeout != NULL); + fsm_timeout = dds_security_fsm_create (g_fsm_control, timeout_transitions, timeout_transitionsSize, &fsm_arg); + CU_ASSERT_FATAL (fsm_timeout != NULL); + fsm_timeout2 = dds_security_fsm_create (g_fsm_control, timeout_transitions, timeout_transitionsSize, &fsm_arg); + CU_ASSERT_FATAL (fsm_timeout2 != NULL); - fsm_timeout2 = dds_security_fsm_create(g_fsm_control, timeout_transitions, timeout_transitionsSize, &fsm_arg); - CU_ASSERT(fsm_timeout2 != NULL); + dds_security_fsm_set_timeout (fsm_timeout, timeout_cb, DDS_SECS (1)); + dds_security_fsm_set_timeout (fsm_timeout2, timeout_cb2, DDS_SECS (2)); - dds_security_fsm_set_timeout(fsm_timeout, timeout_cb, DDS_SECS(1)); - dds_security_fsm_set_timeout(fsm_timeout2, timeout_cb2, DDS_SECS(2)); - dds_security_fsm_start(fsm_timeout); - dds_security_fsm_start(fsm_timeout2); - int n = 100; + dds_security_fsm_start (fsm_timeout); + dds_security_fsm_start (fsm_timeout2); ddsrt_mutex_lock (&g_lock); - while (visited_timeout != 0xf && n-- > 0) - { - ddsrt_mutex_unlock (&g_lock); - dds_sleepfor(DDS_MSECS(100)); - ddsrt_mutex_lock (&g_lock); - } - CU_ASSERT(visited_timeout == 0xf); + while (visited_timeout != 0xf) + ddsrt_cond_wait (&g_cond, &g_lock); ddsrt_mutex_unlock (&g_lock); - dds_security_fsm_free(fsm_timeout); - dds_security_fsm_free(fsm_timeout2); + dds_security_fsm_free (fsm_timeout); + dds_security_fsm_free (fsm_timeout2); } /* Check parallel state timeouts */ CU_Test(ddssec_fsm, parallel_timeout, .init = fsm_control_init, .fini = fsm_control_fini) { - visited_timeout = 0; + fsm_timeout1 = dds_security_fsm_create (g_fsm_control, parallel_timeout_transitions_1, parallel_timeout_transitionsSize_1, &fsm_arg); + CU_ASSERT_FATAL (fsm_timeout1 != NULL); + fsm_timeout2 = dds_security_fsm_create (g_fsm_control, parallel_timeout_transitions_2, parallel_timeout_transitionsSize_2, &fsm_arg); + CU_ASSERT_FATAL (fsm_timeout2 != NULL); + fsm_timeout3 = dds_security_fsm_create (g_fsm_control, parallel_timeout_transitions_3, parallel_timeout_transitionsSize_3, &fsm_arg); + CU_ASSERT_FATAL (fsm_timeout3 != NULL); - fsm_timeout1 = dds_security_fsm_create(g_fsm_control, parallel_timeout_transitions_1, parallel_timeout_transitionsSize_1, &fsm_arg); - CU_ASSERT_FATAL(fsm_timeout1 != NULL); - fsm_timeout2 = dds_security_fsm_create(g_fsm_control, parallel_timeout_transitions_2, parallel_timeout_transitionsSize_2, &fsm_arg); - CU_ASSERT_FATAL(fsm_timeout2 != NULL); - fsm_timeout3 = dds_security_fsm_create(g_fsm_control, parallel_timeout_transitions_3, parallel_timeout_transitionsSize_3, &fsm_arg); - CU_ASSERT_FATAL(fsm_timeout3 != NULL); + time0 = dds_time (); + dds_security_fsm_start (fsm_timeout1); + dds_security_fsm_start (fsm_timeout2); + dds_security_fsm_start (fsm_timeout3); - time0 = dds_time(); - dds_security_fsm_start(fsm_timeout1); - dds_security_fsm_start(fsm_timeout2); - dds_security_fsm_start(fsm_timeout3); - - int n = 300; - while (((dds_security_fsm_current_state(fsm_timeout1) == NULL) - || (dds_security_fsm_current_state(fsm_timeout2) == NULL) - || (dds_security_fsm_current_state(fsm_timeout3) == NULL)) && n-- > 0) - { - dds_sleepfor(DDS_MSECS(100)); - } - while (((dds_security_fsm_current_state(fsm_timeout1) != NULL) - || (dds_security_fsm_current_state(fsm_timeout2) != NULL) - || (dds_security_fsm_current_state(fsm_timeout3) != NULL)) && n-- > 0) - { - dds_sleepfor(DDS_MSECS(100)); - } + while (!(dds_security_fsm_running (fsm_timeout1) && dds_security_fsm_running (fsm_timeout2) && dds_security_fsm_running (fsm_timeout3))) + dds_sleepfor (DDS_MSECS (10)); + while (dds_security_fsm_running (fsm_timeout1) || dds_security_fsm_running (fsm_timeout2) || dds_security_fsm_running (fsm_timeout3)) + dds_sleepfor (DDS_MSECS (10)); dds_duration_t delta1 = time1 - time0; dds_duration_t delta2 = time2 - time0; dds_duration_t delta3 = time3 - time0; - printf("time0 %"PRId64"\n", time0); - printf("time1 %"PRId64", delta1 %"PRId64"\n", time1, delta1); - printf("time2 %"PRId64", delta2 %"PRId64"\n", time2, delta2); - printf("time3 %"PRId64", delta3 %"PRId64"\n", time3, delta3); - CU_ASSERT(delta1 > DDS_MSECS(750)); - CU_ASSERT(delta1 < DDS_MSECS(1250)); - CU_ASSERT(delta2 > DDS_MSECS(1750)); - CU_ASSERT(delta2 < DDS_MSECS(2250)); - CU_ASSERT(delta3 > DDS_MSECS(750)); - CU_ASSERT(delta3 < DDS_MSECS(1250)); + printf ("time0 %"PRId64"\n", time0); + printf ("time1 %"PRId64", delta1 %"PRId64"\n", time1, delta1); + printf ("time2 %"PRId64", delta2 %"PRId64"\n", time2, delta2); + printf ("time3 %"PRId64", delta3 %"PRId64"\n", time3, delta3); + CU_ASSERT (delta1 > DDS_MSECS (750)); + CU_ASSERT (delta1 < DDS_MSECS (1250)); + CU_ASSERT (delta2 > DDS_MSECS (1750)); + CU_ASSERT (delta2 < DDS_MSECS (2250)); + CU_ASSERT (delta3 > DDS_MSECS (750)); + CU_ASSERT (delta3 < DDS_MSECS (1250)); - dds_security_fsm_free(fsm_timeout1); - dds_security_fsm_free(fsm_timeout2); - dds_security_fsm_free(fsm_timeout3); + dds_security_fsm_free (fsm_timeout1); + dds_security_fsm_free (fsm_timeout2); + dds_security_fsm_free (fsm_timeout3); } /* Delete with event timeout */ CU_Test(ddssec_fsm, delete_with_timeout, .init = fsm_control_init, .fini = fsm_control_fini) { - fsm_timeout = dds_security_fsm_create(g_fsm_control, timeout_transitions, timeout_transitionsSize, &fsm_arg); - CU_ASSERT (fsm_timeout != NULL) - visited_timeout = 0; - dds_security_fsm_start(fsm_timeout); - - int n = 100; + fsm_timeout = dds_security_fsm_create (g_fsm_control, timeout_transitions, timeout_transitionsSize, &fsm_arg); + CU_ASSERT_FATAL (fsm_timeout != NULL) + dds_security_fsm_start (fsm_timeout); ddsrt_mutex_lock (&g_lock); - while (visited_timeout == 0 && n-- > 0) - { - ddsrt_mutex_unlock (&g_lock); - dds_sleepfor(DDS_MSECS(100)); - ddsrt_mutex_lock (&g_lock); - } + while (visited_timeout == 0) + ddsrt_cond_wait (&g_cond, &g_lock); ddsrt_mutex_unlock (&g_lock); - dds_security_fsm_free(fsm_timeout); + dds_security_fsm_free (fsm_timeout); }