Fix security handshake test
Isolate domains by using unique tags when running tests that are using security handshake. And updated coding style and some minor refactoring in fsm and timed_cb tests. Signed-off-by: Dennis Potman <dennis.potman@adlinktech.com>
This commit is contained in:
		
							parent
							
								
									ea10dbd8e1
								
							
						
					
					
						commit
						e7f5ae354c
					
				
					 9 changed files with 990 additions and 1333 deletions
				
			
		| 
						 | 
					@ -62,8 +62,8 @@ function(add_wrapper libname linklibs)
 | 
				
			||||||
endfunction()
 | 
					endfunction()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set(security_core_test_sources
 | 
					set(security_core_test_sources
 | 
				
			||||||
    "tc_fsm.c"
 | 
					    "fsm.c"
 | 
				
			||||||
    "dds_security_core.c"
 | 
					    "timed_cb.c"
 | 
				
			||||||
    "security_utils.c"
 | 
					    "security_utils.c"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -102,8 +102,6 @@ target_include_directories(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set(common_etc_dir "${CMAKE_CURRENT_SOURCE_DIR}/common/etc")
 | 
					set(common_etc_dir "${CMAKE_CURRENT_SOURCE_DIR}/common/etc")
 | 
				
			||||||
set(plugin_wrapper_lib_dir "${CMAKE_CURRENT_BINARY_DIR}")
 | 
					set(plugin_wrapper_lib_dir "${CMAKE_CURRENT_BINARY_DIR}")
 | 
				
			||||||
file(TO_NATIVE_PATH "/" file_path_sep)
 | 
					 | 
				
			||||||
string(REPLACE "\\" "\\\\" file_path_sep ${file_path_sep})
 | 
					 | 
				
			||||||
configure_file("common/config_env.h.in" "common/config_env.h")
 | 
					configure_file("common/config_env.h.in" "common/config_env.h")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
target_link_libraries(cunit_security_core PRIVATE ddsc security_api SecurityCoreTests)
 | 
					target_link_libraries(cunit_security_core PRIVATE ddsc security_api SecurityCoreTests)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,6 +19,7 @@
 | 
				
			||||||
#include "dds/version.h"
 | 
					#include "dds/version.h"
 | 
				
			||||||
#include "dds/ddsrt/cdtors.h"
 | 
					#include "dds/ddsrt/cdtors.h"
 | 
				
			||||||
#include "dds/ddsrt/environ.h"
 | 
					#include "dds/ddsrt/environ.h"
 | 
				
			||||||
 | 
					#include "dds/ddsrt/process.h"
 | 
				
			||||||
#include "dds/ddsrt/heap.h"
 | 
					#include "dds/ddsrt/heap.h"
 | 
				
			||||||
#include "dds/ddsrt/string.h"
 | 
					#include "dds/ddsrt/string.h"
 | 
				
			||||||
#include "dds/ddsi/q_config.h"
 | 
					#include "dds/ddsi/q_config.h"
 | 
				
			||||||
| 
						 | 
					@ -36,8 +37,11 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char *config =
 | 
					static const char *config =
 | 
				
			||||||
    "${CYCLONEDDS_URI}${CYCLONEDDS_URI:+,}"
 | 
					    "${CYCLONEDDS_URI}${CYCLONEDDS_URI:+,}"
 | 
				
			||||||
    "<Discovery><ExternalDomainId>0</ExternalDomainId></Discovery>"
 | 
					 | 
				
			||||||
    "<Domain id=\"any\">"
 | 
					    "<Domain id=\"any\">"
 | 
				
			||||||
 | 
					    "  <Discovery>"
 | 
				
			||||||
 | 
					    "    <ExternalDomainId>0</ExternalDomainId>"
 | 
				
			||||||
 | 
					    "    <Tag>\\${CYCLONEDDS_PID}</Tag>"
 | 
				
			||||||
 | 
					    "  </Discovery>"
 | 
				
			||||||
    "  <Tracing><Verbosity>config</></>"
 | 
					    "  <Tracing><Verbosity>config</></>"
 | 
				
			||||||
    "  <DDSSecurity>"
 | 
					    "  <DDSSecurity>"
 | 
				
			||||||
    "    <Authentication>"
 | 
					    "    <Authentication>"
 | 
				
			||||||
| 
						 | 
					@ -87,8 +91,8 @@ static void authentication_init(bool different_ca, const char * trusted_ca_dir,
 | 
				
			||||||
    { NULL, NULL, 0 }
 | 
					    { NULL, NULL, 0 }
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  char *conf1 = ddsrt_expand_vars (config, &expand_lookup_vars_env, config_vars1);
 | 
					  char *conf1 = ddsrt_expand_vars_sh (config, &expand_lookup_vars_env, config_vars1);
 | 
				
			||||||
  char *conf2 = ddsrt_expand_vars (config, &expand_lookup_vars_env, config_vars2);
 | 
					  char *conf2 = ddsrt_expand_vars_sh (config, &expand_lookup_vars_env, config_vars2);
 | 
				
			||||||
  CU_ASSERT_EQUAL_FATAL (expand_lookup_unmatched (config_vars1), 0);
 | 
					  CU_ASSERT_EQUAL_FATAL (expand_lookup_unmatched (config_vars1), 0);
 | 
				
			||||||
  CU_ASSERT_EQUAL_FATAL (expand_lookup_unmatched (config_vars2), 0);
 | 
					  CU_ASSERT_EQUAL_FATAL (expand_lookup_unmatched (config_vars2), 0);
 | 
				
			||||||
  g_domain1 = dds_create_domain (DDS_DOMAINID1, conf1);
 | 
					  g_domain1 = dds_create_domain (DDS_DOMAINID1, conf1);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,7 +12,7 @@
 | 
				
			||||||
#ifndef CONFIG_ENV_H
 | 
					#ifndef CONFIG_ENV_H
 | 
				
			||||||
#define CONFIG_ENV_H
 | 
					#define CONFIG_ENV_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define FILE_PATH_SEP             "@file_path_sep@"
 | 
					#define FILE_PATH_SEP             "/"
 | 
				
			||||||
#define COMMON_ETC_DIR            "@common_etc_dir@"
 | 
					#define COMMON_ETC_DIR            "@common_etc_dir@"
 | 
				
			||||||
#define PLUGIN_WRAPPER_LIB_DIR    "@plugin_wrapper_lib_dir@"
 | 
					#define PLUGIN_WRAPPER_LIB_DIR    "@plugin_wrapper_lib_dir@"
 | 
				
			||||||
#define PLUGIN_WRAPPER_LIB_PREFIX "@CMAKE_SHARED_LIBRARY_PREFIX@"
 | 
					#define PLUGIN_WRAPPER_LIB_PREFIX "@CMAKE_SHARED_LIBRARY_PREFIX@"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,546 +0,0 @@
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Copyright(c) 2019 ADLINK Technology Limited and others
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program and the accompanying materials are made available under the
 | 
					 | 
				
			||||||
 * terms of the Eclipse Public License v. 2.0 which is available at
 | 
					 | 
				
			||||||
 * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
 | 
					 | 
				
			||||||
 * v. 1.0 which is available at
 | 
					 | 
				
			||||||
 * http://www.eclipse.org/org/documents/edl-v10.php.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
#include "CUnit/Test.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "dds/security/core/dds_security_timed_cb.h"
 | 
					 | 
				
			||||||
#include "dds/ddsrt/misc.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define SEQ_SIZE (16)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef struct {
 | 
					 | 
				
			||||||
    struct dds_security_timed_dispatcher_t *d;
 | 
					 | 
				
			||||||
    dds_security_timed_cb_kind kind;
 | 
					 | 
				
			||||||
    void *listener;
 | 
					 | 
				
			||||||
    void *arg;
 | 
					 | 
				
			||||||
    dds_time_t time;
 | 
					 | 
				
			||||||
} tc__sequence_data;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int g_sequence_idx = 0;
 | 
					 | 
				
			||||||
static tc__sequence_data g_sequence_array[SEQ_SIZE];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void simple_callback(struct dds_security_timed_dispatcher_t *d,
 | 
					 | 
				
			||||||
        dds_security_timed_cb_kind kind,
 | 
					 | 
				
			||||||
        void *listener,
 | 
					 | 
				
			||||||
        void *arg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    DDSRT_UNUSED_ARG(d);
 | 
					 | 
				
			||||||
    DDSRT_UNUSED_ARG(kind);
 | 
					 | 
				
			||||||
    DDSRT_UNUSED_ARG(listener);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (*((bool *)arg) == false)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        *((bool *)arg) = true;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        *((bool *)arg) = false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int g_order_callback_idx = 0;
 | 
					 | 
				
			||||||
static void* g_order_callback[2] = {(void*)NULL, (void*)NULL};
 | 
					 | 
				
			||||||
static void order_callback(struct dds_security_timed_dispatcher_t *d,
 | 
					 | 
				
			||||||
        dds_security_timed_cb_kind kind,
 | 
					 | 
				
			||||||
        void *listener,
 | 
					 | 
				
			||||||
        void *arg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    DDSRT_UNUSED_ARG(d);
 | 
					 | 
				
			||||||
    DDSRT_UNUSED_ARG(kind);
 | 
					 | 
				
			||||||
    DDSRT_UNUSED_ARG(listener);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    g_order_callback[g_order_callback_idx] = arg;
 | 
					 | 
				
			||||||
    g_order_callback_idx++;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void
 | 
					 | 
				
			||||||
tc__callback(
 | 
					 | 
				
			||||||
        struct dds_security_timed_dispatcher_t *d,
 | 
					 | 
				
			||||||
        dds_security_timed_cb_kind kind,
 | 
					 | 
				
			||||||
        void *listener,
 | 
					 | 
				
			||||||
        void *arg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    if (g_sequence_idx < SEQ_SIZE) {
 | 
					 | 
				
			||||||
        g_sequence_array[g_sequence_idx].d = d;
 | 
					 | 
				
			||||||
        g_sequence_array[g_sequence_idx].arg = arg;
 | 
					 | 
				
			||||||
        g_sequence_array[g_sequence_idx].kind = kind;
 | 
					 | 
				
			||||||
        g_sequence_array[g_sequence_idx].listener = listener;
 | 
					 | 
				
			||||||
        g_sequence_array[g_sequence_idx].time = dds_time();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    g_sequence_idx++;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
CU_Test(dds_security_timed_cb, simple_test)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    struct dds_security_timed_cb_data *tcb = dds_security_timed_cb_new();
 | 
					 | 
				
			||||||
    struct dds_security_timed_dispatcher_t *d1 = NULL;
 | 
					 | 
				
			||||||
    static bool test_var = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_time_t now     = dds_time();
 | 
					 | 
				
			||||||
    dds_time_t future  = now + DDS_SECS(2);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    d1 = dds_security_timed_dispatcher_new(tcb);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CU_ASSERT_PTR_NOT_NULL_FATAL(d1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_add(tcb, d1, simple_callback, future, (void*)&test_var);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_enable(tcb, d1, (void*)NULL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CU_ASSERT_FALSE_FATAL(test_var);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_sleepfor(DDS_MSECS(500));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CU_ASSERT_FALSE_FATAL(test_var);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_sleepfor(DDS_SECS(2));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CU_ASSERT_TRUE_FATAL(test_var);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_free(tcb, d1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_security_timed_cb_free(tcb);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
CU_Test(dds_security_timed_cb, simple_order)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    struct dds_security_timed_cb_data *tcb = dds_security_timed_cb_new();
 | 
					 | 
				
			||||||
    struct dds_security_timed_dispatcher_t *d1 = NULL;
 | 
					 | 
				
			||||||
    dds_time_t future;
 | 
					 | 
				
			||||||
    dds_time_t future2;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    d1 = dds_security_timed_dispatcher_new(tcb);
 | 
					 | 
				
			||||||
    CU_ASSERT_PTR_NOT_NULL_FATAL(d1);
 | 
					 | 
				
			||||||
    future  = dds_time() + DDS_MSECS(20);
 | 
					 | 
				
			||||||
    future2  = future;
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_add(tcb, d1, order_callback, future, (void*)1);
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_add(tcb, d1, order_callback, future2, (void*)2);
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_enable(tcb, d1, (void*)&g_order_callback);
 | 
					 | 
				
			||||||
    dds_sleepfor(DDS_MSECS(10));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_free(tcb, d1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CU_ASSERT_EQUAL_FATAL(g_order_callback[0], (void*)1);
 | 
					 | 
				
			||||||
    CU_ASSERT_EQUAL_FATAL(g_order_callback[1], (void*)2);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_security_timed_cb_free(tcb);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
CU_Test(dds_security_timed_cb, test_enabled_and_disabled)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    struct dds_security_timed_cb_data *tcb = dds_security_timed_cb_new();
 | 
					 | 
				
			||||||
    struct dds_security_timed_dispatcher_t *d1 = NULL;
 | 
					 | 
				
			||||||
    static bool test_var = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_time_t now     = dds_time();
 | 
					 | 
				
			||||||
    dds_time_t future  = now + DDS_SECS(2);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    d1 = dds_security_timed_dispatcher_new(tcb);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CU_ASSERT_PTR_NOT_NULL_FATAL(d1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_add(tcb, d1, simple_callback, future, (void*)&test_var);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_enable(tcb, d1, (void*)NULL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CU_ASSERT_FALSE(test_var);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_disable(tcb, d1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_sleepfor(DDS_MSECS(500));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CU_ASSERT_FALSE(test_var);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_sleepfor(DDS_SECS(2));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CU_ASSERT_FALSE(test_var);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_free(tcb, d1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_security_timed_cb_free(tcb);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
CU_Test(dds_security_timed_cb, simple_test_with_future)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    struct dds_security_timed_cb_data *tcb = dds_security_timed_cb_new();
 | 
					 | 
				
			||||||
    struct dds_security_timed_dispatcher_t *d1 = NULL;
 | 
					 | 
				
			||||||
    static bool test_var = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_time_t now     = dds_time();
 | 
					 | 
				
			||||||
    dds_time_t future  = now + DDS_SECS(2);
 | 
					 | 
				
			||||||
    dds_time_t far_future  = now + DDS_SECS(10);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    d1 = dds_security_timed_dispatcher_new(tcb);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CU_ASSERT_PTR_NOT_NULL_FATAL(d1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_enable(tcb, d1, (void*)NULL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_add(tcb, d1, simple_callback, future, (void*)&test_var);
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_add(tcb, d1, simple_callback, far_future, (void*)&test_var);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CU_ASSERT_FALSE_FATAL(test_var);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_sleepfor(DDS_MSECS(500));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CU_ASSERT_FALSE_FATAL(test_var);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_sleepfor(DDS_SECS(2));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CU_ASSERT_TRUE_FATAL(test_var);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_free(tcb, d1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_security_timed_cb_free(tcb);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
CU_Test(dds_security_timed_cb, test_multiple_dispatchers)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    struct dds_security_timed_cb_data *tcb = dds_security_timed_cb_new();
 | 
					 | 
				
			||||||
    struct dds_security_timed_dispatcher_t *d1 = NULL;
 | 
					 | 
				
			||||||
    struct dds_security_timed_dispatcher_t *d2 = NULL;
 | 
					 | 
				
			||||||
    static bool test_var = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_time_t now     = dds_time();
 | 
					 | 
				
			||||||
    dds_time_t future  = now + DDS_SECS(2);
 | 
					 | 
				
			||||||
    dds_time_t far_future  = now + DDS_SECS(10);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    d1 = dds_security_timed_dispatcher_new(tcb);
 | 
					 | 
				
			||||||
    d2 = dds_security_timed_dispatcher_new(tcb);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CU_ASSERT_PTR_NOT_NULL_FATAL(d1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_enable(tcb, d1, (void*)NULL);
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_enable(tcb, d2, (void*)NULL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_free(tcb, d2);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_add(tcb, d1, simple_callback, future, (void*)&test_var);
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_add(tcb, d1, simple_callback, far_future, (void*)&test_var);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CU_ASSERT_FALSE_FATAL(test_var);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_sleepfor(DDS_MSECS(500));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CU_ASSERT_FALSE_FATAL(test_var);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_sleepfor(DDS_SECS(2));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CU_ASSERT_TRUE_FATAL(test_var);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_free(tcb, d1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_security_timed_cb_free(tcb);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
CU_Test(dds_security_timed_cb, test_not_enabled_multiple_dispatchers)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    struct dds_security_timed_cb_data *tcb = dds_security_timed_cb_new();
 | 
					 | 
				
			||||||
    struct dds_security_timed_dispatcher_t *d1 = NULL;
 | 
					 | 
				
			||||||
    struct dds_security_timed_dispatcher_t *d2 = NULL;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    d1 = dds_security_timed_dispatcher_new(tcb);
 | 
					 | 
				
			||||||
    d2 = dds_security_timed_dispatcher_new(tcb);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CU_ASSERT_PTR_NOT_NULL_FATAL(d1);
 | 
					 | 
				
			||||||
    CU_ASSERT_PTR_NOT_NULL_FATAL(d2);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_free(tcb, d2);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_free(tcb, d1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_security_timed_cb_free(tcb);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CU_PASS("Timed callbacks enabled and disabled without add");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
CU_Test(dds_security_timed_cb, test_create_dispatcher)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    struct dds_security_timed_cb_data *tcb = dds_security_timed_cb_new();
 | 
					 | 
				
			||||||
    struct dds_security_timed_dispatcher_t *d1 = NULL;
 | 
					 | 
				
			||||||
    struct dds_security_timed_dispatcher_t *d2 = NULL;
 | 
					 | 
				
			||||||
    struct dds_security_timed_dispatcher_t *d3 = NULL;
 | 
					 | 
				
			||||||
    struct dds_security_timed_dispatcher_t *d4 = NULL;
 | 
					 | 
				
			||||||
    struct dds_security_timed_dispatcher_t *d5 = NULL;
 | 
					 | 
				
			||||||
    bool ok = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_time_t now     = dds_time();
 | 
					 | 
				
			||||||
    dds_time_t past    = now - DDS_SECS(1);
 | 
					 | 
				
			||||||
    dds_time_t present = now + DDS_SECS(1);
 | 
					 | 
				
			||||||
    dds_time_t future  = present + DDS_SECS(1);
 | 
					 | 
				
			||||||
    dds_time_t future2 = future + DDS_SECS(10);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /*************************************************************************
 | 
					 | 
				
			||||||
     * Check if dispatchers can be created
 | 
					 | 
				
			||||||
     *************************************************************************/
 | 
					 | 
				
			||||||
    d1 = dds_security_timed_dispatcher_new(tcb);
 | 
					 | 
				
			||||||
    d2 = dds_security_timed_dispatcher_new(tcb);
 | 
					 | 
				
			||||||
    CU_ASSERT_PTR_NOT_NULL_FATAL(d1);
 | 
					 | 
				
			||||||
    CU_ASSERT_PTR_NOT_NULL_FATAL(d2);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /*************************************************************************
 | 
					 | 
				
			||||||
     * Check if adding callbacks succeeds
 | 
					 | 
				
			||||||
     *************************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* The last argument is a sequence number in which
 | 
					 | 
				
			||||||
     * the callbacks are expected to be called. */
 | 
					 | 
				
			||||||
    /* We can only really check if it crashes or not... */
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_add(tcb, d1, tc__callback, present, (void*)1);
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_add(tcb, d2, tc__callback, past,    (void*)0);
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_add(tcb, d2, tc__callback, present, (void*)2);
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_add(tcb, d1, tc__callback, future,  (void*)7);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CU_PASS("Added callbacks")
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /*************************************************************************
 | 
					 | 
				
			||||||
     * Check if dispatchers can be created
 | 
					 | 
				
			||||||
     *************************************************************************/
 | 
					 | 
				
			||||||
    d3 = dds_security_timed_dispatcher_new(tcb);
 | 
					 | 
				
			||||||
    d4 = dds_security_timed_dispatcher_new(tcb);
 | 
					 | 
				
			||||||
    d5 = dds_security_timed_dispatcher_new(tcb);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    CU_ASSERT_PTR_NOT_NULL_FATAL(d3);
 | 
					 | 
				
			||||||
    CU_ASSERT_PTR_NOT_NULL_FATAL(d4);
 | 
					 | 
				
			||||||
    CU_ASSERT_PTR_NOT_NULL_FATAL(d5);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /*************************************************************************
 | 
					 | 
				
			||||||
     * Check if enabling dispatchers succeeds
 | 
					 | 
				
			||||||
     *************************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* The sleeps are added to get the timing between
 | 
					 | 
				
			||||||
        * 'present' and 'past' callbacks right. */
 | 
					 | 
				
			||||||
    /* We can only really check if it crashes or not... */
 | 
					 | 
				
			||||||
    dds_sleepfor(DDS_MSECS(600));
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_enable(tcb, d1, (void*)NULL);
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_enable(tcb, d2, (void*)  d2);
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_enable(tcb, d3, (void*)NULL);
 | 
					 | 
				
			||||||
    /* Specifically not enabling d4 and d5. */
 | 
					 | 
				
			||||||
    dds_sleepfor(DDS_MSECS(600));
 | 
					 | 
				
			||||||
    CU_PASS("Enabled dds_security_timed_dispatchers.");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /*************************************************************************
 | 
					 | 
				
			||||||
     * Check if adding callbacks succeeds
 | 
					 | 
				
			||||||
     *************************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* The last argument is a sequence number in which
 | 
					 | 
				
			||||||
        * the callbacks are expected to be called. */
 | 
					 | 
				
			||||||
    /* We can only really check if it crashes or not... */
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_add(tcb, d4, tc__callback, past,    (void*)99);
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_add(tcb, d2, tc__callback, future,  (void*) 8);
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_add(tcb, d3, tc__callback, future2, (void*) 9);
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_add(tcb, d1, tc__callback, past,    (void*) 3);
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_add(tcb, d1, tc__callback, future2, (void*)10);
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_add(tcb, d1, tc__callback, present, (void*) 4);
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_add(tcb, d2, tc__callback, present, (void*) 5);
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_add(tcb, d1, tc__callback, future,  (void*) 6);
 | 
					 | 
				
			||||||
    dds_security_timed_dispatcher_add(tcb, d3, tc__callback, future2, (void*)11);
 | 
					 | 
				
			||||||
    CU_PASS("Added callbacks.");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /*************************************************************************
 | 
					 | 
				
			||||||
     * Check if timeout callbacks are triggered in the right sequence
 | 
					 | 
				
			||||||
     *************************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    int idx;
 | 
					 | 
				
			||||||
    int timeout = 200; /* 2 seconds */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* Wait for the callbacks to have been triggered.
 | 
					 | 
				
			||||||
        * Ignore the ones in the far future. */
 | 
					 | 
				
			||||||
    while ((g_sequence_idx < 8) && (timeout > 0)) {
 | 
					 | 
				
			||||||
        dds_sleepfor(DDS_MSECS(10));
 | 
					 | 
				
			||||||
        timeout--;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* Print and check sequence of triggered callbacks. */
 | 
					 | 
				
			||||||
    for (idx = 0; (idx < g_sequence_idx) && (idx < SEQ_SIZE); idx++) {
 | 
					 | 
				
			||||||
        int seq = (int)(long long)(g_sequence_array[idx].arg);
 | 
					 | 
				
			||||||
        struct dds_security_timed_dispatcher_t *expected_d;
 | 
					 | 
				
			||||||
        void *expected_l;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /*
 | 
					 | 
				
			||||||
            * Sequence checks.
 | 
					 | 
				
			||||||
            */
 | 
					 | 
				
			||||||
        if ((seq == 1) || (seq == 6) || (seq == 3) || (seq == 10) || (seq == 4) || (seq == 7)) {
 | 
					 | 
				
			||||||
            expected_d = d1;
 | 
					 | 
				
			||||||
            expected_l = NULL;
 | 
					 | 
				
			||||||
        } else if ((seq == 0) || (seq == 2) || (seq == 8) || (seq == 5)) {
 | 
					 | 
				
			||||||
            expected_d = d2;
 | 
					 | 
				
			||||||
            expected_l = d2;
 | 
					 | 
				
			||||||
        } else if (seq == 9) {
 | 
					 | 
				
			||||||
            expected_d = d3;
 | 
					 | 
				
			||||||
            expected_l = NULL;
 | 
					 | 
				
			||||||
        } else if (seq == 99) {
 | 
					 | 
				
			||||||
            expected_d = d4;
 | 
					 | 
				
			||||||
            expected_l = NULL;
 | 
					 | 
				
			||||||
            CU_FAIL("Unexpected callback on a disabled dispatcher");
 | 
					 | 
				
			||||||
            ok = false;
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            expected_d = NULL;
 | 
					 | 
				
			||||||
            expected_l = NULL;
 | 
					 | 
				
			||||||
            CU_FAIL(sprintf("Unknown sequence idx received %d", seq));
 | 
					 | 
				
			||||||
            ok = false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (seq != idx) {
 | 
					 | 
				
			||||||
            /* 6 and 7 order may be mixed since the order is not defined for same time stamp */
 | 
					 | 
				
			||||||
            if (!((seq == 6 && idx == 7) || (seq == 7 && idx == 6)))
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                printf("Unexpected sequence ordering %d vs %d\n", seq, idx);
 | 
					 | 
				
			||||||
                CU_FAIL("Unexpected sequence ordering");
 | 
					 | 
				
			||||||
                ok = false;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (seq > 8) {
 | 
					 | 
				
			||||||
            CU_FAIL(sprintf("Unexpected sequence idx %d of the far future", seq));
 | 
					 | 
				
			||||||
            ok = false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (idx > 8) {
 | 
					 | 
				
			||||||
            CU_FAIL(sprintf("Too many callbacks %d", idx));
 | 
					 | 
				
			||||||
            ok = false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /*
 | 
					 | 
				
			||||||
         * Callback contents checks.
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
        if (expected_d != NULL) {
 | 
					 | 
				
			||||||
            if (g_sequence_array[idx].d != expected_d) {
 | 
					 | 
				
			||||||
                printf("Unexpected dispatcher %p vs %p\n", g_sequence_array[idx].d, expected_d);
 | 
					 | 
				
			||||||
                CU_FAIL("Unexpected dispatcher");
 | 
					 | 
				
			||||||
                ok = false;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if (g_sequence_array[idx].listener != expected_l) {
 | 
					 | 
				
			||||||
                CU_FAIL(sprintf("Unexpected listener %p vs %p", g_sequence_array[idx].listener, expected_l));
 | 
					 | 
				
			||||||
                ok = false;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /*
 | 
					 | 
				
			||||||
         * Callback kind check.
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
        if (g_sequence_array[idx].kind != DDS_SECURITY_TIMED_CB_KIND_TIMEOUT) {
 | 
					 | 
				
			||||||
            CU_FAIL(sprintf("Unexpected kind %d vs %d", (int)g_sequence_array[idx].kind, (int)DDS_SECURITY_TIMED_CB_KIND_TIMEOUT));
 | 
					 | 
				
			||||||
            ok = false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (g_sequence_idx < 8) {
 | 
					 | 
				
			||||||
        CU_FAIL(sprintf("Received %d callbacks, while 9 are expected",
 | 
					 | 
				
			||||||
                                g_sequence_idx + 1));
 | 
					 | 
				
			||||||
        ok = false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (ok) {
 | 
					 | 
				
			||||||
        CU_FAIL(sprintf("Received timeout callbacks."));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /* Reset callback index to catch the deletion ones. */
 | 
					 | 
				
			||||||
    g_sequence_idx = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /*************************************************************************
 | 
					 | 
				
			||||||
     * Check if deleting succeeds with dispatchers in different states
 | 
					 | 
				
			||||||
     *************************************************************************/
 | 
					 | 
				
			||||||
    /* We can only really check if it crashes or not... */
 | 
					 | 
				
			||||||
    if (d1) {
 | 
					 | 
				
			||||||
        dds_security_timed_dispatcher_free(tcb, d1);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (d2) {
 | 
					 | 
				
			||||||
        dds_security_timed_dispatcher_free(tcb, d2);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (d3) {
 | 
					 | 
				
			||||||
        dds_security_timed_dispatcher_free(tcb, d3);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (d4) {
 | 
					 | 
				
			||||||
        dds_security_timed_dispatcher_free(tcb, d4);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (d5) {
 | 
					 | 
				
			||||||
        dds_security_timed_dispatcher_free(tcb, d5);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    CU_PASS("Deleted dispatchers.");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /*************************************************************************
 | 
					 | 
				
			||||||
     * Check if deletion callbacks are triggered
 | 
					 | 
				
			||||||
     *************************************************************************/
 | 
					 | 
				
			||||||
    if (ok) {
 | 
					 | 
				
			||||||
        timeout = 200; /* 2 seconds */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /* Wait for the callbacks to have been triggered.
 | 
					 | 
				
			||||||
         * Ignore the ones in the far future. */
 | 
					 | 
				
			||||||
        while ((g_sequence_idx < 4) && (timeout > 0)) {
 | 
					 | 
				
			||||||
            dds_sleepfor(DDS_MSECS(10));
 | 
					 | 
				
			||||||
            timeout--;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /* Print and check sequence of triggered callbacks. */
 | 
					 | 
				
			||||||
        for (idx = 0; (idx < g_sequence_idx) && (idx < SEQ_SIZE); idx++) {
 | 
					 | 
				
			||||||
            int seq = (int)(long long)(g_sequence_array[idx].arg);
 | 
					 | 
				
			||||||
            struct dds_security_timed_dispatcher_t *expected_d;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            /*
 | 
					 | 
				
			||||||
             * Human (somewhat) readable format.
 | 
					 | 
				
			||||||
             */
 | 
					 | 
				
			||||||
            // tc__sequence_data_print(&(g_sequence_array[idx]));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            /*
 | 
					 | 
				
			||||||
             * Sequence checks.
 | 
					 | 
				
			||||||
             */
 | 
					 | 
				
			||||||
            if (seq == 99) {
 | 
					 | 
				
			||||||
                expected_d = d4;
 | 
					 | 
				
			||||||
            } else if ((seq == 9) || (seq == 11)) {
 | 
					 | 
				
			||||||
                expected_d = d3;
 | 
					 | 
				
			||||||
            } else if (seq == 10) {
 | 
					 | 
				
			||||||
                expected_d = d1;
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                expected_d = NULL;
 | 
					 | 
				
			||||||
                CU_FAIL(sprintf("Unexpected sequence idx received %d", seq));
 | 
					 | 
				
			||||||
                ok = false;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if (idx > 4) {
 | 
					 | 
				
			||||||
                CU_FAIL(sprintf("Too many callbacks %d", idx));
 | 
					 | 
				
			||||||
                ok = false;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            /*
 | 
					 | 
				
			||||||
             * Callback contents checks.
 | 
					 | 
				
			||||||
             */
 | 
					 | 
				
			||||||
            if (expected_d != NULL) {
 | 
					 | 
				
			||||||
                if (g_sequence_array[idx].d != expected_d) {
 | 
					 | 
				
			||||||
                    CU_FAIL(sprintf("Unexpected dispatcher %p vs %p", g_sequence_array[idx].d, expected_d));
 | 
					 | 
				
			||||||
                    ok = false;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                if (g_sequence_array[idx].listener != NULL) {
 | 
					 | 
				
			||||||
                    CU_FAIL(sprintf("Unexpected listener %p vs NULL", g_sequence_array[idx].listener));
 | 
					 | 
				
			||||||
                    ok = false;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            /*
 | 
					 | 
				
			||||||
             * Callback kind check.
 | 
					 | 
				
			||||||
             */
 | 
					 | 
				
			||||||
            if (g_sequence_array[idx].kind != DDS_SECURITY_TIMED_CB_KIND_DELETE) {
 | 
					 | 
				
			||||||
                CU_FAIL(sprintf("Unexpected kind %d vs %d", (int)g_sequence_array[idx].kind, (int)DDS_SECURITY_TIMED_CB_KIND_TIMEOUT));
 | 
					 | 
				
			||||||
                ok = false;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (g_sequence_idx < 4) {
 | 
					 | 
				
			||||||
            CU_FAIL(sprintf("Received %d callbacks, while 3 are expected",
 | 
					 | 
				
			||||||
                                    g_sequence_idx + 1));
 | 
					 | 
				
			||||||
            ok = false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (ok) {
 | 
					 | 
				
			||||||
            CU_PASS("Received deletion callbacks.");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    dds_security_timed_cb_free(tcb);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										581
									
								
								src/security/core/tests/fsm.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										581
									
								
								src/security/core/tests/fsm.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,581 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program and the accompanying materials are made available under the
 | 
				
			||||||
 | 
					 * terms of the Eclipse Public License v. 2.0 which is available at
 | 
				
			||||||
 | 
					 * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
 | 
				
			||||||
 | 
					 * v. 1.0 which is available at
 | 
				
			||||||
 | 
					 * http://www.eclipse.org/org/documents/edl-v10.php.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdbool.h>
 | 
				
			||||||
 | 
					#include "CUnit/CUnit.h"
 | 
				
			||||||
 | 
					#include "CUnit/Test.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dds/ddsrt/sync.h"
 | 
				
			||||||
 | 
					#include "dds/ddsrt/misc.h"
 | 
				
			||||||
 | 
					#include "dds/dds.h"
 | 
				
			||||||
 | 
					#include "dds__types.h"
 | 
				
			||||||
 | 
					#include "dds__entity.h"
 | 
				
			||||||
 | 
					#include "dds/security/core/dds_security_fsm.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define CHECK_BIT(var, pos) ((var) & (1<<(pos)))
 | 
				
			||||||
 | 
					#define FSM_AUTH_ARG 10
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static dds_entity_t g_participant = 0;
 | 
				
			||||||
 | 
					static ddsrt_mutex_t g_lock;
 | 
				
			||||||
 | 
					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) { \
 | 
				
			||||||
 | 
					  DDSRT_UNUSED_ARG(fsm); \
 | 
				
			||||||
 | 
					  DDSRT_UNUSED_ARG(arg); \
 | 
				
			||||||
 | 
					  printf("Transition %s\n", __FUNCTION__); \
 | 
				
			||||||
 | 
					  ddsrt_mutex_lock(&g_lock); \
 | 
				
			||||||
 | 
					  visited_##var |= 1u << (bit); \
 | 
				
			||||||
 | 
					  ddsrt_mutex_unlock(&g_lock); \
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					  VALIDATION_PENDING_RETRY,
 | 
				
			||||||
 | 
					  VALIDATION_FAILED,
 | 
				
			||||||
 | 
					  VALIDATION_OK,
 | 
				
			||||||
 | 
					  VALIDATION_OK_FINAL_MESSAGE,
 | 
				
			||||||
 | 
					  VALIDATION_PENDING_HANDSHAKE_MESSAGE,
 | 
				
			||||||
 | 
					  VALIDATION_PENDING_HANDSHAKE_REQUEST,
 | 
				
			||||||
 | 
					  plugin_ret_MAX
 | 
				
			||||||
 | 
					} plugin_ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  printf("validate_remote_identity - %d\n", validate_remote_identity_first);
 | 
				
			||||||
 | 
					  if (validate_remote_identity_first)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    validate_remote_identity_first = 0;
 | 
				
			||||||
 | 
					    return VALIDATION_PENDING_RETRY;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return VALIDATION_PENDING_HANDSHAKE_MESSAGE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static plugin_ret begin_handshake_reply(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  printf("begin_handshake_reply - %d\n", begin_handshake_reply_first);
 | 
				
			||||||
 | 
					  if (begin_handshake_reply_first)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    begin_handshake_reply_first = 0;
 | 
				
			||||||
 | 
					    return VALIDATION_PENDING_RETRY;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return VALIDATION_OK_FINAL_MESSAGE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  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);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void fsm_begin_handshake_reply(struct dds_security_fsm *fsm, void *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  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);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* 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)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  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_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()                            v
 | 
				
			||||||
 | 
					 *                 .----------------------------------------------------.
 | 
				
			||||||
 | 
					 *                 |            StateValidateRemoteIdentity             |
 | 
				
			||||||
 | 
					 *                 |----------------------------------------------------|
 | 
				
			||||||
 | 
					 *         .------>| fsm_validate_remote_identity()                     |
 | 
				
			||||||
 | 
					 *         |       |    - dispatch VALIDATION_PENDING_RETRY             |
 | 
				
			||||||
 | 
					 *    100ms|       |    - dispatch VALIDATION_PENDING_HANDSHAKE_MESSAGE |
 | 
				
			||||||
 | 
					 *    d()  |       '----------------------------------------------------'
 | 
				
			||||||
 | 
					 *         |          VALIDATION_PENDING_RETRY|  | VALIDATION_PENDING_HANDSHAKE_MESSAGE
 | 
				
			||||||
 | 
					 *         |          b()                     |  | c()
 | 
				
			||||||
 | 
					 *         |                                  |  |
 | 
				
			||||||
 | 
					 * .------------------------------.           |  |       .-------------------------------.
 | 
				
			||||||
 | 
					 * | StateValRemIdentityRetryWait |           |  |       | StateHandshakeInitMessageWait |
 | 
				
			||||||
 | 
					 * |------------------------------|<----------'  '------>|-------------------------------|
 | 
				
			||||||
 | 
					 * '------------------------------'                      '-------------------------------'
 | 
				
			||||||
 | 
					 *                                                SHM_MSG_RECEIVED  |
 | 
				
			||||||
 | 
					 *                                                e()               |
 | 
				
			||||||
 | 
					 *                                                                  v
 | 
				
			||||||
 | 
					 *                                      .----------------------------------------.
 | 
				
			||||||
 | 
					 *          VALIDATION_PENDING_RETRY    |        state_beginHandshakeReply        |
 | 
				
			||||||
 | 
					 *          f()                         |----------------------------------------|
 | 
				
			||||||
 | 
					 *            .-------------------------| fsm_begin_handshake_reply()            |
 | 
				
			||||||
 | 
					 *            |                         |    - dispatch VALIDATION_PENDING_RETRY |
 | 
				
			||||||
 | 
					 *            v                         |    - dispatch VALIDATION_OK            |
 | 
				
			||||||
 | 
					 * .-----------------------.    100ms   '----------------------------------------'
 | 
				
			||||||
 | 
					 * | state_beginHsReplyWait |    h()                ^        VALIDATION_OK |
 | 
				
			||||||
 | 
					 * |-----------------------|-----------------------'        g()           |
 | 
				
			||||||
 | 
					 * '-----------------------'                                              v
 | 
				
			||||||
 | 
					 *                                                                       .-.
 | 
				
			||||||
 | 
					 *                                                                       '-'
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					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 uint32_t HandshakeTransistionsSize = sizeof(HandshakeTransistions)/sizeof(HandshakeTransistions[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Example State Machine properties and methods */
 | 
				
			||||||
 | 
					typedef enum {
 | 
				
			||||||
 | 
					    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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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_mutex_lock (&g_lock);
 | 
				
			||||||
 | 
					  visited_test |= 1u << 2;
 | 
				
			||||||
 | 
					  ddsrt_mutex_unlock (&g_lock);
 | 
				
			||||||
 | 
					  if (do_stuff_counter < 2)
 | 
				
			||||||
 | 
					    dds_security_fsm_dispatch(fsm, eventZ, false);
 | 
				
			||||||
 | 
					  else if (do_stuff_counter == 2)
 | 
				
			||||||
 | 
					    dds_security_fsm_dispatch(fsm, eventY, false);
 | 
				
			||||||
 | 
					  ++do_stuff_counter;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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_mutex_lock (&g_lock);
 | 
				
			||||||
 | 
					  visited_test |= 1u << 3;
 | 
				
			||||||
 | 
					  ddsrt_mutex_unlock (&g_lock);
 | 
				
			||||||
 | 
					  if (do_other_stuff_counter == 0)
 | 
				
			||||||
 | 
					    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);
 | 
				
			||||||
 | 
					  else if (do_other_stuff_counter == 2)
 | 
				
			||||||
 | 
					    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 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,
 | 
				
			||||||
 | 
					} 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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void do_timeout(struct dds_security_fsm *fsm, void *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  DDSRT_UNUSED_ARG(arg);
 | 
				
			||||||
 | 
					  printf("Transition >>>> %s\n", __FUNCTION__);
 | 
				
			||||||
 | 
					  ddsrt_mutex_lock (&g_lock);
 | 
				
			||||||
 | 
					  visited_timeout |= 1u << 1;
 | 
				
			||||||
 | 
					  ddsrt_mutex_unlock (&g_lock);
 | 
				
			||||||
 | 
					  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)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  struct fsm_timeout_arg *farg = arg;
 | 
				
			||||||
 | 
					  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;
 | 
				
			||||||
 | 
					  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_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
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					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;
 | 
				
			||||||
 | 
					static struct dds_security_fsm *fsm_timeout2;
 | 
				
			||||||
 | 
					static struct dds_security_fsm *fsm_timeout3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static dds_time_t time0 = 0;
 | 
				
			||||||
 | 
					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)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  DDSRT_UNUSED_ARG(fsm);
 | 
				
			||||||
 | 
					  DDSRT_UNUSED_ARG(arg);
 | 
				
			||||||
 | 
					  time1 = dds_time();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void state_par_time2(struct dds_security_fsm *fsm, void *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  DDSRT_UNUSED_ARG(fsm);
 | 
				
			||||||
 | 
					  DDSRT_UNUSED_ARG(arg);
 | 
				
			||||||
 | 
					  time2 = dds_time();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void state_par_time3(struct dds_security_fsm *fsm, void *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  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 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 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 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);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* 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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ddsrt_mutex_lock (&g_lock);
 | 
				
			||||||
 | 
					  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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Check whether timeout callback has NOT been invoked */
 | 
				
			||||||
 | 
					  ddsrt_mutex_lock (&g_lock);
 | 
				
			||||||
 | 
					  CU_ASSERT(visited_timeout == 0);
 | 
				
			||||||
 | 
					  ddsrt_mutex_unlock (&g_lock);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Test multiple (2) running state machines */
 | 
				
			||||||
 | 
					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_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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* 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);
 | 
				
			||||||
 | 
					  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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  ddsrt_mutex_lock (&g_lock);
 | 
				
			||||||
 | 
					  CU_ASSERT(visited_test == 0x1f);
 | 
				
			||||||
 | 
					  ddsrt_mutex_unlock (&g_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  dds_security_fsm_free(fsm_auth);
 | 
				
			||||||
 | 
					  dds_security_fsm_free(fsm_test);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Check creation of State Machine for timeout purposes
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					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 */
 | 
				
			||||||
 | 
					  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);
 | 
				
			||||||
 | 
					  ddsrt_mutex_unlock (&g_lock);
 | 
				
			||||||
 | 
					  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_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_start(fsm_timeout);
 | 
				
			||||||
 | 
					  dds_security_fsm_start(fsm_timeout2);
 | 
				
			||||||
 | 
					  int n = 100;
 | 
				
			||||||
 | 
					  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);
 | 
				
			||||||
 | 
					  ddsrt_mutex_unlock (&g_lock);
 | 
				
			||||||
 | 
					  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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  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));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  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));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  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;
 | 
				
			||||||
 | 
					  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);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  ddsrt_mutex_unlock (&g_lock);
 | 
				
			||||||
 | 
					  dds_security_fsm_free(fsm_timeout);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,9 +35,12 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char *config =
 | 
					static const char *config =
 | 
				
			||||||
    "${CYCLONEDDS_URI}${CYCLONEDDS_URI:+,}"
 | 
					    "${CYCLONEDDS_URI}${CYCLONEDDS_URI:+,}"
 | 
				
			||||||
    "<Discovery><ExternalDomainId>0</ExternalDomainId></Discovery>"
 | 
					 | 
				
			||||||
    "<Domain id=\"any\">"
 | 
					    "<Domain id=\"any\">"
 | 
				
			||||||
    "  <Tracing><Verbosity>finest</></>"
 | 
					    "  <Discovery>"
 | 
				
			||||||
 | 
					    "    <ExternalDomainId>0</ExternalDomainId>"
 | 
				
			||||||
 | 
					    "    <Tag>\\${CYCLONEDDS_PID}</Tag>"
 | 
				
			||||||
 | 
					    "  </Discovery>"
 | 
				
			||||||
 | 
					    "  <Tracing><Verbosity>config</></>"
 | 
				
			||||||
    "  <DDSSecurity>"
 | 
					    "  <DDSSecurity>"
 | 
				
			||||||
    "    <Authentication>"
 | 
					    "    <Authentication>"
 | 
				
			||||||
    "      <Library finalizeFunction=\"finalize_test_authentication_wrapped\" initFunction=\"init_test_authentication_wrapped\" path=\"" WRAPPERLIB_PATH("dds_security_authentication_wrapper") "\"/>"
 | 
					    "      <Library finalizeFunction=\"finalize_test_authentication_wrapped\" initFunction=\"init_test_authentication_wrapped\" path=\"" WRAPPERLIB_PATH("dds_security_authentication_wrapper") "\"/>"
 | 
				
			||||||
| 
						 | 
					@ -68,30 +71,27 @@ static dds_entity_t g_part2_participant = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handshake_init(void)
 | 
					static void handshake_init(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  /* Domains for pub and sub use a different domain id, but the portgain setting
 | 
					  char *conf_part1 = ddsrt_expand_envvars_sh (config, DDS_DOMAINID_PART1);
 | 
				
			||||||
   * in configuration is 0, so that both domains will map to the same port number.
 | 
					  char *conf_part2 = ddsrt_expand_envvars_sh (config, DDS_DOMAINID_PART2);
 | 
				
			||||||
   * This allows to create two domains in a single test process. */
 | 
					  g_part1_domain = dds_create_domain (DDS_DOMAINID_PART1, conf_part1);
 | 
				
			||||||
  char *conf_part1 = ddsrt_expand_envvars(config, DDS_DOMAINID_PART1);
 | 
					  g_part2_domain = dds_create_domain (DDS_DOMAINID_PART2, conf_part2);
 | 
				
			||||||
  char *conf_part2 = ddsrt_expand_envvars(config, DDS_DOMAINID_PART2);
 | 
					  dds_free (conf_part1);
 | 
				
			||||||
  g_part1_domain = dds_create_domain(DDS_DOMAINID_PART1, conf_part1);
 | 
					  dds_free (conf_part2);
 | 
				
			||||||
  g_part2_domain = dds_create_domain(DDS_DOMAINID_PART2, conf_part2);
 | 
					 | 
				
			||||||
  dds_free(conf_part1);
 | 
					 | 
				
			||||||
  dds_free(conf_part2);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  CU_ASSERT_FATAL((g_part1_participant = dds_create_participant(DDS_DOMAINID_PART1, NULL, NULL)) > 0);
 | 
					  CU_ASSERT_FATAL ((g_part1_participant = dds_create_participant (DDS_DOMAINID_PART1, NULL, NULL)) > 0);
 | 
				
			||||||
  CU_ASSERT_FATAL((g_part2_participant = dds_create_participant(DDS_DOMAINID_PART2, NULL, NULL)) > 0);
 | 
					  CU_ASSERT_FATAL ((g_part2_participant = dds_create_participant (DDS_DOMAINID_PART2, NULL, NULL)) > 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void handshake_fini(void)
 | 
					static void handshake_fini(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  CU_ASSERT_EQUAL_FATAL(dds_delete(g_part1_participant), DDS_RETCODE_OK);
 | 
					  CU_ASSERT_EQUAL_FATAL (dds_delete (g_part1_participant), DDS_RETCODE_OK);
 | 
				
			||||||
  CU_ASSERT_EQUAL_FATAL(dds_delete(g_part2_participant), DDS_RETCODE_OK);
 | 
					  CU_ASSERT_EQUAL_FATAL (dds_delete (g_part2_participant), DDS_RETCODE_OK);
 | 
				
			||||||
  CU_ASSERT_EQUAL_FATAL(dds_delete(g_part1_domain), DDS_RETCODE_OK);
 | 
					  CU_ASSERT_EQUAL_FATAL (dds_delete (g_part1_domain), DDS_RETCODE_OK);
 | 
				
			||||||
  CU_ASSERT_EQUAL_FATAL(dds_delete(g_part2_domain), DDS_RETCODE_OK);
 | 
					  CU_ASSERT_EQUAL_FATAL (dds_delete (g_part2_domain), DDS_RETCODE_OK);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CU_Test(ddssec_handshake, happy_day, .init = handshake_init, .fini = handshake_fini)
 | 
					CU_Test(ddssec_handshake, happy_day, .init = handshake_init, .fini = handshake_fini)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  validate_handshake(DDS_DOMAINID_PART1, false, NULL, false, NULL);
 | 
					  validate_handshake (DDS_DOMAINID_PART1, false, NULL, false, NULL);
 | 
				
			||||||
  validate_handshake(DDS_DOMAINID_PART2, false, NULL, false, NULL);
 | 
					  validate_handshake (DDS_DOMAINID_PART2, false, NULL, false, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,8 +51,11 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const char *config =
 | 
					static const char *config =
 | 
				
			||||||
    "${CYCLONEDDS_URI}${CYCLONEDDS_URI:+,}"
 | 
					    "${CYCLONEDDS_URI}${CYCLONEDDS_URI:+,}"
 | 
				
			||||||
    "<Discovery><ExternalDomainId>0</ExternalDomainId></Discovery>"
 | 
					 | 
				
			||||||
    "<Domain id=\"any\">"
 | 
					    "<Domain id=\"any\">"
 | 
				
			||||||
 | 
					    "  <Discovery>"
 | 
				
			||||||
 | 
					    "    <ExternalDomainId>0</ExternalDomainId>"
 | 
				
			||||||
 | 
					    "    <Tag>\\${CYCLONEDDS_PID}</Tag>"
 | 
				
			||||||
 | 
					    "  </Discovery>"
 | 
				
			||||||
    "  <DDSSecurity>"
 | 
					    "  <DDSSecurity>"
 | 
				
			||||||
    "    <Authentication>"
 | 
					    "    <Authentication>"
 | 
				
			||||||
    "      <Library finalizeFunction=\"finalize_authentication\" initFunction=\"init_authentication\" />"
 | 
					    "      <Library finalizeFunction=\"finalize_authentication\" initFunction=\"init_authentication\" />"
 | 
				
			||||||
| 
						 | 
					@ -219,12 +222,12 @@ static void test_init(const struct domain_sec_config * domain_config, size_t n_s
 | 
				
			||||||
    { NULL, NULL, 0 }
 | 
					    { NULL, NULL, 0 }
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  char *conf_pub = ddsrt_expand_vars (config, &expand_lookup_vars_env, config_vars);
 | 
					  char *conf_pub = ddsrt_expand_vars_sh (config, &expand_lookup_vars_env, config_vars);
 | 
				
			||||||
  create_dom_pp_pubsub (DDS_DOMAINID_PUB, conf_pub, domain_config, n_pub_domains, n_pub_participants,
 | 
					  create_dom_pp_pubsub (DDS_DOMAINID_PUB, conf_pub, domain_config, n_pub_domains, n_pub_participants,
 | 
				
			||||||
      g_pub_domains, g_pub_participants, g_pub_publishers, &dds_create_publisher);
 | 
					      g_pub_domains, g_pub_participants, g_pub_publishers, &dds_create_publisher);
 | 
				
			||||||
  dds_free (conf_pub);
 | 
					  dds_free (conf_pub);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  char *conf_sub = ddsrt_expand_vars (config, &expand_lookup_vars_env, config_vars);
 | 
					  char *conf_sub = ddsrt_expand_vars_sh (config, &expand_lookup_vars_env, config_vars);
 | 
				
			||||||
  create_dom_pp_pubsub (DDS_DOMAINID_SUB, conf_sub, domain_config, n_sub_domains, n_sub_participants,
 | 
					  create_dom_pp_pubsub (DDS_DOMAINID_SUB, conf_sub, domain_config, n_sub_domains, n_sub_participants,
 | 
				
			||||||
      g_sub_domains, g_sub_participants, g_sub_subscribers, &dds_create_subscriber);
 | 
					      g_sub_domains, g_sub_participants, g_sub_subscribers, &dds_create_subscriber);
 | 
				
			||||||
  dds_free (conf_sub);
 | 
					  dds_free (conf_sub);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,757 +0,0 @@
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * This program and the accompanying materials are made available under the
 | 
					 | 
				
			||||||
 * terms of the Eclipse Public License v. 2.0 which is available at
 | 
					 | 
				
			||||||
 * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
 | 
					 | 
				
			||||||
 * v. 1.0 which is available at
 | 
					 | 
				
			||||||
 * http://www.eclipse.org/org/documents/edl-v10.php.
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
#include <stdbool.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "dds/ddsrt/sync.h"
 | 
					 | 
				
			||||||
#include "dds/ddsrt/misc.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "CUnit/CUnit.h"
 | 
					 | 
				
			||||||
#include "CUnit/Test.h"
 | 
					 | 
				
			||||||
#include "dds/dds.h"
 | 
					 | 
				
			||||||
#include "dds__types.h"
 | 
					 | 
				
			||||||
#include "dds__entity.h"
 | 
					 | 
				
			||||||
#include "dds/security/core/dds_security_fsm.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define CHECK_BIT(var, pos) ((var) & (1<<(pos)))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define FSM_AUTH_ARG 10
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define DB_TC_PRINT_DEBUG  (true)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static dds_entity_t g_participant = 0;
 | 
					 | 
				
			||||||
static ddsrt_mutex_t g_lock;
 | 
					 | 
				
			||||||
static struct dds_security_fsm_control *g_fsm_control = NULL;
 | 
					 | 
				
			||||||
static const dds_duration_t msec100 = DDS_MSECS(100);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
//static int fsm_arg = FSM_AUTH_ARG;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define DO_SIMPLE(name, var, bit) static void name(struct dds_security_fsm *fsm, void *arg) { \
 | 
					 | 
				
			||||||
  DDSRT_UNUSED_ARG(fsm); \
 | 
					 | 
				
			||||||
  DDSRT_UNUSED_ARG(arg); \
 | 
					 | 
				
			||||||
  if (DB_TC_PRINT_DEBUG) \
 | 
					 | 
				
			||||||
    printf("Transition %s\n", __FUNCTION__); \
 | 
					 | 
				
			||||||
  ddsrt_mutex_lock(&g_lock); \
 | 
					 | 
				
			||||||
  visited_##var |= 1u << (bit); \
 | 
					 | 
				
			||||||
  ddsrt_mutex_unlock(&g_lock); \
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**********************************************************************
 | 
					 | 
				
			||||||
 * Authentication State Machine properties and methods
 | 
					 | 
				
			||||||
 **********************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef enum {
 | 
					 | 
				
			||||||
    VALIDATION_PENDING_RETRY,
 | 
					 | 
				
			||||||
    VALIDATION_FAILED,
 | 
					 | 
				
			||||||
    VALIDATION_OK,
 | 
					 | 
				
			||||||
    VALIDATION_OK_FINAL_MESSAGE,
 | 
					 | 
				
			||||||
    VALIDATION_PENDING_HANDSHAKE_MESSAGE,
 | 
					 | 
				
			||||||
    VALIDATION_PENDING_HANDSHAKE_REQUEST,
 | 
					 | 
				
			||||||
    PluginReturn_MAX
 | 
					 | 
				
			||||||
} PluginReturn;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
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 PluginReturn validate_remote_identity(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  if (DB_TC_PRINT_DEBUG) {
 | 
					 | 
				
			||||||
    printf("validate_remote_identity - %d\n", validate_remote_identity_first);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  if (validate_remote_identity_first) {
 | 
					 | 
				
			||||||
    validate_remote_identity_first = 0;
 | 
					 | 
				
			||||||
    return VALIDATION_PENDING_RETRY;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return VALIDATION_PENDING_HANDSHAKE_MESSAGE;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static PluginReturn begin_handshake_reply(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  if (DB_TC_PRINT_DEBUG) {
 | 
					 | 
				
			||||||
    printf("begin_handshake_reply - %d\n", begin_handshake_reply_first);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  if (begin_handshake_reply_first) {
 | 
					 | 
				
			||||||
    begin_handshake_reply_first = 0;
 | 
					 | 
				
			||||||
    return VALIDATION_PENDING_RETRY;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  return VALIDATION_OK_FINAL_MESSAGE;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static PluginReturn get_shared_secret(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  return VALIDATION_OK;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* State actions. */
 | 
					 | 
				
			||||||
static void fsm_validate_remote_identity(struct dds_security_fsm *fsm, void *arg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  PluginReturn ret;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  DDSRT_UNUSED_ARG(arg);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ret = validate_remote_identity();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (DB_TC_PRINT_DEBUG) {
 | 
					 | 
				
			||||||
    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)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  PluginReturn ret;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  DDSRT_UNUSED_ARG(arg);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ret = begin_handshake_reply();
 | 
					 | 
				
			||||||
  if (ret == VALIDATION_OK_FINAL_MESSAGE) {
 | 
					 | 
				
			||||||
    ret = get_shared_secret();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (DB_TC_PRINT_DEBUG) {
 | 
					 | 
				
			||||||
    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 StateBeginHandshakeReply = {fsm_begin_handshake_reply, 0};
 | 
					 | 
				
			||||||
static dds_security_fsm_state StateBeginHsReplyWait = {NULL, 100000000};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void a(struct dds_security_fsm *fsm, void *arg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  int *fsm_arg;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (DB_TC_PRINT_DEBUG) {
 | 
					 | 
				
			||||||
    printf("[%p] Transition %s\n", fsm, __FUNCTION__);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ddsrt_mutex_lock (&g_lock);
 | 
					 | 
				
			||||||
  if (arg != NULL) {
 | 
					 | 
				
			||||||
    fsm_arg = (int *) arg;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (*fsm_arg == FSM_AUTH_ARG) {
 | 
					 | 
				
			||||||
      correct_arg = 1;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      correct_arg = 0;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (fsm == fsm_auth) {
 | 
					 | 
				
			||||||
    correct_fsm = 1;
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    correct_fsm = 0;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  visited_auth |= 1u << 0;
 | 
					 | 
				
			||||||
  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 (PluginReturn_MAX + 1)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * .--.
 | 
					 | 
				
			||||||
 * |##|--------------------------------------.
 | 
					 | 
				
			||||||
 * '--'       a()                            v
 | 
					 | 
				
			||||||
 *                 .----------------------------------------------------.
 | 
					 | 
				
			||||||
 *                 |            StateValidateRemoteIdentity             |
 | 
					 | 
				
			||||||
 *                 |----------------------------------------------------|
 | 
					 | 
				
			||||||
 *         .------>| fsm_validate_remote_identity()                     |
 | 
					 | 
				
			||||||
 *         |       |    - dispatch VALIDATION_PENDING_RETRY             |
 | 
					 | 
				
			||||||
 *    100ms|       |    - dispatch VALIDATION_PENDING_HANDSHAKE_MESSAGE |
 | 
					 | 
				
			||||||
 *    d()  |       '----------------------------------------------------'
 | 
					 | 
				
			||||||
 *         |          VALIDATION_PENDING_RETRY|  | VALIDATION_PENDING_HANDSHAKE_MESSAGE
 | 
					 | 
				
			||||||
 *         |          b()                     |  | c()
 | 
					 | 
				
			||||||
 *         |                                  |  |
 | 
					 | 
				
			||||||
 * .------------------------------.           |  |       .-------------------------------.
 | 
					 | 
				
			||||||
 * | StateValRemIdentityRetryWait |           |  |       | StateHandshakeInitMessageWait |
 | 
					 | 
				
			||||||
 * |------------------------------|<----------'  '------>|-------------------------------|
 | 
					 | 
				
			||||||
 * '------------------------------'                      '-------------------------------'
 | 
					 | 
				
			||||||
 *                                                SHM_MSG_RECEIVED  |
 | 
					 | 
				
			||||||
 *                                                e()               |
 | 
					 | 
				
			||||||
 *                                                                  v
 | 
					 | 
				
			||||||
 *                                      .----------------------------------------.
 | 
					 | 
				
			||||||
 *          VALIDATION_PENDING_RETRY    |        StateBeginHandshakeReply        |
 | 
					 | 
				
			||||||
 *          f()                         |----------------------------------------|
 | 
					 | 
				
			||||||
 *            .-------------------------| fsm_begin_handshake_reply()            |
 | 
					 | 
				
			||||||
 *            |                         |    - dispatch VALIDATION_PENDING_RETRY |
 | 
					 | 
				
			||||||
 *            v                         |    - dispatch VALIDATION_OK            |
 | 
					 | 
				
			||||||
 * .-----------------------.    100ms   '----------------------------------------'
 | 
					 | 
				
			||||||
 * | StateBeginHsReplyWait |    h()                ^        VALIDATION_OK |
 | 
					 | 
				
			||||||
 * |-----------------------|-----------------------'        g()           |
 | 
					 | 
				
			||||||
 * '-----------------------'                                              v
 | 
					 | 
				
			||||||
 *                                                                       .-.
 | 
					 | 
				
			||||||
 *                                                                       '-'
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
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, &StateBeginHandshakeReply},
 | 
					 | 
				
			||||||
    {&StateBeginHandshakeReply,      VALIDATION_PENDING_RETRY,             f, &StateBeginHsReplyWait},
 | 
					 | 
				
			||||||
    {&StateBeginHandshakeReply,      VALIDATION_OK,                        g, NULL}, // Reaching NULL means end of state-diagram
 | 
					 | 
				
			||||||
    {&StateBeginHsReplyWait,         DDS_SECURITY_FSM_EVENT_TIMEOUT,       h, &StateBeginHandshakeReply}
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
static const uint32_t HandshakeTransistionsSize = sizeof(HandshakeTransistions)/sizeof(HandshakeTransistions[0]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**********************************************************************
 | 
					 | 
				
			||||||
 * Example State Machine properties and methods
 | 
					 | 
				
			||||||
 **********************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef enum {
 | 
					 | 
				
			||||||
    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(doStart, test, 0)
 | 
					 | 
				
			||||||
DO_SIMPLE(doRestart, test, 1)
 | 
					 | 
				
			||||||
DO_SIMPLE(doEventStuff, test, 4)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void doStuff(struct dds_security_fsm *fsm, void *arg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  DDSRT_UNUSED_ARG(fsm);
 | 
					 | 
				
			||||||
  DDSRT_UNUSED_ARG(arg);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (DB_TC_PRINT_DEBUG) {
 | 
					 | 
				
			||||||
    printf("Transition %s - %d\n", __FUNCTION__, do_stuff_counter);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  ddsrt_mutex_lock (&g_lock);
 | 
					 | 
				
			||||||
  visited_test |= 1u << 2;
 | 
					 | 
				
			||||||
  ddsrt_mutex_unlock (&g_lock);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (do_stuff_counter < 2) {
 | 
					 | 
				
			||||||
    dds_security_fsm_dispatch(fsm, eventZ, false);
 | 
					 | 
				
			||||||
  } else if (do_stuff_counter == 2) {
 | 
					 | 
				
			||||||
    dds_security_fsm_dispatch(fsm, eventY, false);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  ++do_stuff_counter;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void doOtherStuff(struct dds_security_fsm *fsm, void *arg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  DDSRT_UNUSED_ARG(fsm);
 | 
					 | 
				
			||||||
  DDSRT_UNUSED_ARG(arg);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (DB_TC_PRINT_DEBUG) {
 | 
					 | 
				
			||||||
    printf("Transition %s - %d\n", __FUNCTION__, do_other_stuff_counter);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  ddsrt_mutex_lock (&g_lock);
 | 
					 | 
				
			||||||
  visited_test |= 1u << 3;
 | 
					 | 
				
			||||||
  ddsrt_mutex_unlock (&g_lock);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (do_other_stuff_counter == 0) {
 | 
					 | 
				
			||||||
    dds_security_fsm_dispatch(fsm, DDS_SECURITY_FSM_EVENT_AUTO, false);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (do_other_stuff_counter == 1) {
 | 
					 | 
				
			||||||
    dds_security_fsm_dispatch(fsm, eventY, false);
 | 
					 | 
				
			||||||
  } else if (do_other_stuff_counter == 2) {
 | 
					 | 
				
			||||||
    dds_security_fsm_dispatch(fsm, eventX, false);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  ++do_other_stuff_counter;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static dds_security_fsm_state StateA = {doStuff,      0};
 | 
					 | 
				
			||||||
static dds_security_fsm_state StateB = {doStuff,      100000000};
 | 
					 | 
				
			||||||
static dds_security_fsm_state StateC = {NULL,         0};
 | 
					 | 
				
			||||||
static dds_security_fsm_state StateD = {doOtherStuff, 0};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static dds_security_fsm_transition Transitions[] = {
 | 
					 | 
				
			||||||
    {NULL,    DDS_SECURITY_FSM_EVENT_AUTO, doStart,      &StateA}, // NULL state is the start state
 | 
					 | 
				
			||||||
    {&StateA, eventZ,                      NULL,         &StateB},
 | 
					 | 
				
			||||||
    {&StateA, eventY,                      doOtherStuff, &StateC},
 | 
					 | 
				
			||||||
    {&StateB, eventX,                      NULL,         NULL}, // Reaching NULL means end of state-diagram
 | 
					 | 
				
			||||||
    {&StateB, eventZ,                      doRestart,    &StateA},
 | 
					 | 
				
			||||||
    {&StateC, DDS_SECURITY_FSM_EVENT_AUTO, doEventStuff, &StateD},
 | 
					 | 
				
			||||||
    {&StateD, eventY,                      doEventStuff, &StateD},
 | 
					 | 
				
			||||||
    {&StateD, eventX,                      doStuff,      NULL}, // Reaching NULL means end of sttimeoutate-diagram
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
static const uint32_t TransitionsSize = sizeof(Transitions)/sizeof(Transitions[0]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**********************************************************************
 | 
					 | 
				
			||||||
 * Timeout State Machine properties and methods
 | 
					 | 
				
			||||||
 **********************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
typedef enum {
 | 
					 | 
				
			||||||
    eventToTimeout, eventToInterupt, eventToEnd,
 | 
					 | 
				
			||||||
} 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(doInterrupt, timeout, 0)
 | 
					 | 
				
			||||||
DO_SIMPLE(TimeoutCallback2, timeout, 3)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void doTimeout(struct dds_security_fsm *fsm, void *arg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  DDSRT_UNUSED_ARG(arg);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (DB_TC_PRINT_DEBUG) {
 | 
					 | 
				
			||||||
    printf("Transition >>>> %s\n", __FUNCTION__);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  ddsrt_mutex_lock (&g_lock);
 | 
					 | 
				
			||||||
  visited_timeout |= 1u << 1;
 | 
					 | 
				
			||||||
  ddsrt_mutex_unlock (&g_lock);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (DB_TC_PRINT_DEBUG) {
 | 
					 | 
				
			||||||
    printf("Transition <<<< %s\n", __FUNCTION__);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  dds_security_fsm_dispatch(fsm, eventToTimeout, false);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void TimeoutCallback(struct dds_security_fsm *fsm, void *arg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  struct fsm_timeout_arg *farg = arg;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (DB_TC_PRINT_DEBUG) {
 | 
					 | 
				
			||||||
    printf("TimeoutCallback\n");
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ddsrt_mutex_lock (&g_lock);
 | 
					 | 
				
			||||||
  visited_timeout |= 1u << 2;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (farg != NULL) {
 | 
					 | 
				
			||||||
    if (farg->id == FSM_AUTH_ARG) {
 | 
					 | 
				
			||||||
      correct_arg_timeout = 1;
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      correct_arg_timeout = 0;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  if (fsm == fsm_timeout) {
 | 
					 | 
				
			||||||
    correct_fsm_timeout = 1;
 | 
					 | 
				
			||||||
  } else {
 | 
					 | 
				
			||||||
    correct_fsm_timeout = 0;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  ddsrt_mutex_unlock (&g_lock);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static dds_security_fsm_state StateInitial     = {doTimeout,  0};
 | 
					 | 
				
			||||||
static dds_security_fsm_state StateWaitTimeout = {NULL, DDS_SECS(4)};
 | 
					 | 
				
			||||||
static dds_security_fsm_state StateInterupt    = {doInterrupt, 0};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static const dds_security_fsm_transition TimeoutTransitions[] = {
 | 
					 | 
				
			||||||
    {NULL,              DDS_SECURITY_FSM_EVENT_AUTO,    NULL, &StateInitial},  // NULL state is the start state
 | 
					 | 
				
			||||||
    {&StateInitial,     eventToTimeout,                 NULL, &StateWaitTimeout},
 | 
					 | 
				
			||||||
    {&StateWaitTimeout, DDS_SECURITY_FSM_EVENT_TIMEOUT, NULL, &StateInterupt},
 | 
					 | 
				
			||||||
    {&StateWaitTimeout, eventToInterupt,                NULL, &StateInterupt},
 | 
					 | 
				
			||||||
    {&StateInterupt,    eventToEnd,                     NULL, NULL},           // Reaching NULL means end of state-diagram
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
static const uint32_t TimeoutTransitionsSize = sizeof(TimeoutTransitions)/sizeof(TimeoutTransitions[0]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**********************************************************************
 | 
					 | 
				
			||||||
 * Parallel Timeout State Machines properties and methods
 | 
					 | 
				
			||||||
 **********************************************************************/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static struct dds_security_fsm *fsm_timeout1;
 | 
					 | 
				
			||||||
static struct dds_security_fsm *fsm_timeout2;
 | 
					 | 
				
			||||||
static struct dds_security_fsm *fsm_timeout3;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static dds_time_t time0 = 0;
 | 
					 | 
				
			||||||
static dds_time_t time1 = 0;
 | 
					 | 
				
			||||||
static dds_time_t time2 = 0;
 | 
					 | 
				
			||||||
static dds_time_t time3 = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void StateParTime1(struct dds_security_fsm *fsm, void *arg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  DDSRT_UNUSED_ARG(fsm);
 | 
					 | 
				
			||||||
  DDSRT_UNUSED_ARG(arg);
 | 
					 | 
				
			||||||
  time1 = dds_time();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void StateParTime2(struct dds_security_fsm *fsm, void *arg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  DDSRT_UNUSED_ARG(fsm);
 | 
					 | 
				
			||||||
  DDSRT_UNUSED_ARG(arg);
 | 
					 | 
				
			||||||
  time2 = dds_time();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void StateParTime3(struct dds_security_fsm *fsm, void *arg)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  DDSRT_UNUSED_ARG(fsm);
 | 
					 | 
				
			||||||
  DDSRT_UNUSED_ARG(arg);
 | 
					 | 
				
			||||||
  time3 = dds_time();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static dds_security_fsm_state StateParTimeout1 = {NULL, DDS_SECS(1)};
 | 
					 | 
				
			||||||
static dds_security_fsm_state StateParTimeout2 = {NULL, DDS_SECS(2)};
 | 
					 | 
				
			||||||
static dds_security_fsm_state StateParTimeout3 = {NULL, DDS_SECS(1)};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static dds_security_fsm_transition ParallelTimeoutTransitions_1[] = {
 | 
					 | 
				
			||||||
    {NULL,              DDS_SECURITY_FSM_EVENT_AUTO,    NULL,           &StateParTimeout1}, // NULL state is the startfsm_control_thread state
 | 
					 | 
				
			||||||
    {&StateParTimeout1, DDS_SECURITY_FSM_EVENT_TIMEOUT, &StateParTime1, NULL},              // Reaching NULL means end of state-diagram
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
static const uint32_t ParallelTimeoutTransitionsSize_1 = sizeof(ParallelTimeoutTransitions_1) / sizeof(ParallelTimeoutTransitions_1[0]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static dds_security_fsm_transition ParallelTimeoutTransitions_2[] = {
 | 
					 | 
				
			||||||
    {NULL,              DDS_SECURITY_FSM_EVENT_AUTO,    NULL,           &StateParTimeout2}, // NULL state is the start state
 | 
					 | 
				
			||||||
    {&StateParTimeout2, DDS_SECURITY_FSM_EVENT_TIMEOUT, &StateParTime2, NULL},              // Reaching NULL means end of state-diagram
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
static const uint32_t ParallelTimeoutTransitionsSize_2 = sizeof(ParallelTimeoutTransitions_2) / sizeof(ParallelTimeoutTransitions_2[0]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static dds_security_fsm_transition ParallelTimeoutTransitions_3[] = {
 | 
					 | 
				
			||||||
    {NULL,              DDS_SECURITY_FSM_EVENT_AUTO,    NULL,           &StateParTimeout3}, // NULL state is the start state
 | 
					 | 
				
			||||||
    {&StateParTimeout3, DDS_SECURITY_FSM_EVENT_TIMEOUT, &StateParTime3, NULL},              // Reaching NULL means end of state-diagram
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
static const uint32_t ParallelTimeoutTransitionsSize_3 = sizeof(ParallelTimeoutTransitions_3) / sizeof(ParallelTimeoutTransitions_3[0]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void fsm_control_init(void)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  dds_return_t rc;
 | 
					 | 
				
			||||||
  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);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  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_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);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
CU_Test(ddssec_fsm, create, .init = fsm_control_init, .fini = fsm_control_fini)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  dds_time_t delay30 = DDS_SECS(30);
 | 
					 | 
				
			||||||
  int timeout;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /*
 | 
					 | 
				
			||||||
   * 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)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // set a delay that doesn't expire. Should be terminate when fsm is freed.
 | 
					 | 
				
			||||||
  dds_security_fsm_set_timeout(fsm_auth, TimeoutCallback, delay30);
 | 
					 | 
				
			||||||
  dds_security_fsm_start(fsm_auth);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /**
 | 
					 | 
				
			||||||
   * Check the result of one running State Machine
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Wait for the last state to occur
 | 
					 | 
				
			||||||
  timeout = 100; /* 10 sec */
 | 
					 | 
				
			||||||
  while ((dds_security_fsm_current_state(fsm_auth) != &StateHandshakeInitMessageWait) && (timeout > 0)) {
 | 
					 | 
				
			||||||
    dds_sleepfor(msec100);
 | 
					 | 
				
			||||||
    timeout--;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  CU_ASSERT(timeout > 0);
 | 
					 | 
				
			||||||
  dds_security_fsm_dispatch(fsm_auth, SHM_MSG_RECEIVED, false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  timeout = 100; /* 10 sec */
 | 
					 | 
				
			||||||
  while ((dds_security_fsm_current_state(fsm_auth) != NULL) && (timeout > 0)) {
 | 
					 | 
				
			||||||
    dds_sleepfor(msec100);
 | 
					 | 
				
			||||||
    timeout--;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  CU_ASSERT(timeout > 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ddsrt_mutex_lock (&g_lock);
 | 
					 | 
				
			||||||
  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);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* Check whether timeout callback has NOT been invoked */
 | 
					 | 
				
			||||||
  ddsrt_mutex_lock (&g_lock);
 | 
					 | 
				
			||||||
  CU_ASSERT(visited_timeout == 0);
 | 
					 | 
				
			||||||
  ddsrt_mutex_unlock (&g_lock);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Test multiple (2) running state machines
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
CU_Test(ddssec_fsm, multiple, .init = fsm_control_init, .fini = fsm_control_fini)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  int timeout;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /*Check creation of multiple (2) State Machines*/
 | 
					 | 
				
			||||||
  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_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);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* Check the results of multiple running State Machines */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* Wait for the last state to occur */
 | 
					 | 
				
			||||||
  timeout = 100; /* 10 sec */
 | 
					 | 
				
			||||||
  while ((dds_security_fsm_current_state(fsm_auth) != &StateHandshakeInitMessageWait) && (timeout > 0)) {
 | 
					 | 
				
			||||||
    dds_sleepfor(100 * DDS_NSECS_IN_MSEC);
 | 
					 | 
				
			||||||
    timeout--;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  CU_ASSERT_FATAL(timeout > 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  timeout = 100; /* 10 sec */
 | 
					 | 
				
			||||||
  dds_security_fsm_dispatch(fsm_auth, SHM_MSG_RECEIVED, false);
 | 
					 | 
				
			||||||
  while ((dds_security_fsm_current_state(fsm_auth) != NULL) && (timeout > 0)) {
 | 
					 | 
				
			||||||
    dds_sleepfor(100 * DDS_NSECS_IN_MSEC);
 | 
					 | 
				
			||||||
    timeout--;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  CU_ASSERT_FATAL(timeout > 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);
 | 
					 | 
				
			||||||
  ddsrt_mutex_unlock (&g_lock);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* Wait for the last state to occur */
 | 
					 | 
				
			||||||
  timeout = 100; /* 10 sec */
 | 
					 | 
				
			||||||
  while ((dds_security_fsm_current_state(fsm_test) != NULL) && timeout > 0) {
 | 
					 | 
				
			||||||
    dds_sleepfor(100 * DDS_NSECS_IN_MSEC);
 | 
					 | 
				
			||||||
    timeout--;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  CU_ASSERT_FATAL(timeout > 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ddsrt_mutex_lock (&g_lock);
 | 
					 | 
				
			||||||
  CU_ASSERT(visited_test == 0x1f);
 | 
					 | 
				
			||||||
  ddsrt_mutex_unlock (&g_lock);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  dds_security_fsm_free(fsm_auth);
 | 
					 | 
				
			||||||
  dds_security_fsm_free(fsm_test);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Check creation of State Machine for timeout purposes
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
CU_Test(ddssec_fsm, timeout, .init = fsm_control_init, .fini = fsm_control_fini)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  dds_time_t delay1 = DDS_SECS(1);
 | 
					 | 
				
			||||||
  int timeout;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  visited_timeout = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /*
 | 
					 | 
				
			||||||
   * Test timeout monitoring of state machines
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
  fsm_timeout = dds_security_fsm_create(g_fsm_control, TimeoutTransitions, TimeoutTransitionsSize, &fsm_arg);
 | 
					 | 
				
			||||||
  CU_ASSERT(fsm_timeout != NULL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  dds_security_fsm_set_timeout(fsm_timeout, TimeoutCallback, delay1);
 | 
					 | 
				
			||||||
  dds_security_fsm_start(fsm_timeout);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /*Check the result of the running State Machine for timeout purposes*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  // Wait for the last state to occur
 | 
					 | 
				
			||||||
  timeout = 100; /* 10 sec */
 | 
					 | 
				
			||||||
  ddsrt_mutex_lock (&g_lock);
 | 
					 | 
				
			||||||
  while (visited_timeout != 0x7 && (timeout > 0)) {
 | 
					 | 
				
			||||||
    ddsrt_mutex_unlock (&g_lock);
 | 
					 | 
				
			||||||
    dds_sleepfor(100 * DDS_NSECS_IN_MSEC);
 | 
					 | 
				
			||||||
    timeout--;
 | 
					 | 
				
			||||||
    ddsrt_mutex_lock (&g_lock);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  CU_ASSERT(timeout > 0);
 | 
					 | 
				
			||||||
  CU_ASSERT(visited_timeout == 0x7);
 | 
					 | 
				
			||||||
  CU_ASSERT(correct_arg_timeout && correct_fsm_timeout);
 | 
					 | 
				
			||||||
  ddsrt_mutex_unlock (&g_lock);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  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)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  dds_time_t delay1 = DDS_SECS(1);
 | 
					 | 
				
			||||||
  dds_time_t delay2 = DDS_SECS(2);
 | 
					 | 
				
			||||||
  int timeout;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  visited_timeout = 0;
 | 
					 | 
				
			||||||
  fsm_timeout = dds_security_fsm_create(g_fsm_control, TimeoutTransitions, TimeoutTransitionsSize, &fsm_arg);
 | 
					 | 
				
			||||||
  CU_ASSERT(fsm_timeout != NULL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  fsm_timeout2 = dds_security_fsm_create(g_fsm_control, TimeoutTransitions, TimeoutTransitionsSize, &fsm_arg);
 | 
					 | 
				
			||||||
  CU_ASSERT(fsm_timeout2 != NULL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  dds_security_fsm_set_timeout(fsm_timeout, TimeoutCallback, delay1);
 | 
					 | 
				
			||||||
  dds_security_fsm_set_timeout(fsm_timeout2, TimeoutCallback2, delay2);
 | 
					 | 
				
			||||||
  dds_security_fsm_start(fsm_timeout);
 | 
					 | 
				
			||||||
  dds_security_fsm_start(fsm_timeout2);
 | 
					 | 
				
			||||||
  timeout = 100; /* 10 sec */
 | 
					 | 
				
			||||||
  ddsrt_mutex_lock (&g_lock);
 | 
					 | 
				
			||||||
  while (visited_timeout != 0xf && (timeout > 0)) {
 | 
					 | 
				
			||||||
    ddsrt_mutex_unlock (&g_lock);
 | 
					 | 
				
			||||||
    dds_sleepfor(100 * DDS_NSECS_IN_MSEC);
 | 
					 | 
				
			||||||
    timeout--;
 | 
					 | 
				
			||||||
    ddsrt_mutex_lock (&g_lock);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  CU_ASSERT(visited_timeout == 0xf);
 | 
					 | 
				
			||||||
  ddsrt_mutex_unlock (&g_lock);
 | 
					 | 
				
			||||||
  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)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  dds_duration_t delta1;
 | 
					 | 
				
			||||||
  dds_duration_t delta2;
 | 
					 | 
				
			||||||
  dds_duration_t delta3;
 | 
					 | 
				
			||||||
  int timeout;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  visited_timeout = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  fsm_timeout1 = dds_security_fsm_create(g_fsm_control, ParallelTimeoutTransitions_1, ParallelTimeoutTransitionsSize_1, &fsm_arg);
 | 
					 | 
				
			||||||
  CU_ASSERT_FATAL(fsm_timeout1 != NULL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  fsm_timeout2 = dds_security_fsm_create(g_fsm_control, ParallelTimeoutTransitions_2, ParallelTimeoutTransitionsSize_2, &fsm_arg);
 | 
					 | 
				
			||||||
  CU_ASSERT_FATAL(fsm_timeout2 != NULL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  fsm_timeout3 = dds_security_fsm_create(g_fsm_control, ParallelTimeoutTransitions_3, ParallelTimeoutTransitionsSize_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);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* Wait for both to end. */
 | 
					 | 
				
			||||||
  timeout = 300; /* 10 sec */
 | 
					 | 
				
			||||||
  /* First, they have to be started. */
 | 
					 | 
				
			||||||
  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)) && (timeout > 0)) {
 | 
					 | 
				
			||||||
    dds_sleepfor(100 * DDS_NSECS_IN_MSEC);
 | 
					 | 
				
			||||||
    timeout--;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* Then, they have to have ended. */
 | 
					 | 
				
			||||||
  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)) && (timeout > 0)) {
 | 
					 | 
				
			||||||
    dds_sleepfor(100 * DDS_NSECS_IN_MSEC);
 | 
					 | 
				
			||||||
    timeout--;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /*
 | 
					 | 
				
			||||||
   * There should be about 1 second difference between all times:
 | 
					 | 
				
			||||||
   *      time1 = time0 + 1
 | 
					 | 
				
			||||||
   *      time2 = time0 + 2
 | 
					 | 
				
			||||||
   *      time3 = time0 + 1
 | 
					 | 
				
			||||||
   */
 | 
					 | 
				
			||||||
  delta1 = time1 - time0;
 | 
					 | 
				
			||||||
  delta2 = time2 - time0;
 | 
					 | 
				
			||||||
  delta3 = time3 - time0;
 | 
					 | 
				
			||||||
  printf("Time0 %" PRId64 "\n", time0);
 | 
					 | 
				
			||||||
  printf("Time1 %" PRId64 "\n", time1);
 | 
					 | 
				
			||||||
  printf("Time2 %" PRId64 "\n", time2);
 | 
					 | 
				
			||||||
  printf("Time3 %" PRId64 "\n", time3);
 | 
					 | 
				
			||||||
  printf("Delta1 %" PRId64 "\n", delta1);
 | 
					 | 
				
			||||||
  printf("Delta2 %" PRId64 "\n", delta2);
 | 
					 | 
				
			||||||
  printf("Delta3 %" PRId64 "\n", delta3);
 | 
					 | 
				
			||||||
  CU_ASSERT(delta1 > 750 * DDS_NSECS_IN_MSEC);
 | 
					 | 
				
			||||||
  CU_ASSERT(delta1 < 1250 * DDS_NSECS_IN_MSEC);
 | 
					 | 
				
			||||||
  CU_ASSERT(delta2 > 1750 * DDS_NSECS_IN_MSEC);
 | 
					 | 
				
			||||||
  CU_ASSERT(delta2 < 2250 * DDS_NSECS_IN_MSEC);
 | 
					 | 
				
			||||||
  CU_ASSERT(delta3 > 750 * DDS_NSECS_IN_MSEC);
 | 
					 | 
				
			||||||
  CU_ASSERT(delta3 < 1250 * DDS_NSECS_IN_MSEC);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  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)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  int timeout;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  fsm_timeout = dds_security_fsm_create(g_fsm_control, TimeoutTransitions, TimeoutTransitionsSize, &fsm_arg);
 | 
					 | 
				
			||||||
  CU_ASSERT (fsm_timeout != NULL)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  visited_timeout = 0;
 | 
					 | 
				
			||||||
  dds_security_fsm_start(fsm_timeout);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /* Wait until we're in the timeout function. */
 | 
					 | 
				
			||||||
  timeout = 100; /* 10 sec */
 | 
					 | 
				
			||||||
  ddsrt_mutex_lock (&g_lock);
 | 
					 | 
				
			||||||
  while ((visited_timeout == 0) && (timeout > 0)) {
 | 
					 | 
				
			||||||
    ddsrt_mutex_unlock (&g_lock);
 | 
					 | 
				
			||||||
    dds_sleepfor(100 * DDS_NSECS_IN_MSEC);
 | 
					 | 
				
			||||||
    timeout--;
 | 
					 | 
				
			||||||
    ddsrt_mutex_lock (&g_lock);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  ddsrt_mutex_unlock (&g_lock);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  dds_security_fsm_free(fsm_timeout);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
							
								
								
									
										374
									
								
								src/security/core/tests/timed_cb.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										374
									
								
								src/security/core/tests/timed_cb.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,374 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright(c) 2019 ADLINK Technology Limited and others
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * This program and the accompanying materials are made available under the
 | 
				
			||||||
 | 
					 * terms of the Eclipse Public License v. 2.0 which is available at
 | 
				
			||||||
 | 
					 * http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
 | 
				
			||||||
 | 
					 * v. 1.0 which is available at
 | 
				
			||||||
 | 
					 * http://www.eclipse.org/org/documents/edl-v10.php.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include "CUnit/Test.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "dds/security/core/dds_security_timed_cb.h"
 | 
				
			||||||
 | 
					#include "dds/ddsrt/misc.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SEQ_SIZE (16)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  struct dds_security_timed_dispatcher_t *d;
 | 
				
			||||||
 | 
					  dds_security_timed_cb_kind kind;
 | 
				
			||||||
 | 
					  void *listener;
 | 
				
			||||||
 | 
					  void *arg;
 | 
				
			||||||
 | 
					  dds_time_t time;
 | 
				
			||||||
 | 
					} test_sequence_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int g_sequence_idx = 0;
 | 
				
			||||||
 | 
					static test_sequence_data g_sequence_array[SEQ_SIZE];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void simple_callback(struct dds_security_timed_dispatcher_t *d, dds_security_timed_cb_kind kind, void *listener, void *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  DDSRT_UNUSED_ARG(d);
 | 
				
			||||||
 | 
					  DDSRT_UNUSED_ARG(kind);
 | 
				
			||||||
 | 
					  DDSRT_UNUSED_ARG(listener);
 | 
				
			||||||
 | 
					  *((bool *)arg) = !(*((bool *)arg));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int g_order_callback_idx = 0;
 | 
				
			||||||
 | 
					static void *g_order_callback[2] = {(void *)NULL, (void *)NULL};
 | 
				
			||||||
 | 
					static void order_callback(struct dds_security_timed_dispatcher_t *d, dds_security_timed_cb_kind kind, void *listener, void *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  DDSRT_UNUSED_ARG(d);
 | 
				
			||||||
 | 
					  DDSRT_UNUSED_ARG(kind);
 | 
				
			||||||
 | 
					  DDSRT_UNUSED_ARG(listener);
 | 
				
			||||||
 | 
					  g_order_callback[g_order_callback_idx] = arg;
 | 
				
			||||||
 | 
					  g_order_callback_idx++;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void test_callback(struct dds_security_timed_dispatcher_t *d, dds_security_timed_cb_kind kind, void *listener, void *arg)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  if (g_sequence_idx < SEQ_SIZE)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    g_sequence_array[g_sequence_idx].d = d;
 | 
				
			||||||
 | 
					    g_sequence_array[g_sequence_idx].arg = arg;
 | 
				
			||||||
 | 
					    g_sequence_array[g_sequence_idx].kind = kind;
 | 
				
			||||||
 | 
					    g_sequence_array[g_sequence_idx].listener = listener;
 | 
				
			||||||
 | 
					    g_sequence_array[g_sequence_idx].time = dds_time();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  g_sequence_idx++;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CU_Test(ddssec_timed_cb, simple_test)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  struct dds_security_timed_cb_data *tcb = dds_security_timed_cb_new();
 | 
				
			||||||
 | 
					  static bool test_var = false;
 | 
				
			||||||
 | 
					  dds_time_t future = dds_time() + DDS_SECS(2);
 | 
				
			||||||
 | 
					  struct dds_security_timed_dispatcher_t *d1 = dds_security_timed_dispatcher_new(tcb);
 | 
				
			||||||
 | 
					  CU_ASSERT_PTR_NOT_NULL_FATAL(d1);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_add(tcb, d1, simple_callback, future, (void *)&test_var);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_enable(tcb, d1, (void *)NULL);
 | 
				
			||||||
 | 
					  CU_ASSERT_FALSE_FATAL(test_var);
 | 
				
			||||||
 | 
					  dds_sleepfor(DDS_MSECS(500));
 | 
				
			||||||
 | 
					  CU_ASSERT_FALSE_FATAL(test_var);
 | 
				
			||||||
 | 
					  dds_sleepfor(DDS_SECS(2));
 | 
				
			||||||
 | 
					  CU_ASSERT_TRUE_FATAL(test_var);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_free(tcb, d1);
 | 
				
			||||||
 | 
					  dds_security_timed_cb_free(tcb);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CU_Test(ddssec_timed_cb, simple_order)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  struct dds_security_timed_cb_data *tcb = dds_security_timed_cb_new();
 | 
				
			||||||
 | 
					  struct dds_security_timed_dispatcher_t *d1 = dds_security_timed_dispatcher_new(tcb);
 | 
				
			||||||
 | 
					  CU_ASSERT_PTR_NOT_NULL_FATAL(d1);
 | 
				
			||||||
 | 
					  dds_time_t future = dds_time() + DDS_MSECS(20), future2 = future;
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_add(tcb, d1, order_callback, future, (void *)1);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_add(tcb, d1, order_callback, future2, (void *)2);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_enable(tcb, d1, (void *)&g_order_callback);
 | 
				
			||||||
 | 
					  dds_sleepfor(DDS_MSECS(10));
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_free(tcb, d1);
 | 
				
			||||||
 | 
					  CU_ASSERT_EQUAL_FATAL(g_order_callback[0], (void *)1);
 | 
				
			||||||
 | 
					  CU_ASSERT_EQUAL_FATAL(g_order_callback[1], (void *)2);
 | 
				
			||||||
 | 
					  dds_security_timed_cb_free(tcb);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CU_Test(ddssec_timed_cb, test_enabled_and_disabled)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  struct dds_security_timed_cb_data *tcb = dds_security_timed_cb_new();
 | 
				
			||||||
 | 
					  static bool test_var = false;
 | 
				
			||||||
 | 
					  dds_time_t future = dds_time() + DDS_SECS(2);
 | 
				
			||||||
 | 
					  struct dds_security_timed_dispatcher_t *d1 = dds_security_timed_dispatcher_new(tcb);
 | 
				
			||||||
 | 
					  CU_ASSERT_PTR_NOT_NULL_FATAL(d1);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_add(tcb, d1, simple_callback, future, (void *)&test_var);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_enable(tcb, d1, (void *)NULL);
 | 
				
			||||||
 | 
					  CU_ASSERT_FALSE(test_var);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_disable(tcb, d1);
 | 
				
			||||||
 | 
					  dds_sleepfor(DDS_MSECS(500));
 | 
				
			||||||
 | 
					  CU_ASSERT_FALSE(test_var);
 | 
				
			||||||
 | 
					  dds_sleepfor(DDS_SECS(2));
 | 
				
			||||||
 | 
					  CU_ASSERT_FALSE(test_var);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_free(tcb, d1);
 | 
				
			||||||
 | 
					  dds_security_timed_cb_free(tcb);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CU_Test(ddssec_timed_cb, simple_test_with_future)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  struct dds_security_timed_cb_data *tcb = dds_security_timed_cb_new();
 | 
				
			||||||
 | 
					  static bool test_var = false;
 | 
				
			||||||
 | 
					  dds_time_t now = dds_time(), future = now + DDS_SECS(2), far_future = now + DDS_SECS(10);
 | 
				
			||||||
 | 
					  struct dds_security_timed_dispatcher_t *d1 = dds_security_timed_dispatcher_new(tcb);
 | 
				
			||||||
 | 
					  CU_ASSERT_PTR_NOT_NULL_FATAL(d1);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_enable(tcb, d1, (void *)NULL);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_add(tcb, d1, simple_callback, future, (void *)&test_var);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_add(tcb, d1, simple_callback, far_future, (void *)&test_var);
 | 
				
			||||||
 | 
					  CU_ASSERT_FALSE_FATAL(test_var);
 | 
				
			||||||
 | 
					  dds_sleepfor(DDS_MSECS(500));
 | 
				
			||||||
 | 
					  CU_ASSERT_FALSE_FATAL(test_var);
 | 
				
			||||||
 | 
					  dds_sleepfor(DDS_SECS(2));
 | 
				
			||||||
 | 
					  CU_ASSERT_TRUE_FATAL(test_var);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_free(tcb, d1);
 | 
				
			||||||
 | 
					  dds_security_timed_cb_free(tcb);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CU_Test(ddssec_timed_cb, test_multiple_dispatchers)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  struct dds_security_timed_cb_data *tcb = dds_security_timed_cb_new();
 | 
				
			||||||
 | 
					  static bool test_var = false;
 | 
				
			||||||
 | 
					  dds_time_t now = dds_time(), future = now + DDS_SECS(2), far_future = now + DDS_SECS(10);
 | 
				
			||||||
 | 
					  struct dds_security_timed_dispatcher_t *d1 = dds_security_timed_dispatcher_new(tcb);
 | 
				
			||||||
 | 
					  struct dds_security_timed_dispatcher_t *d2 = dds_security_timed_dispatcher_new(tcb);
 | 
				
			||||||
 | 
					  CU_ASSERT_PTR_NOT_NULL_FATAL(d1);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_enable(tcb, d1, (void *)NULL);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_enable(tcb, d2, (void *)NULL);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_free(tcb, d2);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_add(tcb, d1, simple_callback, future, (void *)&test_var);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_add(tcb, d1, simple_callback, far_future, (void *)&test_var);
 | 
				
			||||||
 | 
					  CU_ASSERT_FALSE_FATAL(test_var);
 | 
				
			||||||
 | 
					  dds_sleepfor(DDS_MSECS(500));
 | 
				
			||||||
 | 
					  CU_ASSERT_FALSE_FATAL(test_var);
 | 
				
			||||||
 | 
					  dds_sleepfor(DDS_SECS(2));
 | 
				
			||||||
 | 
					  CU_ASSERT_TRUE_FATAL(test_var);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_free(tcb, d1);
 | 
				
			||||||
 | 
					  dds_security_timed_cb_free(tcb);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CU_Test(ddssec_timed_cb, test_not_enabled_multiple_dispatchers)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  struct dds_security_timed_cb_data *tcb = dds_security_timed_cb_new();
 | 
				
			||||||
 | 
					  struct dds_security_timed_dispatcher_t *d1 = dds_security_timed_dispatcher_new(tcb);
 | 
				
			||||||
 | 
					  struct dds_security_timed_dispatcher_t *d2 = dds_security_timed_dispatcher_new(tcb);
 | 
				
			||||||
 | 
					  CU_ASSERT_PTR_NOT_NULL_FATAL(d1);
 | 
				
			||||||
 | 
					  CU_ASSERT_PTR_NOT_NULL_FATAL(d2);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_free(tcb, d2);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_free(tcb, d1);
 | 
				
			||||||
 | 
					  dds_security_timed_cb_free(tcb);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CU_Test(ddssec_timed_cb, test_create_dispatcher)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  struct dds_security_timed_cb_data *tcb = dds_security_timed_cb_new();
 | 
				
			||||||
 | 
					  struct dds_security_timed_dispatcher_t *d1 = NULL;
 | 
				
			||||||
 | 
					  struct dds_security_timed_dispatcher_t *d2 = NULL;
 | 
				
			||||||
 | 
					  struct dds_security_timed_dispatcher_t *d3 = NULL;
 | 
				
			||||||
 | 
					  struct dds_security_timed_dispatcher_t *d4 = NULL;
 | 
				
			||||||
 | 
					  struct dds_security_timed_dispatcher_t *d5 = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  dds_time_t now = dds_time();
 | 
				
			||||||
 | 
					  dds_time_t past = now - DDS_SECS(1);
 | 
				
			||||||
 | 
					  dds_time_t present = now + DDS_SECS(1);
 | 
				
			||||||
 | 
					  dds_time_t future = present + DDS_SECS(1);
 | 
				
			||||||
 | 
					  dds_time_t future2 = future + DDS_SECS(10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  d1 = dds_security_timed_dispatcher_new(tcb);
 | 
				
			||||||
 | 
					  d2 = dds_security_timed_dispatcher_new(tcb);
 | 
				
			||||||
 | 
					  CU_ASSERT_PTR_NOT_NULL_FATAL(d1);
 | 
				
			||||||
 | 
					  CU_ASSERT_PTR_NOT_NULL_FATAL(d2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* The last argument is a sequence number in which
 | 
				
			||||||
 | 
					     the callbacks are expected to be called. */
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_add(tcb, d1, test_callback, present, (void *)1);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_add(tcb, d2, test_callback, past, (void *)0);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_add(tcb, d2, test_callback, present, (void *)2);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_add(tcb, d1, test_callback, future, (void *)7);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  d3 = dds_security_timed_dispatcher_new(tcb);
 | 
				
			||||||
 | 
					  d4 = dds_security_timed_dispatcher_new(tcb);
 | 
				
			||||||
 | 
					  d5 = dds_security_timed_dispatcher_new(tcb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  CU_ASSERT_PTR_NOT_NULL_FATAL(d3);
 | 
				
			||||||
 | 
					  CU_ASSERT_PTR_NOT_NULL_FATAL(d4);
 | 
				
			||||||
 | 
					  CU_ASSERT_PTR_NOT_NULL_FATAL(d5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* The sleeps are added to get the timing between 'present' and 'past' callbacks right. */
 | 
				
			||||||
 | 
					  dds_sleepfor(DDS_MSECS(600));
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_enable(tcb, d1, (void *)NULL);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_enable(tcb, d2, (void *)d2);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_enable(tcb, d3, (void *)NULL);
 | 
				
			||||||
 | 
					  /* Specifically not enabling d4 and d5. */
 | 
				
			||||||
 | 
					  dds_sleepfor(DDS_MSECS(600));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* The last argument is a sequence number in which the callbacks are expected to be called. */
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_add(tcb, d4, test_callback, past, (void *)99);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_add(tcb, d2, test_callback, future, (void *)8);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_add(tcb, d3, test_callback, future2, (void *)9);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_add(tcb, d1, test_callback, past, (void *)3);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_add(tcb, d1, test_callback, future2, (void *)10);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_add(tcb, d1, test_callback, present, (void *)4);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_add(tcb, d2, test_callback, present, (void *)5);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_add(tcb, d1, test_callback, future, (void *)6);
 | 
				
			||||||
 | 
					  dds_security_timed_dispatcher_add(tcb, d3, test_callback, future2, (void *)11);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  int idx;
 | 
				
			||||||
 | 
					  int n = 200;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Wait for the callbacks to have been triggered. Ignore the ones in the far future. */
 | 
				
			||||||
 | 
					  while (g_sequence_idx < 8 && n-- > 0)
 | 
				
			||||||
 | 
					    dds_sleepfor(DDS_MSECS(10));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Print and check sequence of triggered callbacks. */
 | 
				
			||||||
 | 
					  for (idx = 0; idx < g_sequence_idx && idx < SEQ_SIZE; idx++)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    int seq = (int)(long long)(g_sequence_array[idx].arg);
 | 
				
			||||||
 | 
					    struct dds_security_timed_dispatcher_t *expected_d;
 | 
				
			||||||
 | 
					    void *expected_l;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (seq == 1 || seq == 6 || seq == 3 || seq == 10 || seq == 4 || seq == 7)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      expected_d = d1;
 | 
				
			||||||
 | 
					      expected_l = NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (seq == 0 || seq == 2 || seq == 8 || seq == 5)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      expected_d = d2;
 | 
				
			||||||
 | 
					      expected_l = d2;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (seq == 9)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      expected_d = d3;
 | 
				
			||||||
 | 
					      expected_l = NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (seq == 99)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      expected_d = d4;
 | 
				
			||||||
 | 
					      expected_l = NULL;
 | 
				
			||||||
 | 
					      CU_FAIL_FATAL("Unexpected callback on a disabled dispatcher");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      expected_d = NULL;
 | 
				
			||||||
 | 
					      expected_l = NULL;
 | 
				
			||||||
 | 
					      CU_FAIL_FATAL(sprintf("Unknown sequence idx received %d", seq));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (seq != idx)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      /* 6 and 7 order may be mixed since the order is not defined for same time stamp */
 | 
				
			||||||
 | 
					      if (!((seq == 6 && idx == 7) || (seq == 7 && idx == 6)))
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        CU_FAIL_FATAL(sprintf("Unexpected sequence ordering %d vs %d\n", seq, idx));
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (seq > 8)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      CU_FAIL_FATAL(sprintf("Unexpected sequence idx %d of the far future", seq));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (idx > 8)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      CU_FAIL_FATAL(sprintf("Too many callbacks %d", idx));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Callback contents checks. */
 | 
				
			||||||
 | 
					    if (expected_d != NULL)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      if (g_sequence_array[idx].d != expected_d)
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        CU_FAIL_FATAL(sprintf("Unexpected dispatcher %p vs %p\n", g_sequence_array[idx].d, expected_d));
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (g_sequence_array[idx].listener != expected_l)
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        CU_FAIL_FATAL(sprintf("Unexpected listener %p vs %p", g_sequence_array[idx].listener, expected_l));
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Callback kind check. */
 | 
				
			||||||
 | 
					    if (g_sequence_array[idx].kind != DDS_SECURITY_TIMED_CB_KIND_TIMEOUT)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      CU_FAIL_FATAL(sprintf("Unexpected kind %d vs %d", (int)g_sequence_array[idx].kind, (int)DDS_SECURITY_TIMED_CB_KIND_TIMEOUT));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (g_sequence_idx < 8)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    CU_FAIL_FATAL(sprintf("Received %d callbacks, while 9 are expected", g_sequence_idx + 1));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Reset callback index to catch the deletion ones. */
 | 
				
			||||||
 | 
					  g_sequence_idx = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Check if deleting succeeds with dispatchers in different states */
 | 
				
			||||||
 | 
					  if (d1)
 | 
				
			||||||
 | 
					    dds_security_timed_dispatcher_free(tcb, d1);
 | 
				
			||||||
 | 
					  if (d2)
 | 
				
			||||||
 | 
					    dds_security_timed_dispatcher_free(tcb, d2);
 | 
				
			||||||
 | 
					  if (d3)
 | 
				
			||||||
 | 
					    dds_security_timed_dispatcher_free(tcb, d3);
 | 
				
			||||||
 | 
					  if (d4)
 | 
				
			||||||
 | 
					    dds_security_timed_dispatcher_free(tcb, d4);
 | 
				
			||||||
 | 
					  if (d5)
 | 
				
			||||||
 | 
					    dds_security_timed_dispatcher_free(tcb, d5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Wait for the callbacks to have been triggered. Ignore the ones in the far future. */
 | 
				
			||||||
 | 
					  n = 200;
 | 
				
			||||||
 | 
					  while (g_sequence_idx < 4 && n-- > 0)
 | 
				
			||||||
 | 
					    dds_sleepfor(DDS_MSECS(10));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /* Print and check sequence of triggered callbacks. */
 | 
				
			||||||
 | 
					  for (idx = 0; (idx < g_sequence_idx) && (idx < SEQ_SIZE); idx++)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    int seq = (int)(long long)(g_sequence_array[idx].arg);
 | 
				
			||||||
 | 
					    struct dds_security_timed_dispatcher_t *expected_d;
 | 
				
			||||||
 | 
					    if (seq == 99)
 | 
				
			||||||
 | 
					      expected_d = d4;
 | 
				
			||||||
 | 
					    else if (seq == 9 || seq == 11)
 | 
				
			||||||
 | 
					      expected_d = d3;
 | 
				
			||||||
 | 
					    else if (seq == 10)
 | 
				
			||||||
 | 
					      expected_d = d1;
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      expected_d = NULL;
 | 
				
			||||||
 | 
					      CU_FAIL_FATAL(sprintf("Unexpected sequence idx received %d", seq));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (idx > 4)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      CU_FAIL_FATAL(sprintf("Too many callbacks %d", idx));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Callback contents checks. */
 | 
				
			||||||
 | 
					    if (expected_d != NULL)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      if (g_sequence_array[idx].d != expected_d)
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        CU_FAIL_FATAL(sprintf("Unexpected dispatcher %p vs %p", g_sequence_array[idx].d, expected_d));
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (g_sequence_array[idx].listener != NULL)
 | 
				
			||||||
 | 
					      {
 | 
				
			||||||
 | 
					        CU_FAIL_FATAL(sprintf("Unexpected listener %p vs NULL", g_sequence_array[idx].listener));
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Callback kind check. */
 | 
				
			||||||
 | 
					    if (g_sequence_array[idx].kind != DDS_SECURITY_TIMED_CB_KIND_DELETE)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      CU_FAIL_FATAL(sprintf("Unexpected kind %d vs %d", (int)g_sequence_array[idx].kind, (int)DDS_SECURITY_TIMED_CB_KIND_TIMEOUT));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (g_sequence_idx < 4)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    CU_FAIL_FATAL(sprintf("Received %d callbacks, while 3 are expected", g_sequence_idx + 1));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  dds_security_timed_cb_free(tcb);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue