diff --git a/CHANGELOG.md b/CHANGELOG.md index 609fda1..10a646a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,8 +23,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - fix so that parodus can be killed, even if in a connection fail loop - provide signal handlers so we shut down properly when INCLUDE_BREAKPAD active - send status code and reason in websocket close message -- dont try to install handler for signal 9 -- add unit tests for interface down +- dont try to install handler for signal 9 +- on connect retry, requery jwt only if it failed before +- put two timestamps in connection health file; start conn and current +- change health file update interval to 240sec ## [1.0.2] - 2019-02-08 - Refactored connection.c and updated corresponding unit tests diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 01a3ece..0029f70 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -14,7 +14,7 @@ set(SOURCES main.c mutex.c networking.c nopoll_helpers.c heartBeat.c nopoll_handlers.c ParodusInternal.c string_helpers.c time.c config.c conn_interface.c connection.c spin_thread.c client_list.c service_alive.c - upstream.c downstream.c thread_tasks.c partners_check.c token.c + upstream.c downstream.c thread_tasks.c partners_check.c token.c event_handler.c crud_interface.c crud_tasks.c crud_internal.c close_retry.c auth_token.c) if (ENABLE_SESHAT) diff --git a/src/ParodusInternal.h b/src/ParodusInternal.h index 65eaab6..8d40716 100644 --- a/src/ParodusInternal.h +++ b/src/ParodusInternal.h @@ -108,6 +108,7 @@ typedef struct { //--- Used in connection.c for backoff delay timer typedef struct { + unsigned long start_time; struct timespec ts; int count; int max_count; @@ -126,7 +127,7 @@ typedef struct { // wait_connection_ready, and nopoll_connect typedef struct { noPollCtx *nopoll_ctx; - server_list_t server_list; + server_list_t *server_list; server_t *current_server; header_info_t header_info; char *extra_headers; // need to be freed diff --git a/src/conn_interface.c b/src/conn_interface.c index 097c780..52c12a4 100644 --- a/src/conn_interface.c +++ b/src/conn_interface.c @@ -33,6 +33,7 @@ #include "spin_thread.h" #include "service_alive.h" #include "seshat_interface.h" +#include "event_handler.h" #include "crud_interface.h" #include "heartBeat.h" #include "close_retry.h" @@ -73,6 +74,7 @@ void createSocketConnection(void (* initKeypress)()) { //ParodusCfg *tmpCfg = (ParodusCfg*)config_in; noPollCtx *ctx; + server_list_t server_list; bool seshat_registered = false; int create_conn_rtn = 0; unsigned int webpa_ping_timeout_ms = 1000 * get_parodus_cfg()->webpa_ping_timeout; @@ -95,9 +97,10 @@ void createSocketConnection(void (* initKeypress)()) nopoll_log_set_handler (ctx, __report_log, NULL); #endif - start_conn_in_progress (); - create_conn_rtn = createNopollConnection(ctx); - stop_conn_in_progress (); + EventHandler(); + + set_server_list_null (&server_list); + create_conn_rtn = createNopollConnection(ctx, &server_list); if(!create_conn_rtn) { ParodusError("Unrecovered error, terminating the process\n"); @@ -190,9 +193,7 @@ void createSocketConnection(void (* initKeypress)()) free(get_parodus_cfg()->cloud_disconnect); reset_cloud_disconnect_reason(get_parodus_cfg()); } - start_conn_in_progress (); - createNopollConnection(ctx); - stop_conn_in_progress (); + createNopollConnection(ctx, &server_list); } } while(!get_close_retry() && !g_shutdown); diff --git a/src/connection.c b/src/connection.c index 713b87e..b8a4d65 100644 --- a/src/connection.c +++ b/src/connection.c @@ -38,7 +38,7 @@ #define HTTP_CUSTOM_HEADER_COUNT 5 #define INITIAL_CJWT_RETRY -2 -#define UPDATE_HEALTH_FILE_INTERVAL_SECS 450 +#define UPDATE_HEALTH_FILE_INTERVAL_SECS 240 /* Close codes defined in RFC 6455, section 11.7. */ enum { @@ -233,6 +233,7 @@ void init_backoff_timer (backoff_timer_t *timer, int max_count) timer->max_count = max_count; timer->delay = 1; clock_gettime (CLOCK_REALTIME, &timer->ts); + timer->start_time = time(NULL); } void terminate_backoff_delay (void) @@ -256,7 +257,7 @@ int update_backoff_delay (backoff_timer_t *timer) #define BACKOFF_SHUTDOWN 1 #define BACKOFF_DELAY_TAKEN 0 -void start_conn_in_progress (void); +void start_conn_in_progress (unsigned long start_time); /* backoff_delay * @@ -267,7 +268,7 @@ void start_conn_in_progress (void); * 1 shutdown * 0 delay taken */ -int backoff_delay (backoff_timer_t *timer) +static int backoff_delay (backoff_timer_t *timer) { struct timespec ts; int rtn; @@ -275,7 +276,7 @@ int backoff_delay (backoff_timer_t *timer) // periodically update the health file. clock_gettime (CLOCK_REALTIME, &ts); if ((ts.tv_sec - timer->ts.tv_sec) >= UPDATE_HEALTH_FILE_INTERVAL_SECS) { - start_conn_in_progress (); + start_conn_in_progress (timer->start_time); timer->ts.tv_sec += UPDATE_HEALTH_FILE_INTERVAL_SECS; } @@ -373,7 +374,7 @@ char *build_extra_hdrs (header_info_t *header_info) //-------------------------------------------------------------------- void set_current_server (create_connection_ctx_t *ctx) { - ctx->current_server = get_current_server (&ctx->server_list); + ctx->current_server = get_current_server (ctx->server_list); } void free_extra_headers (create_connection_ctx_t *ctx) @@ -399,7 +400,8 @@ void free_connection_ctx (create_connection_ctx_t *ctx) { free_extra_headers (ctx); free_header_info (&ctx->header_info); - free_server_list (&ctx->server_list); + if (NULL != ctx->server_list) + free_server_list (ctx->server_list); } @@ -416,8 +418,10 @@ int find_servers (server_list_t *server_list) free_server_list (server_list); // parse default server URL - if (parse_server_url (get_parodus_cfg()->webpa_url, default_server) < 0) - return FIND_INVALID_DEFAULT; // must have valid default url + if (parse_server_url (get_parodus_cfg()->webpa_url, default_server) < 0) { + ParodusError ("Invalid Default URL\n"); + return FIND_INVALID_DEFAULT; + } ParodusInfo("default server_Address %s\n", default_server->server_addr); ParodusInfo("default port %u\n", default_server->port); #ifdef FEATURE_DNS_QUERY @@ -435,7 +439,6 @@ int find_servers (server_list_t *server_list) return FIND_SUCCESS; } - //-------------------------------------------------------------------- // connect to current server int nopoll_connect (create_connection_ctx_t *ctx, int is_ipv6) @@ -513,8 +516,8 @@ int wait_connection_ready (create_connection_ctx_t *ctx) // Extract server Address and port from the redirectURL if (strncmp (redirect_ptr, "Redirect:", 9) == 0) redirect_ptr += 9; - free_server (&ctx->server_list.redirect); - if (parse_server_url (redirect_ptr, &ctx->server_list.redirect) < 0) { + free_server (&ctx->server_list->redirect); + if (parse_server_url (redirect_ptr, &ctx->server_list->redirect) < 0) { ParodusError ("Redirect url error %s\n", redirectURL); free (redirectURL); return WAIT_FAIL; @@ -543,7 +546,7 @@ int wait_connection_ready (create_connection_ctx_t *ctx) // Return codes for connect_and_wait #define CONN_WAIT_SUCCESS 0 #define CONN_WAIT_ACTION_RETRY 1 // if wait_status is 307, 302, 303, or 403 -#define CONN_WAIT_RETRY_DNS 2 +#define CONN_WAIT_FAIL 2 int connect_and_wait (create_connection_ctx_t *ctx) { @@ -587,7 +590,7 @@ int connect_and_wait (create_connection_ctx_t *ctx) continue; } - return CONN_WAIT_RETRY_DNS; + return CONN_WAIT_FAIL; } } @@ -615,7 +618,7 @@ int keep_trying_to_connect (create_connection_ctx_t *ctx, if(get_interface_down_event()) { if (0 != wait_while_interface_down()) return false; - start_conn_in_progress(); + start_conn_in_progress(backoff_timer->start_time); ParodusInfo("Interface is back up, re-initializing the convey header\n"); // Reset the reconnect reason by initializing the convey header again ((header_info_t *)(&ctx->header_info))->conveyHeader = getWebpaConveyHeader(); @@ -625,8 +628,9 @@ int keep_trying_to_connect (create_connection_ctx_t *ctx, != BACKOFF_DELAY_TAKEN) // shutdown or cond wait error return false; } - if (rtn == CONN_WAIT_RETRY_DNS) - return false; //find_server again + if (rtn == CONN_WAIT_FAIL) { + return false; + } // else retry } return false; @@ -661,11 +665,10 @@ int wait_while_interface_down() * @brief createNopollConnection interface to create WebSocket client connections. *Loads the WebPA config file and creates the intial connection and manages the connection wait, close mechanisms. */ -int createNopollConnection(noPollCtx *ctx) +int createNopollConnection(noPollCtx *ctx, server_list_t *server_list) { create_connection_ctx_t conn_ctx; int max_retry_count; - int query_dns_status; struct timespec connect_time,*connectTimePtr; connectTimePtr = &connect_time; backoff_timer_t backoff_timer; @@ -685,18 +688,33 @@ int createNopollConnection(noPollCtx *ctx) conn_ctx.nopoll_ctx = ctx; init_expire_timer (&conn_ctx.connect_timer); init_header_info (&conn_ctx.header_info); - set_server_list_null (&conn_ctx.server_list); - init_backoff_timer (&backoff_timer, max_retry_count); + /* look up server information if we don't already have it */ + if (server_is_null (&server_list->defaults)) + if (find_servers (server_list) == FIND_INVALID_DEFAULT) { + return nopoll_false; + } + conn_ctx.server_list = server_list; + init_backoff_timer (&backoff_timer, max_retry_count); + start_conn_in_progress (backoff_timer.start_time); while (!g_shutdown) { - query_dns_status = find_servers (&conn_ctx.server_list); - if (query_dns_status == FIND_INVALID_DEFAULT) - return nopoll_false; set_current_server (&conn_ctx); - if (keep_trying_to_connect (&conn_ctx, &backoff_timer)) + if (keep_trying_to_connect (&conn_ctx, &backoff_timer)) { + // Don't reuse the redirect server during reconnect + free_server (&conn_ctx.server_list->redirect); break; - // retry dns query + } + /* if we failed to connect, don't reuse the redirect server */ + free_server (&conn_ctx.server_list->redirect); +#ifdef FEATURE_DNS_QUERY + /* if we don't already have a valid jwt, look up server information */ + if (server_is_null (&conn_ctx.server_list->jwt)) + if (find_servers (conn_ctx.server_list) == FIND_INVALID_DEFAULT) { + /* since we already found a default server, we don't expect FIND_INVALID_DEFAULT */ + g_shutdown = true; + } +#endif } if(conn_ctx.current_server->allow_insecure <= 0) @@ -726,8 +744,7 @@ int createNopollConnection(noPollCtx *ctx) } free_extra_headers (&conn_ctx); - free_header_info (&conn_ctx.header_info); - free_server_list (&conn_ctx.server_list); + free_header_info (&conn_ctx.header_info); // Reset close_retry flag and heartbeatTimer once the connection retry is successful ParodusPrint("createNopollConnection(): reset_close_retry\n"); @@ -737,7 +754,7 @@ int createNopollConnection(noPollCtx *ctx) set_global_reconnect_status(false); ParodusPrint("LastReasonStatus reset after successful connection\n"); setMessageHandlers(); - + stop_conn_in_progress (); return nopoll_true; } @@ -804,7 +821,7 @@ void close_and_unref_connection(noPollConn *conn) } } -void write_conn_in_prog_file (const char *msg) +void write_conn_in_prog_file (bool is_starting, unsigned long start_time) { int fd; FILE *fp; @@ -825,18 +842,22 @@ void write_conn_in_prog_file (const char *msg) return; } timestamp = (unsigned long) time(NULL); - fprintf (fp, "{%s=%lu}\n", msg, timestamp); + if (is_starting) + fprintf (fp, "{START=%lu,%lu}\n", start_time, timestamp); + else + fprintf (fp, "{STOP=%lu}\n", timestamp); + fclose (fp); } -void start_conn_in_progress (void) +void start_conn_in_progress (unsigned long start_time) { - write_conn_in_prog_file ("START"); + write_conn_in_prog_file (true, start_time); } void stop_conn_in_progress (void) { - write_conn_in_prog_file ("STOP"); + write_conn_in_prog_file (false, 0); } diff --git a/src/connection.h b/src/connection.h index 2e5dfbd..3bb049a 100644 --- a/src/connection.h +++ b/src/connection.h @@ -49,7 +49,8 @@ parodusOnPingStatusChangeHandler on_ping_status_change; /* Function Prototypes */ /*----------------------------------------------------------------------------*/ -int createNopollConnection(noPollCtx *); +void set_server_list_null (server_list_t *server_list); +int createNopollConnection(noPollCtx *, server_list_t *); /** * @brief Interface to terminate WebSocket client connections and clean up resources. @@ -74,7 +75,7 @@ void set_cloud_disconnect_time(int disconnTime); /** * @brief Interface to self heal connection in progress getting stuck */ -void start_conn_in_progress (void); +void start_conn_in_progress (unsigned long start_time); void stop_conn_in_progress (void); // To Register parodusOnPingStatusChangeHandler Callback function diff --git a/src/event_handler.c b/src/event_handler.c new file mode 100644 index 0000000..fd26ec3 --- /dev/null +++ b/src/event_handler.c @@ -0,0 +1,26 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2016 RDK Management + * Copyright [2014] [Cisco Systems, Inc.] + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/* This is a stub file that will be overridden in a patch */ + +#include "event_handler.h" + +void EventHandler() +{ +} diff --git a/src/event_handler.h b/src/event_handler.h new file mode 100644 index 0000000..60b0f9c --- /dev/null +++ b/src/event_handler.h @@ -0,0 +1,21 @@ +/* + * If not stated otherwise in this file or this component's Licenses.txt file the + * following copyright and licenses apply: + * + * Copyright 2016 RDK Management + * Copyright [2014] [Cisco Systems, Inc.] + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +void EventHandler(); +#define LOGGING_INTERVAL_SECS ( 60 * 60 ) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9117421..0c594ff 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -16,7 +16,9 @@ set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -W -g -fprofile-arcs -ftest-coverage set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DTEST ") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -W -g -fprofile-arcs -ftest-coverage -O0") set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage -O0") -set (PARODUS_COMMON_SRC ../src/string_helpers.c ../src/mutex.c ../src/time.c ../src/config.c ../src/spin_thread.c ../src/token.c) +set (PARODUS_COMMON_SRC ../src/string_helpers.c ../src/mutex.c + ../src/time.c ../src/config.c ../src/spin_thread.c + ../src/event_handler.c ../src/token.c) set (PARODUS_COMMON_LIBS gcov -lcunit -lcimplog -lwrp-c -luuid -lmsgpackc -lnopoll -lnanomsg -lpthread -Wl,--no-as-needed -lcjson -lcjwt -ltrower-base64 @@ -283,6 +285,7 @@ set(CONIFC_SRC test_conn_interface.c ../src/mutex.c ../src/heartBeat.c ../src/close_retry.c + ../src/event_handler.c ) if (ENABLE_SESHAT) set(CONIFC_SRC ${CONIFC_SRC} ../src/seshat_interface.c) @@ -320,7 +323,7 @@ set(TOKEN_SRC ../src/conn_interface.c ../src/config.c ../src/thread_tasks.c ../src/time.c ../src/string_helpers.c ../src/mutex.c ../src/token.c ../src/heartBeat.c - ../src/close_retry.c + ../src/close_retry.c ../src/event_handler.c ) if (ENABLE_SESHAT) diff --git a/tests/test_conn_interface.c b/tests/test_conn_interface.c index 30440d6..e149798 100644 --- a/tests/test_conn_interface.c +++ b/tests/test_conn_interface.c @@ -47,9 +47,20 @@ pthread_cond_t svc_con=PTHREAD_COND_INITIALIZER; /*----------------------------------------------------------------------------*/ /* Mocks */ /*----------------------------------------------------------------------------*/ -int createNopollConnection(noPollCtx *ctx) +void set_server_list_null (server_list_t *server_list) { - UNUSED(ctx); + UNUSED(server_list); +} + +int find_servers (server_list_t *server_list) +{ + UNUSED(server_list); + return FIND_SUCCESS; +} + +int createNopollConnection(noPollCtx *ctx, server_list_t *server_list) +{ + UNUSED(ctx); UNUSED(server_list); function_called(); return (int) mock(); } @@ -91,8 +102,9 @@ void set_global_shutdown_reason(char *reason) UNUSED(reason); } -void start_conn_in_progress (void) +void start_conn_in_progress (unsigned long start_time) { + UNUSED(start_time); } void stop_conn_in_progress (void) diff --git a/tests/test_connection.c b/tests/test_connection.c index 1adc464..bca9dbb 100644 --- a/tests/test_connection.c +++ b/tests/test_connection.c @@ -15,14 +15,12 @@ */ #include -#include #include #include #include #include #include #include -#include #include #include @@ -39,7 +37,6 @@ extern void init_expire_timer (expire_timer_t *timer); extern int check_timer_expired (expire_timer_t *timer, long timeout_ms); extern void init_backoff_timer (backoff_timer_t *timer, int max_count); extern int update_backoff_delay (backoff_timer_t *timer); -extern int backoff_delay (backoff_timer_t *timer); extern int init_header_info (header_info_t *header_info); extern void free_header_info (header_info_t *header_info); extern char *build_extra_hdrs (header_info_t *header_info); @@ -398,16 +395,19 @@ void test_extra_headers () void test_set_current_server() { + server_list_t server_list; create_connection_ctx_t ctx; - memset (&ctx, 0xFF, sizeof(ctx)); + memset (&server_list, 0xFF, sizeof(server_list)); + memset (&ctx, 0, sizeof(ctx)); + ctx.server_list = &server_list; set_current_server (&ctx); - assert_ptr_equal (&ctx.server_list.redirect, ctx.current_server); - set_server_null (&ctx.server_list.redirect); + assert_ptr_equal (&ctx.server_list->redirect, ctx.current_server); + set_server_null (&ctx.server_list->redirect); set_current_server (&ctx); - assert_ptr_equal (&ctx.server_list.jwt, ctx.current_server); - set_server_null (&ctx.server_list.jwt); + assert_ptr_equal (&ctx.server_list->jwt, ctx.current_server); + set_server_null (&ctx.server_list->jwt); set_current_server (&ctx); - assert_ptr_equal (&ctx.server_list.defaults, ctx.current_server); + assert_ptr_equal (&ctx.server_list->defaults, ctx.current_server); } void init_cfg_header_info (ParodusCfg *cfg) @@ -623,10 +623,12 @@ void test_nopoll_connect () void test_wait_connection_ready () { + server_list_t server_list; create_connection_ctx_t ctx; + set_server_list_null (&server_list); memset(&ctx,0,sizeof(ctx)); - set_server_list_null (&ctx.server_list); + ctx.server_list = &server_list; mock_wait_status = 0; mock_redirect = NULL; @@ -655,22 +657,22 @@ void test_wait_connection_ready () will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_false); expect_function_call (nopoll_conn_wait_for_status_until_connection_ready); assert_int_equal (wait_connection_ready (&ctx), WAIT_ACTION_RETRY); - assert_string_equal (ctx.server_list.redirect.server_addr, "mydns.mycom.net"); - assert_int_equal (ctx.server_list.redirect.port, 8080); - assert_int_equal (0, ctx.server_list.redirect.allow_insecure); - assert_ptr_equal (ctx.current_server, &ctx.server_list.redirect); - free_server (&ctx.server_list.redirect); + assert_string_equal (ctx.server_list->redirect.server_addr, "mydns.mycom.net"); + assert_int_equal (ctx.server_list->redirect.port, 8080); + assert_int_equal (0, ctx.server_list->redirect.allow_insecure); + assert_ptr_equal (ctx.current_server, &ctx.server_list->redirect); + free_server (&ctx.server_list->redirect); mock_wait_status = 303; mock_redirect = "http://mydns.mycom.net"; will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_false); expect_function_call (nopoll_conn_wait_for_status_until_connection_ready); assert_int_equal (wait_connection_ready (&ctx), WAIT_ACTION_RETRY); - assert_string_equal (ctx.server_list.redirect.server_addr, "mydns.mycom.net"); - assert_int_equal (ctx.server_list.redirect.port, 80); - assert_int_equal (1, ctx.server_list.redirect.allow_insecure); - assert_ptr_equal (ctx.current_server, &ctx.server_list.redirect); - free_server (&ctx.server_list.redirect); + assert_string_equal (ctx.server_list->redirect.server_addr, "mydns.mycom.net"); + assert_int_equal (ctx.server_list->redirect.port, 80); + assert_int_equal (1, ctx.server_list->redirect.allow_insecure); + assert_ptr_equal (ctx.current_server, &ctx.server_list->redirect); + free_server (&ctx.server_list->redirect); mock_wait_status = 403; will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_false); @@ -688,6 +690,7 @@ void test_wait_connection_ready () void test_connect_and_wait () { + server_list_t server_list; create_connection_ctx_t ctx; noPollCtx test_nopoll_ctx; server_t test_server; @@ -704,7 +707,9 @@ void test_connect_and_wait () mock_wait_status = 0; + set_server_list_null (&server_list); memset(&ctx,0,sizeof(ctx)); + ctx.server_list = &server_list; ctx.nopoll_ctx = &test_nopoll_ctx; ctx.current_server = &test_server; ctx.extra_headers = test_extra_headers; @@ -819,9 +824,9 @@ void test_connect_and_wait () void test_keep_trying () { int rtn; + server_list_t server_list; create_connection_ctx_t ctx; noPollCtx test_nopoll_ctx; - server_t test_server; backoff_timer_t backoff_timer; ParodusCfg Cfg; @@ -831,14 +836,16 @@ void test_keep_trying () mock_wait_status = 0; + set_server_list_null (&server_list); memset(&ctx,0,sizeof(ctx)); + ctx.server_list = &server_list; ctx.nopoll_ctx = &test_nopoll_ctx; - ctx.current_server = &test_server; - - test_server.allow_insecure = 1; - test_server.server_addr = "mydns.mycom.net"; - test_server.port = 8080; + server_list.defaults.allow_insecure = 1; + server_list.defaults.server_addr = "mydns.mycom.net"; + server_list.defaults.port = 8080; + set_current_server (&ctx); + Cfg.flags = 0; set_parodus_cfg(&Cfg); @@ -852,7 +859,7 @@ void test_keep_trying () rtn = keep_trying_to_connect (&ctx, &backoff_timer); assert_int_equal (rtn, true); - test_server.allow_insecure = 0; + server_list.defaults.allow_insecure = 0; Cfg.flags = FLAGS_IPV4_ONLY; set_parodus_cfg(&Cfg); @@ -919,9 +926,12 @@ void test_create_nopoll_connection() { int rtn; ParodusCfg cfg; + server_list_t server_list; noPollCtx test_nopoll_ctx; + set_server_list_null (&server_list); memset(&cfg,0,sizeof(cfg)); + cfg.flags = 0; parStrncpy (cfg.webpa_url, "mydns.mycom.net:8080", sizeof(cfg.webpa_url)); cfg.boot_time = 25; @@ -934,11 +944,12 @@ void test_create_nopoll_connection() parStrncpy(cfg.fw_name , "2.364s2", sizeof(cfg.fw_name)); parStrncpy(cfg.webpa_protocol , "WebPA-1.6", sizeof(cfg.webpa_protocol)); set_parodus_cfg(&cfg); - rtn = createNopollConnection (&test_nopoll_ctx); + rtn = createNopollConnection (&test_nopoll_ctx, &server_list); assert_int_equal (rtn, nopoll_false); parStrncpy (cfg.webpa_url, "http://mydns.mycom.net:8080", sizeof(cfg.webpa_url)); set_parodus_cfg(&cfg); + set_server_list_null (&server_list); mock_wait_status = 0; @@ -948,12 +959,13 @@ void test_create_nopoll_connection() expect_function_call (nopoll_conn_is_ok); will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_true); expect_function_call (nopoll_conn_wait_for_status_until_connection_ready); - rtn = createNopollConnection (&test_nopoll_ctx); + rtn = createNopollConnection (&test_nopoll_ctx, &server_list); assert_int_equal (rtn, nopoll_true); parStrncpy (cfg.webpa_url, "https://mydns.mycom.net:8080", sizeof(cfg.webpa_url)); cfg.flags = 0; set_parodus_cfg(&cfg); + set_server_list_null (&server_list); will_return (nopoll_conn_tls_new6, &connection1); expect_function_call (nopoll_conn_tls_new6); @@ -965,9 +977,11 @@ void test_create_nopoll_connection() expect_function_call (nopoll_conn_is_ok); will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_true); expect_function_call (nopoll_conn_wait_for_status_until_connection_ready); - rtn = createNopollConnection (&test_nopoll_ctx); + rtn = createNopollConnection (&test_nopoll_ctx, &server_list); assert_int_equal (rtn, nopoll_true); + set_server_list_null (&server_list); + will_return (nopoll_conn_tls_new6, &connection1); expect_function_call (nopoll_conn_tls_new6); will_return (nopoll_conn_is_ok, nopoll_false); @@ -992,13 +1006,14 @@ void test_create_nopoll_connection() mock_wait_status = 0; will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_true); expect_function_call (nopoll_conn_wait_for_status_until_connection_ready); - rtn = createNopollConnection (&test_nopoll_ctx); + rtn = createNopollConnection (&test_nopoll_ctx, &server_list); assert_int_equal (rtn, nopoll_true); #ifdef FEATURE_DNS_QUERY cfg.acquire_jwt = 1; cfg.flags = FLAGS_IPV4_ONLY; set_parodus_cfg(&cfg); + set_server_list_null (&server_list); will_return (allow_insecure_conn, -1); expect_function_call (allow_insecure_conn); @@ -1016,11 +1031,32 @@ void test_create_nopoll_connection() expect_function_call (nopoll_conn_is_ok); will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_true); expect_function_call (nopoll_conn_wait_for_status_until_connection_ready); - rtn = createNopollConnection (&test_nopoll_ctx); + rtn = createNopollConnection (&test_nopoll_ctx, &server_list); assert_int_equal (rtn, nopoll_true); + set_server_list_null (&server_list); + mock_server_addr = "mydns.myjwtcom.net"; + mock_port = 80; + will_return (allow_insecure_conn, 0); + expect_function_call (allow_insecure_conn); + will_return (nopoll_conn_tls_new, &connection1); + expect_function_call (nopoll_conn_tls_new); + will_return (nopoll_conn_is_ok, nopoll_true); + expect_function_call (nopoll_conn_is_ok); + will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_false); + expect_function_call (nopoll_conn_wait_for_status_until_connection_ready); + will_return (nopoll_conn_tls_new, &connection1); + expect_function_call (nopoll_conn_tls_new); + will_return (nopoll_conn_is_ok, nopoll_true); + expect_function_call (nopoll_conn_is_ok); + will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_true); + expect_function_call (nopoll_conn_wait_for_status_until_connection_ready); + rtn = createNopollConnection (&test_nopoll_ctx, &server_list); + assert_int_equal (rtn, nopoll_true); + cfg.flags = 0; set_parodus_cfg(&cfg); + set_server_list_null (&server_list); will_return (allow_insecure_conn, -1); expect_function_call (allow_insecure_conn); @@ -1035,76 +1071,18 @@ void test_create_nopoll_connection() expect_function_call (nopoll_conn_is_ok); will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_true); expect_function_call (nopoll_conn_wait_for_status_until_connection_ready); - rtn = createNopollConnection (&test_nopoll_ctx); + rtn = createNopollConnection (&test_nopoll_ctx, &server_list); assert_int_equal (rtn, nopoll_true); #endif } -#define BACKOFF_ERR -1 -#define BACKOFF_SHUTDOWN 1 -#define BACKOFF_DELAY_TAKEN 0 - -backoff_timer_t test_timer; - -void *c() -{ - sleep (5); - g_shutdown = true; - terminate_backoff_delay (); - pthread_exit(0); - return NULL; -} - -void test_backoff_delay () -{ - int rtn; - pthread_t thread_c; - - init_backoff_timer (&test_timer, 5); - rtn = backoff_delay (&test_timer); // delay will be 3 - assert_int_equal (rtn, BACKOFF_DELAY_TAKEN); - - update_backoff_delay (&test_timer); // delay will be 7 - pthread_create(&thread_c, NULL, c, NULL); - rtn = backoff_delay (&test_timer); // delay will be 15 - assert_int_equal (rtn, BACKOFF_SHUTDOWN); - g_shutdown = false; -} - void test_get_interface_down_event() { assert_false(get_interface_down_event()); set_interface_down_event(); } -void *b(void *arg) -{ - sleep(5); - if (arg) - g_shutdown = true; - reset_interface_down_event(); - pthread_exit(0); - return NULL; -} - -void test_wait_while_interface_down() -{ - int rtn; - pthread_t thread_b; - - set_interface_down_event (); - pthread_create(&thread_b, NULL, b, NULL); - rtn = wait_while_interface_down (); - assert_int_equal (rtn, 0); - - set_interface_down_event (); - pthread_create(&thread_b, NULL, b, &rtn); - rtn = wait_while_interface_down (); - assert_int_equal (rtn, -1); - g_shutdown = false; -} - void *a() { sleep(15); @@ -1119,6 +1097,7 @@ void test_interface_down_retry() int rtn; ParodusCfg cfg; noPollCtx test_nopoll_ctx; + server_list_t server_list; pthread_t thread_a; pthread_create(&thread_a, NULL, a, NULL); @@ -1136,7 +1115,8 @@ void test_interface_down_retry() parStrncpy(cfg.fw_name , "2.364s2", sizeof(cfg.fw_name)); parStrncpy(cfg.webpa_protocol , "WebPA-1.6", sizeof(cfg.webpa_protocol)); set_parodus_cfg(&cfg); - rtn = createNopollConnection (&test_nopoll_ctx); + set_server_list_null (&server_list); + rtn = createNopollConnection (&test_nopoll_ctx, &server_list); assert_int_equal (rtn, nopoll_false); parStrncpy (cfg.webpa_url, "http://mydns.mycom.net:8080", sizeof(cfg.webpa_url)); @@ -1150,7 +1130,8 @@ void test_interface_down_retry() expect_function_call (nopoll_conn_is_ok); will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_true); expect_function_call (nopoll_conn_wait_for_status_until_connection_ready); - rtn = createNopollConnection (&test_nopoll_ctx); + set_server_list_null (&server_list); + rtn = createNopollConnection (&test_nopoll_ctx, &server_list); assert_int_equal (rtn, nopoll_true); parStrncpy (cfg.webpa_url, "https://mydns.mycom.net:8080", sizeof(cfg.webpa_url)); @@ -1167,7 +1148,8 @@ void test_interface_down_retry() expect_function_call (nopoll_conn_is_ok); will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_true); expect_function_call (nopoll_conn_wait_for_status_until_connection_ready); - rtn = createNopollConnection (&test_nopoll_ctx); + set_server_list_null (&server_list); + rtn = createNopollConnection (&test_nopoll_ctx, &server_list); assert_int_equal (rtn, nopoll_true); will_return (nopoll_conn_tls_new6, &connection1); @@ -1194,7 +1176,8 @@ void test_interface_down_retry() mock_wait_status = 0; will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_true); expect_function_call (nopoll_conn_wait_for_status_until_connection_ready); - rtn = createNopollConnection (&test_nopoll_ctx); + set_server_list_null (&server_list); + rtn = createNopollConnection (&test_nopoll_ctx, &server_list); assert_int_equal (rtn, nopoll_true); #ifdef FEATURE_DNS_QUERY @@ -1218,7 +1201,8 @@ void test_interface_down_retry() expect_function_call (nopoll_conn_is_ok); will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_true); expect_function_call (nopoll_conn_wait_for_status_until_connection_ready); - rtn = createNopollConnection (&test_nopoll_ctx); + set_server_list_null (&server_list); + rtn = createNopollConnection (&test_nopoll_ctx, &server_list); assert_int_equal (rtn, nopoll_true); cfg.flags = 0; @@ -1237,7 +1221,8 @@ void test_interface_down_retry() expect_function_call (nopoll_conn_is_ok); will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_true); expect_function_call (nopoll_conn_wait_for_status_until_connection_ready); - rtn = createNopollConnection (&test_nopoll_ctx); + set_server_list_null (&server_list); + rtn = createNopollConnection (&test_nopoll_ctx, &server_list); assert_int_equal (rtn, nopoll_true); #endif pthread_join(thread_a, NULL); @@ -1269,9 +1254,7 @@ int main(void) cmocka_unit_test(test_wait_connection_ready), cmocka_unit_test(test_connect_and_wait), cmocka_unit_test(test_keep_trying), - cmocka_unit_test(test_create_nopoll_connection), - cmocka_unit_test (test_backoff_delay), - cmocka_unit_test (test_wait_while_interface_down), + cmocka_unit_test(test_create_nopoll_connection), cmocka_unit_test(test_get_interface_down_event), cmocka_unit_test(test_interface_down_retry) };