Compare commits

...

76 Commits

Author SHA1 Message Date
Shilpa Seshadri
4671d2efa0 To fix memory leak in upstream event message flow 2019-01-04 14:30:09 -08:00
shilpa24balaji
b48680c358 Merge pull request #265 from bill1600/backoff
Backoff
2018-12-11 15:15:30 -08:00
shilpa24balaji
2304951186 Merge pull request #266 from Comcast/partner_crash
Added NULL check in validate_partner_id
2018-12-11 14:25:00 -08:00
Bill Williams
85004c165c use max count not max delay time for backoff 2018-12-11 10:01:53 -08:00
Bill Williams
94b64af4a0 update changelog 2018-12-10 16:31:13 -08:00
Bill Williams
d190b8b10c backoff retry to include find_servers in loop 2018-12-10 16:29:30 -08:00
Shilpa Seshadri
4e24197d24 Added NULL check in validate_partner_id 2018-12-09 23:04:55 -08:00
shilpa24balaji
f4d544fc40 Merge pull request #263 from Comcast/mac_null
Added mac id null check in upstream retrieve message handling
2018-12-04 17:49:15 -08:00
Shilpa Seshadri
0972ff76fd Fixed unit tests and updated change log 2018-12-04 16:03:53 -08:00
shilpa24balaji
ae8a9beb8e Merge pull request #262 from vathikar/Mac_null
Added Code and  Test cases fot NULL check for MAC
2018-12-04 17:36:38 -08:00
Weston Schmidt
08ed64c822 Merge pull request #260 from Comcast/time_diff
Added log for time difference in connect time and boot time
2018-12-04 15:01:27 -08:00
vathikar
f0f2903106 Added Code and Test cases fot NULL check for MAC 2018-11-30 15:30:52 +05:30
Shilpa Seshadri
8c83c4ce01 Added log for time difference in connect time and boot time 2018-11-29 21:59:00 -08:00
shilpa24balaji
385a38f10a Merge pull request #259 from Comcast/tags
Update CMake git tags
2018-11-21 18:53:49 -08:00
Shilpa Seshadri
4abad4dc13 Reverting to old nanomsg to fix cmake error 2018-11-21 18:14:29 -08:00
Shilpa Seshadri
cbe184e00e Use git tag version instead of commit hash and fix unit tests 2018-11-21 17:54:43 -08:00
shilpa24balaji
25a6a6cc72 Merge pull request #257 from bill1600/revert_temp_ref_to_bill1600_seshat
revert temporary CMake reference to bill1600/seshat
2018-11-15 17:13:50 -08:00
Bill Williams
aabe6be96a revert temporary CMake reference to bill1600/seshat 2018-11-14 09:49:42 -08:00
shilpa24balaji
9aa18cea1c Merge pull request #253 from vathikar/master
Added NULL check for MAC
2018-11-12 12:51:17 -08:00
shilpa24balaji
2f762fe9a1 Merge pull request #256 from bill1600/revert_from_NNG
revert from NNG
2018-11-12 12:38:46 -08:00
shilpa24balaji
93363b35db Update CHANGELOG.md 2018-11-12 12:10:30 -08:00
Bill Williams
7e8edcaca4 revert from NNG 2018-11-12 11:55:01 -08:00
shilpa24balaji
81290ffd84 Merge pull request #251 from gbuddappagari/change_log
Modify changelog for partnerid change
2018-11-09 22:38:06 -08:00
vathikar
8a69bc3955 Added NULL check for MAC 2018-11-07 13:11:56 +05:30
Gayathri
3634aa0a70 Modify changelog for partnerid change 2018-10-25 16:38:36 +05:30
Weston Schmidt
08a09106cf Merge pull request #248 from Comcast/partner_icase
Partner-id comparison made case insensitive
2018-10-17 11:46:55 -07:00
Shilpa Seshadri
f730a41cdb Partner-id comparison made case insensitive 2018-10-16 23:34:29 -07:00
shilpa24balaji
f79eeb066a Merge pull request #247 from bill1600/5xx_tweak
add unit test for 503
2018-10-08 14:27:53 -07:00
shilpa24balaji
b4a8d8b2da Merge branch 'master' into 5xx_tweak 2018-10-08 14:13:50 -07:00
Bill Williams
b42051bf96 Updated change log for the connection retry change 2018-10-08 13:48:02 -07:00
shilpa24balaji
cd1d1ba52b Merge pull request #245 from Comcast/mem_fix
Memory leak fixes
2018-10-08 13:41:55 -07:00
Bill Williams
44554b0dfa add unit test for 503 2018-10-08 11:26:32 -07:00
Shilpa Seshadri
1addffdeb0 Memory leak fixes 2018-10-05 16:20:18 -07:00
shilpa24balaji
ce0c43d894 Merge pull request #242 from bill1600/nng_compat
switch from nanomsg to NNG
2018-10-05 12:01:34 -07:00
Bill Williams
4f1952ddcc Fix travis build by changing link order in tests/CMakeLists.txt 2018-10-05 10:55:51 -07:00
Bill Williams
eda3823ef0 Change CMakeLists.txt to use Comcast versions of seshat and libparodus 2018-10-05 07:57:27 -07:00
Bill Williams
774f308680 use NNG release v1.0.1 2018-10-04 15:09:04 -07:00
Bill Williams
130d8f2933 switch from nanomsg to NNG 2018-10-02 16:56:26 -07:00
shilpa24balaji
5f1650b009 Merge pull request #240 from sadhyama/close-retry
Fix parodus crash while sending notification to server
2018-09-25 00:22:47 -07:00
Sadhyama Vengilat
5cf95ac1ab Updated comment 2018-09-25 11:21:40 +05:30
Sadhyama Vengilat
c1e1a8ebdc Added unit tests for close_retry changes 2018-09-21 20:00:04 +05:30
Sadhyama Vengilat
d82c9ea187 Fix parodus crash while sending notification during connection retry 2018-09-21 19:51:22 +05:30
Sadhyama Vengilat
4562592536 Protect close_retry using mutex locks 2018-09-21 19:45:20 +05:30
Weston Schmidt
cdd333cc3a Merge pull request #238 from gbuddappagari/master
Used wrp_does_service_match() API to fix #236
2018-09-07 01:54:20 -07:00
Gayathri
7ae1d2a1c4 Used wrp_does_service_match() API to fix #236 2018-09-06 14:22:03 +05:30
Weston Schmidt
ed1ff2b105 Merge pull request #237 from gbuddappagari/master
To fix crash observed in #236 issue
2018-09-05 11:28:58 -07:00
Gayathri
166b7ec7c2 To fix crash observed in #236 issue 2018-09-05 16:29:06 +05:30
shilpa24balaji
97ac941a81 Merge pull request #234 from gbuddappagari/master
Modified validation logic for boot-time
2018-08-24 16:58:46 -07:00
Gayathri
844a1d925a Modified validation logic for boot-time 2018-08-20 18:16:46 +05:30
Weston Schmidt
ba690db3a1 Merge pull request #233 from sadhyama/master
To fix issue of WRP_MSG_TYPE__REQ response is not sending to server
2018-08-17 08:54:17 -07:00
Sadhyama Vengilat
a8d077dbf5 To fix issue of WRP_MSG_TYPE__REQ response is not sending to server 2018-08-17 18:51:41 +05:30
Weston Schmidt
2c3b8fc994 Merge pull request #230 from gbuddappagari/master
Allow a wildcard partner-id to match everything. #225
2018-08-07 07:12:47 -07:00
shilpa24balaji
35509cd5b2 Merge pull request #232 from bill1600/refactor_conn
Refactor conn
2018-08-06 00:16:50 -07:00
Bill Williams
4f74bc037d merge upstream.c and crud_internal.c 2018-08-03 09:29:02 -07:00
Bill Williams
9e3b32af69 refactored connection.c 2018-08-03 08:20:03 -07:00
shilpa24balaji
8a20d3a7c4 Merge pull request #231 from sadhyama/master
Changes to use modified wrp-c function for source/dest parsing
2018-08-02 21:29:00 -07:00
shilpa24balaji
19a0bc26af Merge pull request #229 from mrigaya/master
Add unit tests for heartBeat.c
2018-08-02 15:49:30 -07:00
Gayathri
558f007bdf Added comments 2018-08-02 10:53:35 +05:30
Sadhyama Vengilat
2ba26b37dc Changes to use modified wrp-c function for source/dest parsing 2018-07-31 11:04:45 +05:30
Weston Schmidt
da924e89a5 Merge pull request #228 from sadhyama/additional-fields
Added additional CRUD fields #208
2018-07-30 00:02:20 -07:00
Gayathri
6a1d908407 Avoiding triple pointer to get list of partner_ids 2018-07-27 13:14:34 +05:30
Gayathri
7b496769fc Returing with 403 error on mismatch of partner_id 2018-07-27 12:50:52 +05:30
Gayathri
1e05869ded To validate array of partner_ids 2018-07-26 18:26:27 +05:30
Gayathri
e7bf8cf468 Parse comma(,) separated partner_id to get partner_ids list 2018-07-26 17:15:28 +05:30
Sadhyama Vengilat
e40af91fa7 Incorporated review comments on crud additional fields 2018-07-25 18:25:58 +05:30
Sadhyama Vengilat
f88a3f11cc Merge remote-tracking branch 'upstream/master' into additional-fields 2018-07-25 18:12:04 +05:30
mrigaya
db07521d64 Add unit tests for heartBeat.c 2018-07-25 12:23:42 +05:30
Weston Schmidt
eb0281128d Merge pull request #227 from selvamKrish/ipv6_review_comment
Abort parodus process for invalid webpa url
2018-07-24 08:46:17 -07:00
Sadhyama Vengilat
7432b6f9fb Unit test cases for cloud-disconnect handling 2018-07-24 19:10:16 +05:30
Sadhyama Vengilat
db70ecf934 Unit test cases for cloud-status handling 2018-07-24 18:32:29 +05:30
Sadhyama Vengilat
c49a14cb00 Handled cloud-status retrieve requests from internal libparodus clients 2018-07-24 18:16:36 +05:30
Sadhyama Vengilat
b7e486994f Added crud field cloud-disconnect and handled cloud UPDATE request 2018-07-24 17:53:21 +05:30
Sadhyama Vengilat
9831cefd52 Added crud field cloud-status and handled cloud retrieve request 2018-07-24 17:39:27 +05:30
skrishnamoorthy01
ff7472be5d Abort the parodus process for invalid webpa url 2018-07-24 14:50:26 +05:30
Weston Schmidt
6f36fb7861 Merge pull request #226 from selvamKrish/ipv6_parsing
Fix to parse webpa-url IPv6 address properly #224
2018-07-23 10:04:54 -07:00
skrishnamoorthy01
d8b009b5d0 Fix to parse webpa-url IPv6 address properly #224 2018-07-23 18:02:10 +05:30
43 changed files with 3364 additions and 1078 deletions

View File

@@ -5,8 +5,19 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
## [Unreleased]
- Refactor of connection code (simplification).
- Refactored connection.c and updated corresponding unit tests
- Additional `/cloud-status` and `/cloud-disconnect` fields.
- Switched from nanomsg (Release 1.1.2) to NNG (Release v1.0.1)
- Memory leak fixes
- Changed connection logic (connection.c) for retries, and added unit test
- Partner-id comparison made case insensitive
- Reverted from NNG to nanomag (v1.1.2)
- reverted temporary CMake reference to https://github.com/bill1600/seshat
- Added log for time difference of parodus connect time and boot time
- added NULL check for device mac id in upstream retrieve message handling
- backoff retry to include find_servers in loop (connection.c)
- backoff max is max count not max delay
- Fixed memory leak in upstream event message flow
## [1.0.1] - 2018-07-18
### Added

View File

@@ -23,6 +23,7 @@ set(INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/_install)
set(PREFIX_DIR ${CMAKE_CURRENT_BINARY_DIR}/_prefix)
set(INCLUDE_DIR ${INSTALL_DIR}/include)
set(INCLUDE_UCRESOLV ${PREFIX_DIR}/ucresolv/src/ucresolv/include)
set(PATCHES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/patches)
set(LIBRARY_DIR ${INSTALL_DIR}/lib)
set(LIBRARY_DIR64 ${INSTALL_DIR}/lib64)
set(COMMON_LIBRARY_DIR ${INSTALL_DIR}/lib/${CMAKE_LIBRARY_ARCHITECTURE})
@@ -71,7 +72,7 @@ if (NOT BUILD_YOCTO)
ExternalProject_Add(trower-base64
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/trower-base64
GIT_REPOSITORY https://github.com/Comcast/trower-base64.git
GIT_TAG "fbb9440ae2bc1118866baefcea7ff814f16613dd"
GIT_TAG "v1.1.1"
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} -DBUILD_TESTING=OFF
)
add_library(libtrower-base64 STATIC SHARED IMPORTED)
@@ -83,7 +84,7 @@ add_dependencies(libtrower-base64 trower-base64)
ExternalProject_Add(nopoll
PREFIX ${PREFIX_DIR}/nopoll
GIT_REPOSITORY https://github.com/Comcast/nopoll.git
GIT_TAG "739b740683b0615e5999bdeea756cbd593b7f1cc"
GIT_TAG "1.0.1"
CONFIGURE_COMMAND COMMAND <SOURCE_DIR>/autogen.sh --prefix=${PREFIX}
--includedir=${INCLUDE_DIR}
--libdir=${LIBRARY_DIR}
@@ -99,7 +100,7 @@ add_dependencies(libnopoll nopoll)
ExternalProject_Add(nanomsg
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/nanomsg
GIT_REPOSITORY https://github.com/nanomsg/nanomsg.git
GIT_TAG "0c1aa2b288f6b167dbafe7e29c20e6fc7e71c000"
GIT_TAG "1.1.2"
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR}
)
add_library(libnanomsg STATIC SHARED IMPORTED)
@@ -112,7 +113,7 @@ ExternalProject_Add(cJSON
#PREFIX ${PREFIX_DIR}/cJSON
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/cJSON
GIT_REPOSITORY https://github.com/DaveGamble/cJSON.git
GIT_TAG "aafb64a1c549b7b927e339df6d35b1d5059dc235"
GIT_TAG "v1.7.8"
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} -DBUILD_TESTING=OFF
)
add_library(libcJSON STATIC SHARED IMPORTED)
@@ -124,7 +125,7 @@ add_dependencies(libcJSON cJSON)
ExternalProject_Add(msgpack
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/msgpack
GIT_REPOSITORY https://github.com/msgpack/msgpack-c.git
GIT_TAG "7a98138f27f27290e680bf8fbf1f8d1b089bf138"
GIT_TAG "cpp-3.1.1"
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR}
-DMSGPACK_ENABLE_CXX=OFF
-DMSGPACK_BUILD_EXAMPLES=OFF
@@ -138,7 +139,7 @@ add_dependencies(libmsgpack msgpack)
ExternalProject_Add(cimplog
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/cimplog
GIT_REPOSITORY https://github.com/Comcast/cimplog.git
GIT_TAG "8a5fb3c2f182241d17f5342bea5b7688c28cd1fd"
GIT_TAG "1.0.1"
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} -DBUILD_TESTING=OFF
)
add_library(libcimplog STATIC SHARED IMPORTED)
@@ -151,7 +152,7 @@ ExternalProject_Add(wrp-c
DEPENDS trower-base64 msgpack cimplog
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/wrp-c
GIT_REPOSITORY https://github.com/Comcast/wrp-c.git
GIT_TAG "d42ac3a63b8d6e723995b63e23aa1969e622faa5"
GIT_TAG "1.0.1"
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR}
-DMSGPACK_ENABLE_CXX=OFF
-DMSGPACK_BUILD_EXAMPLES=OFF
@@ -163,22 +164,6 @@ ExternalProject_Add(wrp-c
add_library(libwrp-c STATIC SHARED IMPORTED)
add_dependencies(libwrp-c wrp-c)
# libparodus external dependency
#-------------------------------------------------------------------------------
ExternalProject_Add(libparodus
DEPENDS trower-base64 msgpack nanomsg wrp-c
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/libparodus
GIT_REPOSITORY https://github.com/Comcast/libparodus.git
GIT_TAG "a7615d69bd5859e337f467fb7e33182da970a5de"
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} -DBUILD_TESTING=OFF
-DMAIN_PROJ_BUILD=ON
-DMAIN_PROJ_LIB_PATH=${LIBRARY_DIR}
-DMAIN_PROJ_LIB64_PATH=${LIBRARY_DIR64}
-DMAIN_PROJ_COMMON_PATH=${COMMON_LIBRARY_DIR}
-DMAIN_PROJ_INCLUDE_PATH=${INCLUDE_DIR}
)
add_library(liblibparodus STATIC SHARED IMPORTED)
add_dependencies(liblibparodus libparodus)
if (ENABLE_SESHAT)
# libseshat external dependency
@@ -186,8 +171,8 @@ if (ENABLE_SESHAT)
ExternalProject_Add(libseshat
DEPENDS cJSON trower-base64 msgpack nanomsg wrp-c
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/libseshat
GIT_REPOSITORY https://github.com/comcast/seshat.git
GIT_TAG "470f8d5e9457755028aae6da65d3df9b62a53942"
GIT_REPOSITORY https://github.com/Comcast/seshat.git
GIT_TAG "1.0.1"
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} -DBUILD_TESTING=OFF
-DMAIN_PROJ_BUILD=ON
-DMAIN_PROJ_LIB_PATH=${LIBRARY_DIR}
@@ -206,7 +191,7 @@ endif (ENABLE_SESHAT)
ExternalProject_Add(cjwt
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/cjwt
GIT_REPOSITORY https://github.com/Comcast/cjwt.git
GIT_TAG "ddd077f0f00407f9657934492b252ee5cfcde535"
GIT_TAG "1.0.1"
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} -DBUILD_TESTING=OFF
)
add_library(libcjwt STATIC SHARED IMPORTED)
@@ -218,7 +203,7 @@ if (FEATURE_DNS_QUERY)
ExternalProject_Add(ucresolv
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/ucresolv
GIT_REPOSITORY https://github.com/Comcast/libucresolv.git
GIT_TAG "b58d49e165208791f84b44e3c079b1b4ef6d5c9d"
GIT_TAG "1.0.0"
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR}
)
add_library(libucresolv STATIC SHARED IMPORTED)

View File

@@ -15,7 +15,7 @@ set(SOURCES main.c mutex.c networking.c nopoll_helpers.c heartBeat.c nopoll_hand
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
crud_interface.c crud_tasks.c crud_internal.c)
crud_interface.c crud_tasks.c crud_internal.c close_retry.c)
if (ENABLE_SESHAT)
set(SOURCES ${SOURCES} seshat_interface.c)

View File

@@ -87,6 +87,10 @@ char* getWebpaConveyHeader()
ParodusError("Failed to GET Reconnect reason value\n");
}
if(get_parodus_cfg()->boot_retry_wait > 0)
{
cJSON_AddNumberToObject(response, BOOT_RETRY_WAIT, get_parodus_cfg()->boot_retry_wait);
}
buffer = cJSON_PrintUnformatted(response);
ParodusInfo("X-WebPA-Convey Header: [%zd]%s\n", strlen(buffer), buffer);

View File

@@ -59,6 +59,12 @@ extern int numLoops;
#define FOREVER() numLoops--
#endif
// Return values for find_servers() in connection.c
#define FIND_SUCCESS 0
#define FIND_INVALID_DEFAULT -2
#define FIND_JWT_FAIL -1
/*----------------------------------------------------------------------------*/
/* Data Structures */
/*----------------------------------------------------------------------------*/
@@ -77,6 +83,53 @@ typedef struct {
int rr_len;
} rr_rec_t;
//------------ Used in comnection.c -----------------
typedef struct {
int allow_insecure;
char *server_addr; // must be freed
unsigned int port;
} server_t;
typedef struct {
server_t defaults; // from command line
server_t jwt; // from jwt endpoint claim
server_t redirect; // from redirect response to
// nopoll_conn_wait_until_connection_ready
} server_list_t;
//---- Used in connection.c for expire timer
typedef struct {
int running;
struct timespec start_time;
struct timespec end_time;
} expire_timer_t;
//--- Used in connection.c for backoff delay timer
typedef struct {
int count;
int max_count;
int delay;
} backoff_timer_t;
//--- Used in connection.c for init_header_info
typedef struct {
char *conveyHeader; // Do not free
char *device_id; // Need to free
char *user_agent; // Need to free
} header_info_t;
// connection context which is defined in createNopollConnection
// and passed into functions keep_retrying_connect, connect_and_wait,
// wait_connection_ready, and nopoll_connect
typedef struct {
noPollCtx *nopoll_ctx;
server_list_t server_list;
server_t *current_server;
header_info_t header_info;
char *extra_headers; // need to be freed
expire_timer_t connect_timer;
} create_connection_ctx_t;
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/

View File

@@ -224,3 +224,31 @@ int deleteFromList(char* service_name)
ParodusError("Could not find the entry to delete from list\n");
return -1;
}
/*
*@dest : Client destination to send message
*@Msg: Msg to send it to client (No free done here), user responsibilites to free the msg
*@msgSize : Total size of the msg to send to client
*/
int sendMsgtoRegisteredClients(char *dest,const char **Msg,size_t msgSize)
{
int bytes =0;
reg_list_item_t *temp = NULL;
temp = get_global_node();
//Checking for individual clients & Sending msg to registered client
while (NULL != temp)
{
ParodusPrint("node is pointing to temp->service_name %s \n",temp->service_name);
// Sending message to registered clients
if( strcmp(dest, temp->service_name) == 0)
{
bytes = nn_send(temp->sock, *Msg, msgSize, 0);
ParodusInfo("sent downstream message to reg_client '%s'\n", temp->url);
ParodusPrint("downstream bytes sent:%d\n", bytes);
return 1;
}
ParodusPrint("checking the next item in the list\n");
temp= temp->next;
}
return 0;
}

View File

@@ -50,6 +50,7 @@ int sendAuthStatus(reg_list_item_t *new_node);
int deleteFromList(char* service_name);
int get_numOfClients();
int sendMsgtoRegisteredClients(char *dest,const char **Msg,size_t msgSize);
reg_list_item_t * get_global_node(void);

56
src/close_retry.c Normal file
View File

@@ -0,0 +1,56 @@
/**
* Copyright 2018 Comcast Cable Communications Management, LLC
*
* 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.
*
*/
/**
* @file close_retry.c
*
* @description Functions required to manage connection close retry.
*
*/
#include "close_retry.h"
bool close_retry = false;
pthread_mutex_t close_mut=PTHREAD_MUTEX_INITIALIZER;
// Get value of close_retry
bool get_close_retry()
{
bool tmp = false;
pthread_mutex_lock (&close_mut);
tmp = close_retry;
pthread_mutex_unlock (&close_mut);
return tmp;
}
// Reset value of close_retry to false
void reset_close_retry()
{
pthread_mutex_lock (&close_mut);
close_retry = false;
pthread_mutex_unlock (&close_mut);
}
// set value of close_retry to true
void set_close_retry()
{
pthread_mutex_lock (&close_mut);
close_retry = true;
pthread_mutex_unlock (&close_mut);
}

47
src/close_retry.h Normal file
View File

@@ -0,0 +1,47 @@
/**
* Copyright 2018 Comcast Cable Communications Management, LLC
*
* 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.
*
*/
/**
* @file close_retry.h
*
* @description Functions required to manage connection close retry.
*
*/
#ifndef _CLOSERETRY_H_
#define _CLOSERETRY_H_
#include <pthread.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
// Get value of close_retry
bool get_close_retry();
// Reset value of close_retry to false
void reset_close_retry();
// Set value of close_retry to true
void set_close_retry();
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -51,7 +51,16 @@ void set_parodus_cfg(ParodusCfg *cfg)
memcpy(&parodusCfg, cfg, sizeof(ParodusCfg));
}
static void execute_token_script(char *token, char *name, size_t len, char *mac, char *serNum);
void set_cloud_disconnect_reason(ParodusCfg *cfg, char *disconn_reason)
{
cfg->cloud_disconnect = strdup(disconn_reason);
}
void reset_cloud_disconnect_reason(ParodusCfg *cfg)
{
cfg->cloud_disconnect = NULL;
}
const char *get_tok (const char *src, int delim, char *result, int resultsize)
{
@@ -132,7 +141,7 @@ void read_key_from_file (const char *fname, char *buf, size_t buflen)
ParodusInfo ("%d bytes read\n", nbytes);
}
static void execute_token_script(char *token, char *name, size_t len, char *mac, char *serNum)
void execute_token_script(char *token, char *name, size_t len, char *mac, char *serNum)
{
FILE* out = NULL, *file = NULL;
char command[MAX_BUF_SIZE] = {'\0'};
@@ -201,7 +210,7 @@ int server_is_http (const char *full_url,
}
int parse_webpa_url(const char *full_url,
int parse_webpa_url__ (const char *full_url,
char *server_addr, int server_addr_buflen,
char *port_buf, int port_buflen)
{
@@ -210,6 +219,9 @@ int parse_webpa_url(const char *full_url,
char *end_port;
size_t server_len;
int http_match;
char *closeBracket = NULL;
char *openBracket = NULL;
char *checkPort = NULL;
ParodusInfo ("full url: %s\n", full_url);
http_match = server_is_http (full_url, &server_ptr);
@@ -222,6 +234,40 @@ int parse_webpa_url(const char *full_url,
// If there's a '/' on end, null it out
if ((server_len>0) && (server_addr[server_len-1] == '/'))
server_addr[server_len-1] = '\0';
openBracket = strchr(server_addr,'[');
if(openBracket != NULL){
//Remove [ from server address
char *remove = server_addr;
remove++;
parStrncpy (server_addr, remove, server_addr_buflen);
closeBracket = strchr(server_addr,']');
if(closeBracket != NULL){
//Remove ] by making it as null
*closeBracket = '\0';
closeBracket++;
checkPort = strchr(closeBracket,':');
if (NULL == checkPort) {
if (http_match)
parStrncpy (port_buf, "80", port_buflen);
else
parStrncpy (port_buf, "443", port_buflen);
} else {
checkPort++;
end_port = strchr (checkPort, '/');
if (NULL != end_port)
*end_port = '\0'; // terminate port with null
parStrncpy (port_buf, checkPort, port_buflen);
}
}else{
ParodusError("Invalid url %s\n", full_url);
return -1;
}
}else if (strchr(server_addr,']') != NULL ){
ParodusError("Invalid url %s\n", full_url);
return -1;
}else{
// Look for ':'
port_val = strchr (server_addr, ':');
@@ -230,7 +276,6 @@ int parse_webpa_url(const char *full_url,
parStrncpy (port_buf, "80", port_buflen);
else
parStrncpy (port_buf, "443", port_buflen);
end_port = strchr (server_addr, '/');
if (NULL != end_port) {
*end_port = '\0'; // terminate server address with null
@@ -244,6 +289,7 @@ int parse_webpa_url(const char *full_url,
*end_port = '\0'; // terminate port with null
parStrncpy (port_buf, port_val, port_buflen);
}
}
ParodusInfo ("server %s, port %s, http_match %d\n",
server_addr, port_buf, http_match);
return http_match;
@@ -271,6 +317,49 @@ unsigned int parse_num_arg (const char *arg, const char *arg_name)
return result;
}
int parse_webpa_url (const char *full_url,
char **server_addr, unsigned int *port)
{
int allow_insecure;
unsigned int port_val;
int buflen = strlen (full_url) + 1;
char *url_buf = NULL;
char port_buf[8];
#define ERROR__(msg) \
ParodusError (msg); \
if (NULL != url_buf) \
free (url_buf);
*server_addr = NULL;
url_buf = (char *) malloc (buflen);
if (NULL == url_buf) {
ERROR__ ("parse_webpa_url allocatio n failed.\n")
return -1;
}
allow_insecure = parse_webpa_url__ (full_url,
url_buf, buflen, port_buf, 8);
if (allow_insecure < 0) {
ERROR__ ("parse_webpa_url invalid url\n")
return -1;
}
port_val = parse_num_arg (port_buf, "server port");
if (port_val == (unsigned int) -1) {
ERROR__ ("Invalid port in server url")
return -1;
}
if ((port_val == 0) || (port_val > 65535)) {
ERROR__ ("port value out of range in server url")
return -1;
}
*server_addr = url_buf;
*port = port_val;
return allow_insecure;
#undef ERROR__
}
int parseCommandLine(int argc,char **argv,ParodusCfg * cfg)
{
static const struct option long_options[] = {
@@ -298,6 +387,7 @@ int parseCommandLine(int argc,char **argv,ParodusCfg * cfg)
{"force-ipv4", no_argument, 0, '4'},
{"force-ipv6", no_argument, 0, '6'},
{"token-read-script", required_argument, 0, 'T'},
{"boot-time-retry-wait", required_argument, 0, 'w'},
{"token-acquisition-script", required_argument, 0, 'J'},
{"crud-config-file", required_argument, 0, 'C'},
{0, 0, 0, 0}
@@ -315,13 +405,15 @@ int parseCommandLine(int argc,char **argv,ParodusCfg * cfg)
cfg->jwt_algo = 0;
parStrncpy (cfg->jwt_key, "", sizeof(cfg->jwt_key));
cfg->crud_config_file = NULL;
cfg->cloud_status = NULL;
cfg->cloud_disconnect = NULL;
optind = 1; /* We need this if parseCommandLine is called again */
while (1)
{
/* getopt_long stores the option index here. */
int option_index = 0;
c = getopt_long (argc, argv, "m:s:f:d:r:n:b:u:t:o:i:l:p:e:D:j:a:k:c:T:J:46:C",
c = getopt_long (argc, argv, "m:s:f:d:r:n:b:u:t:o:i:l:p:e:D:j:a:k:c:T:w:J:46:C",
long_options, &option_index);
/* Detect the end of the options. */
@@ -371,8 +463,6 @@ int parseCommandLine(int argc,char **argv,ParodusCfg * cfg)
case 'b':
cfg->boot_time = parse_num_arg (optarg, "boot-time");
if (cfg->boot_time == (unsigned int) -1)
return -1;
ParodusInfo("boot_time is %d\n",cfg->boot_time);
break;
@@ -462,6 +552,11 @@ int parseCommandLine(int argc,char **argv,ParodusCfg * cfg)
case 'T':
parStrncpy(cfg->token_read_script, optarg,sizeof(cfg->token_read_script));
break;
case 'w':
cfg->boot_retry_wait = parse_num_arg (optarg, "boot-time-retry-wait");
ParodusInfo("boot_retry_wait is %d\n",cfg->boot_retry_wait);
break;
case 'C':
@@ -598,8 +693,10 @@ void setDefaultValuesToCfg(ParodusCfg *cfg)
parStrncpy(cfg->webpa_uuid, "1234567-345456546",sizeof(cfg->webpa_uuid));
ParodusPrint("cfg->webpa_uuid is :%s\n", cfg->webpa_uuid);
cfg->crud_config_file = strdup("parodus_cfg.json");
ParodusPrint("Default crud_config_file is %s\n", cfg->crud_config_file);
cfg->crud_config_file = NULL;
cfg->cloud_status = CLOUD_STATUS_OFFLINE;
ParodusInfo("Default cloud_status is %s\n", cfg->cloud_status);
}
void loadParodusCfg(ParodusCfg * config,ParodusCfg *cfg)

View File

@@ -49,6 +49,12 @@ extern "C" {
#define WEBPA_BACKOFF_MAX "webpa-backoff-max"
#define PARTNER_ID "partner-id"
#define CERT_PATH "ssl-cert-path"
#define CLOUD_STATUS "cloud-status"
#define CLOUD_DISCONNECT "cloud-disconnect"
#define CLOUD_STATUS_ONLINE "online"
#define CLOUD_STATUS_OFFLINE "offline"
#define CLOUD_DISCONNECT_REASON "disconnection-reason"
#define BOOT_RETRY_WAIT "boot-time-retry-wait"
#define PROTOCOL_VALUE "PARODUS-2.0"
#define WEBPA_PATH_URL "/api/v2/device"
@@ -94,6 +100,9 @@ typedef struct
char token_acquisition_script[64];
char token_read_script[64];
char *crud_config_file;
char *cloud_status;
char *cloud_disconnect;
unsigned int boot_retry_wait;
} ParodusCfg;
#define FLAGS_IPV6_ONLY (1 << 0)
@@ -124,22 +133,22 @@ void getAuthToken(ParodusCfg *cfg);
ParodusCfg *get_parodus_cfg(void);
void set_parodus_cfg(ParodusCfg *);
char *get_token_application(void) ;
void set_cloud_disconnect_reason(ParodusCfg *cfg, char *disconn_reason);
void reset_cloud_disconnect_reason(ParodusCfg *cfg);
/**
* parse a webpa url. Extract the server address, the port
* and return whether it's secure or not
*
* @param full_url full url
* @param server_addr buffer containing server address found in url
* @param server_addr_buflen len of the server addr buffer provided by caller
* @param port_buf buffer containing port value found in url
* @param port_buflen len of the port buffer provided by caller
* @param full_url full url
* @param server_addr ptr to a server address ptr
* will be NULL if invalid,
* otherwise will need to be freed
* @param port ptr to port variable
* @return 1 if insecure connection is allowed, 0 if not,
* or -1 if error
*/
int parse_webpa_url(const char *full_url,
char *server_addr, int server_addr_buflen,
char *port_buf, int port_buflen);
int parse_webpa_url (const char *full_url,
char **server_addr, unsigned int *port);
#ifdef __cplusplus
}

View File

@@ -35,6 +35,7 @@
#include "seshat_interface.h"
#include "crud_interface.h"
#include "heartBeat.h"
#include "close_retry.h"
#ifdef FEATURE_DNS_QUERY
#include <ucresolv_log.h>
#endif
@@ -45,13 +46,12 @@
/*----------------------------------------------------------------------------*/
#define HEARTBEAT_RETRY_SEC 30 /* Heartbeat (ping/pong) timeout in seconds */
#define CLOUD_RECONNECT_TIME 5 /* Cloud disconnect max time in minutes */
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
bool close_retry = false;
pthread_mutex_t close_mut=PTHREAD_MUTEX_INITIALIZER;
bool g_shutdown = false;
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
@@ -86,7 +86,11 @@ void createSocketConnection(void (* initKeypress)())
nopoll_log_set_handler (ctx, __report_log, NULL);
#endif
createNopollConnection(ctx);
if(!createNopollConnection(ctx))
{
ParodusError("Unrecovered error, terminating the process\n");
abort();
}
packMetaData();
UpStreamMsgQ = NULL;
@@ -121,19 +125,18 @@ void createSocketConnection(void (* initKeypress)())
if(heartBeatTimer >= webpa_ping_timeout_ms)
{
ParodusInfo("heartBeatTimer %d webpa_ping_timeout_ms %d\n", heartBeatTimer, webpa_ping_timeout_ms);
if(!close_retry)
if(!get_close_retry())
{
ParodusError("ping wait time > %d . Terminating the connection with WebPA server and retrying\n", webpa_ping_timeout_ms / 1000);
ParodusInfo("Reconnect detected, setting Ping_Miss reason for Reconnect\n");
set_global_reconnect_reason("Ping_Miss");
set_global_reconnect_status(true);
pthread_mutex_lock (&close_mut);
close_retry = true;
pthread_mutex_unlock (&close_mut);
set_close_retry();
}
else
{
ParodusPrint("heartBeatHandler - close_retry set to %d, hence resetting the heartBeatTimer\n",close_retry);
{
ParodusPrint("heartBeatHandler - close_retry set to %d, hence resetting the heartBeatTimer\n",get_close_retry());
}
reset_heartBeatTimer();
}
@@ -145,17 +148,35 @@ void createSocketConnection(void (* initKeypress)())
seshat_registered = __registerWithSeshat();
}
if(close_retry)
if(get_close_retry())
{
ParodusInfo("close_retry is %d, hence closing the connection and retrying\n", close_retry);
ParodusInfo("close_retry is %d, hence closing the connection and retrying\n", get_close_retry());
close_and_unref_connection(get_global_conn());
set_global_conn(NULL);
get_parodus_cfg()->cloud_status = CLOUD_STATUS_OFFLINE;
ParodusInfo("cloud_status set as %s after connection close\n", get_parodus_cfg()->cloud_status);
if(get_parodus_cfg()->cloud_disconnect !=NULL)
{
ParodusPrint("get_parodus_cfg()->cloud_disconnect is %s\n", get_parodus_cfg()->cloud_disconnect);
set_cloud_disconnect_time(CLOUD_RECONNECT_TIME);
ParodusInfo("Waiting for %d minutes for reconnecting .. \n", get_cloud_disconnect_time());
sleep( get_cloud_disconnect_time() * 60 );
ParodusInfo("cloud-disconnect reason reset after %d minutes\n", get_cloud_disconnect_time());
free(get_parodus_cfg()->cloud_disconnect);
reset_cloud_disconnect_reason(get_parodus_cfg());
}
createNopollConnection(ctx);
}
} while(!close_retry);
}
} while(!get_close_retry() && !g_shutdown);
close_and_unref_connection(get_global_conn());
nopoll_ctx_unref(ctx);
nopoll_cleanup_library();
}
void shutdownSocketConnection(void) {
g_shutdown = true;
}

View File

@@ -45,6 +45,7 @@ extern UpStreamMsg *UpStreamMsgQ;
* and creates the intial connection and manages the connection wait, close mechanisms.
*/
void createSocketConnection(void (* initKeypress)());
void shutdownSocketConnection(void);
#ifdef __cplusplus
}

View File

@@ -28,28 +28,27 @@
#include "nopoll_helpers.h"
#include "mutex.h"
#include "spin_thread.h"
#include "ParodusInternal.h"
#include "heartBeat.h"
#include "close_retry.h"
/*----------------------------------------------------------------------------*/
/* Macros */
/*----------------------------------------------------------------------------*/
#define HTTP_CUSTOM_HEADER_COUNT 5
#define INITIAL_CJWT_RETRY -2
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
char deviceMAC[32]={'\0'};
static char *reconnect_reason = "webpa_process_starts";
static int cloud_disconnect_max_time = 5;
static noPollConn *g_conn = NULL;
static bool LastReasonStatus = false;
static noPollConnOpts * createConnOpts (char * extra_headers, bool secure);
static noPollConn * nopoll_tls_common_conn (noPollCtx * ctx,char * serverAddr,char *serverPort,char * extra_headers,unsigned int *fallback);
static char* build_extra_headers( const char *auth, const char *device_id,
const char *user_agent, const char *convey );
static void toggleIPFlag (unsigned int *ptrFallback);
static noPollConn * __internal_fallbackConn(noPollCtx * ctx,noPollConnOpts * opts,char * serverAddr,char *serverPort,char * extra_headers,unsigned int *fallback);
/*----------------------------------------------------------------------------*/
/* External Functions */
@@ -84,332 +83,491 @@ void set_global_reconnect_status(bool status)
LastReasonStatus = status;
}
// If IPv6 conn failed to connect then fallback to IPv4 conn or vice-versa
static void toggleIPFlag (unsigned int *ptrFallback)
int get_cloud_disconnect_time()
{
if(FLAGS_IPV6_ONLY == (FLAGS_IPV6_IPV4 & *ptrFallback))
*ptrFallback = FLAGS_IPV4_ONLY;
else
*ptrFallback = FLAGS_IPV6_ONLY;
return cloud_disconnect_max_time;
}
void set_cloud_disconnect_time(int disconnTime)
{
cloud_disconnect_max_time = disconnTime;
}
//--------------------------------------------------------------------
// createNopollConnection_logic:
// call stack:
// createNopollConnection
// find_servers
// keep_trying_connect // keep trying till success or need to requery dns
// connect_and_wait // tries both ipv6 and ipv4, if necessary
// nopoll_connect
// wait_connection_ready
//--------------------------------------------------------------------
#define FREE_PTR_VAR(ptr_var) \
if (NULL != ptr_var) { \
free(ptr_var); \
ptr_var = NULL; \
}
void set_server_null (server_t *server)
{
server->server_addr = NULL;
}
void set_server_list_null (server_list_t *server_list)
{
set_server_null (&server_list->defaults);
set_server_null (&server_list->jwt);
set_server_null (&server_list->redirect);
}
int server_is_null (server_t *server)
{
return (NULL == server->server_addr);
}
void free_server (server_t *server)
{
FREE_PTR_VAR (server->server_addr)
}
void free_server_list (server_list_t *server_list)
{
free_server (&server_list->redirect);
free_server (&server_list->jwt);
free_server (&server_list->defaults);
}
// If there's a redirect server, that's it,
// else if there's a jwt server that's it,
// else it's the default server
server_t *get_current_server (server_list_t *server_list)
{
if (!server_is_null (&server_list->redirect))
return &server_list->redirect;
if (!server_is_null (&server_list->jwt))
return &server_list->jwt;
return &server_list->defaults;
}
int parse_server_url (const char *full_url, server_t *server)
{
server->allow_insecure = parse_webpa_url (full_url,
&server->server_addr, &server->port);
return server->allow_insecure;
}
//--------------------------------------------------------------------
void init_expire_timer (expire_timer_t *timer)
{
timer->running = false;
}
int check_timer_expired (expire_timer_t *timer, long timeout_ms)
{
long time_diff_ms;
if (!timer->running) {
getCurrentTime(&timer->start_time);
timer->running = true;
ParodusInfo("First connect error occurred, initialized the connect error timer\n");
return false;
}
getCurrentTime(&timer->end_time);
time_diff_ms = timeValDiff (&timer->start_time, &timer->end_time);
ParodusPrint("checking timeout difference:%ld\n", time_diff_ms);
if(time_diff_ms >= timeout_ms)
return true;
return false;
}
//--------------------------------------------------------------------
void init_backoff_timer (backoff_timer_t *timer, int max_count)
{
timer->count = 1;
timer->max_count = max_count;
timer->delay = 1;
}
int update_backoff_delay (backoff_timer_t *timer)
{
if (timer->count < timer->max_count) {
timer->count += 1;
timer->delay = timer->delay + timer->delay + 1;
// 3,7,15,31 ..
}
return timer->delay;
}
static void backoff_delay (backoff_timer_t *timer)
{
update_backoff_delay (timer);
ParodusInfo("Waiting with backoffRetryTime %d seconds\n", timer->delay);
sleep (timer->delay);
}
//--------------------------------------------------------------------
void free_header_info (header_info_t *header_info)
{
FREE_PTR_VAR (header_info->user_agent)
FREE_PTR_VAR (header_info->device_id)
// Don't free header_info->conveyHeader, because it's static
header_info->conveyHeader = NULL;
}
void set_header_info_null (header_info_t *header_info)
{
header_info->conveyHeader = NULL;
header_info->user_agent = NULL;
header_info->device_id = NULL;
}
int init_header_info (header_info_t *header_info)
{
ParodusCfg *cfg = get_parodus_cfg();
size_t device_id_len;
#define CFG_PARAM(param) ((0 != strlen(cfg->param)) ? cfg->param : "unknown")
const char *user_agent_format = "%s (%s; %s/%s;)";
char *protocol = CFG_PARAM (webpa_protocol);
char *fw_name = CFG_PARAM (fw_name);
char *hw_model = CFG_PARAM (hw_model);
char *hw_manufacturer = CFG_PARAM (hw_manufacturer);
size_t user_agent_len = strlen(protocol) + strlen(fw_name) +
strlen(hw_model) + strlen(hw_manufacturer) + strlen(user_agent_format)
+ 1;
set_header_info_null (header_info);
header_info->user_agent = (char *) malloc (user_agent_len);
if (NULL == header_info->user_agent) {
ParodusError ("header user agent allocation failed.\n");
return -1;
}
snprintf(header_info->user_agent, user_agent_len, user_agent_format,
protocol, fw_name, hw_model, hw_manufacturer);
device_id_len = strlen (cfg->hw_mac) + 5;
header_info->device_id = (char *) malloc (device_id_len);
if (NULL == header_info->device_id) {
ParodusError ("header device id allocation failed.\n");
FREE_PTR_VAR (header_info->user_agent)
return -1;
}
snprintf(header_info->device_id, device_id_len, "mac:%s", cfg->hw_mac);
ParodusInfo("User-Agent: %s\n",header_info->user_agent);
header_info->conveyHeader = getWebpaConveyHeader(); // ptr to static variable returned
if (NULL == header_info->conveyHeader) {
ParodusError ("getWebpaConveyHeader error\n");
free_header_info (header_info);
return -1;
}
ParodusInfo("Device_id %s\n", header_info->device_id);
return 0;
#undef CFG_PARAM
}
char *build_extra_hdrs (header_info_t *header_info)
// result must be freed
{
char *auth_token = get_parodus_cfg()->webpa_auth_token;
return build_extra_headers( (0 < strlen(auth_token) ? auth_token : NULL),
header_info->device_id, header_info->user_agent, header_info->conveyHeader );
}
//--------------------------------------------------------------------
void set_current_server (create_connection_ctx_t *ctx)
{
ctx->current_server = get_current_server (&ctx->server_list);
}
void set_extra_headers (create_connection_ctx_t *ctx, int reauthorize)
{
if (reauthorize && (strlen(get_parodus_cfg()->token_acquisition_script) >0))
{
createNewAuthToken(get_parodus_cfg()->webpa_auth_token,
sizeof(get_parodus_cfg()->webpa_auth_token));
}
ctx->extra_headers = build_extra_hdrs (&ctx->header_info);
}
void free_extra_headers (create_connection_ctx_t *ctx)
{
FREE_PTR_VAR (ctx->extra_headers)
}
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);
}
//--------------------------------------------------------------------
// find_servers:
// get and parse default server
// if necessary, query dns and parse server from jwt
// populate server_list
// return values defined in ParodusInternal.h
int find_servers (server_list_t *server_list)
{
server_t *default_server = &server_list->defaults;
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
ParodusInfo("default server_Address %s\n", default_server->server_addr);
ParodusInfo("default port %u\n", default_server->port);
#ifdef FEATURE_DNS_QUERY
if (get_parodus_cfg()->acquire_jwt) {
server_t *jwt_server = &server_list->jwt;
//query dns and validate JWT
jwt_server->allow_insecure = allow_insecure_conn(
&jwt_server->server_addr, &jwt_server->port);
if (jwt_server->allow_insecure < 0) {
return FIND_JWT_FAIL;
}
ParodusInfo("JWT ON: jwt_server_url stored as %s\n", jwt_server->server_addr);
}
#endif
return FIND_SUCCESS;
}
//--------------------------------------------------------------------
// connect to current server
int nopoll_connect (create_connection_ctx_t *ctx, int is_ipv6)
{
noPollCtx *nopoll_ctx = ctx->nopoll_ctx;
server_t *server = ctx->current_server;
noPollConn *connection;
noPollConnOpts * opts;
char *default_url = get_parodus_cfg()->webpa_path_url;
char port_buf[8];
sprintf (port_buf, "%u", server->port);
if (server->allow_insecure > 0) {
ParodusPrint("secure false\n");
opts = createConnOpts(ctx->extra_headers, false);
connection = nopoll_conn_new_opts (nopoll_ctx, opts,
server->server_addr, port_buf,
NULL, default_url,NULL,NULL);// WEBPA-787
} else {
ParodusPrint("secure true\n");
opts = createConnOpts(ctx->extra_headers, true);
if (is_ipv6) {
ParodusInfo("Connecting in Ipv6 mode\n");
connection = nopoll_conn_tls_new6 (nopoll_ctx, opts,
server->server_addr, port_buf,
NULL, default_url,NULL,NULL);
} else {
ParodusInfo("Connecting in Ipv4 mode\n");
connection = nopoll_conn_tls_new (nopoll_ctx, opts,
server->server_addr, port_buf,
NULL, default_url,NULL,NULL);
}
}
if (NULL == connection) {
if((checkHostIp(server->server_addr) == -2)) {
if (check_timer_expired (&ctx->connect_timer, 15*60*1000)) {
ParodusError("WebPA unable to connect due to DNS resolving to 10.0.0.1 for over 15 minutes; crashing service.\n");
set_global_reconnect_reason("Dns_Res_webpa_reconnect");
set_global_reconnect_status(true);
kill(getpid(),SIGTERM);
}
}
}
set_global_conn(connection);
return (NULL != connection);
}
//--------------------------------------------------------------------
// Return codes for wait_connection_ready
#define WAIT_SUCCESS 0
#define WAIT_ACTION_RETRY 1 // if wait_status is 307, 302, 303 or 403
#define WAIT_FAIL 2
int wait_connection_ready (create_connection_ctx_t *ctx)
{
int wait_status;
char *redirectURL = NULL;
if(nopoll_conn_wait_for_status_until_connection_ready(get_global_conn(), 10,
&wait_status, &redirectURL))
return WAIT_SUCCESS;
if(wait_status == 307 || wait_status == 302 || wait_status == 303) // only when there is a http redirect
{
char *redirect_ptr = redirectURL;
ParodusError("Received temporary redirection response message %s\n", redirectURL);
// 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) {
ParodusError ("Redirect url error %s\n", redirectURL);
free (redirectURL);
return WAIT_FAIL;
}
free (redirectURL);
set_current_server (ctx); // set current server to redirect server
return WAIT_ACTION_RETRY;
}
if (NULL != redirectURL) {
free (redirectURL);
}
if(wait_status == 403)
{
ParodusError("Received Unauthorized response with status: %d\n", wait_status);
free_extra_headers (ctx);
set_extra_headers (ctx, true);
return WAIT_ACTION_RETRY;
}
ParodusError("Client connection timeout\n");
ParodusError("RDK-10037 - WebPA Connection Lost\n");
return WAIT_FAIL;
}
//--------------------------------------------------------------------
// 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
int connect_and_wait (create_connection_ctx_t *ctx)
{
unsigned int force_flags = get_parodus_cfg()->flags;
int is_ipv6 = true;
int nopoll_connected;
int wait_rtn;
if( FLAGS_IPV4_ONLY == (FLAGS_IPV4_ONLY & force_flags) ) {
is_ipv6 = false;
}
// This loop will be executed at most twice:
// Once for ipv6 and once for ipv4
while (true) {
nopoll_connected = nopoll_connect (ctx, is_ipv6);
wait_rtn = WAIT_FAIL;
if (nopoll_connected) {
if(nopoll_conn_is_ok(get_global_conn())) {
ParodusPrint("Connected to Server but not yet ready\n");
wait_rtn = wait_connection_ready (ctx);
if (wait_rtn == WAIT_SUCCESS)
return CONN_WAIT_SUCCESS;
} else { // nopoll_conn not ok
ParodusError("Error connecting to server\n");
ParodusError("RDK-10037 - WebPA Connection Lost\n");
}
} // nopoll_connected
if (nopoll_connected) {
close_and_unref_connection(get_global_conn());
set_global_conn(NULL);
}
if (wait_rtn == WAIT_ACTION_RETRY)
return CONN_WAIT_ACTION_RETRY;
// try ipv4 if we need to
if ((0==force_flags) && (0==ctx->current_server->allow_insecure) && is_ipv6) {
is_ipv6 = false;
continue;
}
return CONN_WAIT_RETRY_DNS;
}
}
//--------------------------------------------------------------------
// Tries to connect until
// a) success, or
// b) need to requery dns
int keep_trying_to_connect (create_connection_ctx_t *ctx,
backoff_timer_t *backoff_timer)
{
int rtn;
while (true)
{
rtn = connect_and_wait (ctx);
if (rtn == CONN_WAIT_SUCCESS)
return true;
if (rtn == CONN_WAIT_ACTION_RETRY) // if redirected or build_headers
continue;
backoff_delay (backoff_timer); // 3,7,15,31 ..
if (rtn == CONN_WAIT_RETRY_DNS)
return false; //find_server again
// else retry
}
}
//--------------------------------------------------------------------
/**
* @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)
{
bool initial_retry = false;
int backoffRetryTime = 0;
int max_retry_sleep;
char port[8];
char server_Address[256];
char *jwt_server_url= NULL;
char *redirectURL = NULL;
int status=0;
int allow_insecure = -1;
int jwt_status = INITIAL_CJWT_RETRY;
int connErr=0;
struct timespec connErr_start,connErr_end,*connErr_startPtr,*connErr_endPtr;
connErr_startPtr = &connErr_start;
connErr_endPtr = &connErr_end;
//Retry Backoff count shall start at c=2 & calculate 2^c - 1.
int c=2;
char *conveyHeader = NULL;
char device_id[36]={'\0'};
char user_agent[512]={'\0'};
char * extra_headers = NULL;
unsigned int fallback = FLAGS_IPV6_ONLY;
if(ctx == NULL) {
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;
if(ctx == NULL) {
return nopoll_false;
}
}
ParodusPrint("BootTime In sec: %d\n", get_parodus_cfg()->boot_time);
ParodusInfo("Received reboot_reason as:%s\n", get_parodus_cfg()->hw_last_reboot_reason);
ParodusInfo("Received reconnect_reason as:%s\n", reconnect_reason);
max_retry_sleep = (int) get_parodus_cfg()->webpa_backoff_max;
ParodusPrint("max_retry_sleep is %d\n", max_retry_sleep );
snprintf(user_agent, sizeof(user_agent),"%s (%s; %s/%s;)",
((0 != strlen(get_parodus_cfg()->webpa_protocol)) ? get_parodus_cfg()->webpa_protocol : "unknown"),
((0 != strlen(get_parodus_cfg()->fw_name)) ? get_parodus_cfg()->fw_name : "unknown"),
((0 != strlen(get_parodus_cfg()->hw_model)) ? get_parodus_cfg()->hw_model : "unknown"),
((0 != strlen(get_parodus_cfg()->hw_manufacturer)) ? get_parodus_cfg()->hw_manufacturer : "unknown"));
ParodusInfo("User-Agent: %s\n",user_agent);
conveyHeader = getWebpaConveyHeader();
parStrncpy(deviceMAC, get_parodus_cfg()->hw_mac,sizeof(deviceMAC));
snprintf(device_id, sizeof(device_id), "mac:%s", deviceMAC);
ParodusInfo("Device_id %s\n",device_id);
extra_headers = build_extra_headers(
((0 < strlen(get_parodus_cfg()->webpa_auth_token)) ? get_parodus_cfg()->webpa_auth_token : NULL),
device_id, user_agent, conveyHeader );
do
max_retry_count = (int) get_parodus_cfg()->webpa_backoff_max;
ParodusPrint("max_retry_count is %d\n", max_retry_count );
conn_ctx.nopoll_ctx = ctx;
init_expire_timer (&conn_ctx.connect_timer);
init_header_info (&conn_ctx.header_info);
set_extra_headers (&conn_ctx, false);
set_server_list_null (&conn_ctx.server_list);
init_backoff_timer (&backoff_timer, max_retry_count);
while (true)
{
//calculate backoffRetryTime and to perform exponential increment during retry
if(backoffRetryTime < max_retry_sleep)
{
backoffRetryTime = (int) pow(2, c) -1;
}
ParodusPrint("New backoffRetryTime value calculated as %d seconds\n", backoffRetryTime);
noPollConn *connection;
//retry jwt validation on query dns failure
if((jwt_status == INITIAL_CJWT_RETRY) || (jwt_status == TOKEN_ERR_QUERY_DNS_FAIL))
{
allow_insecure = parse_webpa_url (get_parodus_cfg()->webpa_url,
server_Address, (int) sizeof(server_Address),
port, (int) sizeof(port));
if (allow_insecure < 0)
return nopoll_false; // must have valid default url
#ifdef FEATURE_DNS_QUERY
if (get_parodus_cfg()->acquire_jwt) {
//query dns and validate JWT
jwt_status = allow_insecure_conn(
server_Address, (int) sizeof(server_Address),
port, (int) sizeof(port));
//store server_Address as jwt_server_url to use it for JWT retry scenarios
jwt_server_url = strdup(server_Address);
if (jwt_server_url !=NULL)
ParodusInfo("JWT ON: jwt_server_url stored as %s\n", jwt_server_url);
if (jwt_status >= 0)
allow_insecure = jwt_status;
}
else
{
ParodusInfo("JWT validation is disabled\n");
jwt_status = 1;
}
#else
jwt_status = 1;
#endif
ParodusInfo("server_Address %s\n",server_Address);
ParodusInfo("port %s\n", port);
}
if(allow_insecure <= 0)
{
ParodusPrint("secure true\n");
connection = nopoll_tls_common_conn(ctx,server_Address, port, extra_headers,&fallback);
}
else
{
ParodusPrint("secure false\n");
noPollConnOpts * opts;
opts = createConnOpts(extra_headers, false);
connection = nopoll_conn_new_opts (ctx, opts,server_Address,port,NULL,get_parodus_cfg()->webpa_path_url,NULL,NULL);// WEBPA-787
}
set_global_conn(connection);
if(get_global_conn() != NULL)
{
if(!nopoll_conn_is_ok(get_global_conn()))
{
ParodusError("Error connecting to server\n");
ParodusError("RDK-10037 - WebPA Connection Lost\n");
// Copy the server address from config to avoid retrying to the same failing talaria redirected node
if (get_parodus_cfg()->acquire_jwt == 0)
{
ParodusInfo("acquire_jwt is 0, retrying with config server address\n");
allow_insecure = parse_webpa_url (get_parodus_cfg()->webpa_url,
server_Address, (int) sizeof(server_Address),
port, (int) sizeof(port));
}
else
{
if( (jwt_server_url != NULL) && strlen(jwt_server_url) != 0 )
{
ParodusInfo("acquire_jwt is 1, retrying with jwt_server_url\n");
parStrncpy(server_Address, jwt_server_url, sizeof(server_Address));
}
else
{
ParodusError("acquire_jwt is 1 & unable to get jwt_server_url, retrying with config server address\n");
allow_insecure = parse_webpa_url (get_parodus_cfg()->webpa_url, server_Address, (int) sizeof(server_Address), port, (int) sizeof(port));
}
}
close_and_unref_connection(get_global_conn());
set_global_conn(NULL);
initial_retry = true;
toggleIPFlag(&fallback);
ParodusInfo("Waiting with backoffRetryTime %d seconds\n", backoffRetryTime);
sleep(backoffRetryTime);
continue;
}
else
{
ParodusPrint("Connected to Server but not yet ready\n");
initial_retry = false;
//reset backoffRetryTime back to the starting value, as next reason can be different
c = 2;
backoffRetryTime = (int) pow(2, c) -1;
}
if(!nopoll_conn_wait_for_status_until_connection_ready(get_global_conn(), 10, &status, &redirectURL))
{
if(status == 307 || status == 302 || status == 303) // only when there is a http redirect
{
ParodusError("Received temporary redirection response message %s\n", redirectURL);
// Extract server Address and port from the redirectURL
if (strncmp (redirectURL, "Redirect:", 9) == 0)
redirectURL += 9;
allow_insecure = parse_webpa_url (redirectURL,
server_Address, (int) sizeof(server_Address),
port, (int) sizeof(port));
if (allow_insecure < 0) {
ParodusError ("Invalid redirectURL\n");
if (get_parodus_cfg()->acquire_jwt == 0)
{
ParodusInfo("acquire_jwt is 0, retrying with config server address\n");
allow_insecure = parse_webpa_url (get_parodus_cfg()->webpa_url, server_Address, (int) sizeof(server_Address), port, (int) sizeof(port));
}
else
{
if( (jwt_server_url != NULL) && strlen(jwt_server_url) != 0 )
{
ParodusInfo("acquire_jwt is 1, retrying with jwt_server_url\n");
parStrncpy(server_Address, jwt_server_url, sizeof(server_Address));
}
else
{
ParodusError("acquire_jwt is 1 & unable to get jwt_server_url, retrying with config server address\n");
allow_insecure = parse_webpa_url (get_parodus_cfg()->webpa_url, server_Address, (int) sizeof(server_Address), port, (int) sizeof(port));
}
}
} else
ParodusInfo("Trying to Connect to new Redirected server : %s with port : %s\n", server_Address, port);
//reset c=2 to start backoffRetryTime as retrying using new redirect server
c = 2;
}
else if(status == 403)
{
ParodusError("Received Unauthorized response with status: %d\n", status);
//Get new token and update auth header
if (strlen(get_parodus_cfg()->token_acquisition_script) >0) {
createNewAuthToken(get_parodus_cfg()->webpa_auth_token,sizeof(get_parodus_cfg()->webpa_auth_token));
}
extra_headers = build_extra_headers( (0 < strlen(get_parodus_cfg()->webpa_auth_token) ? get_parodus_cfg()->webpa_auth_token : NULL),
device_id, user_agent, conveyHeader );
//reset c=2 to start backoffRetryTime as retrying
c = 2;
}
else
{
ParodusError("Client connection timeout\n");
ParodusError("RDK-10037 - WebPA Connection Lost\n");
// Copy the server address and port from config to avoid retrying to the same failing talaria redirected node
if (get_parodus_cfg()->acquire_jwt == 0)
{
ParodusInfo("acquire_jwt is 0, retrying with config server address\n");
allow_insecure = parse_webpa_url (get_parodus_cfg()->webpa_url, server_Address, (int) sizeof(server_Address), port, (int) sizeof(port));
}
else
{
if( (jwt_server_url != NULL) && strlen(jwt_server_url) != 0 )
{
ParodusInfo("acquire_jwt is 1, retrying with jwt_server_url\n");
parStrncpy(server_Address, jwt_server_url, sizeof(server_Address));
}
else
{
ParodusError("acquire_jwt is 1 & unable to get jwt_server_url, retrying with config server address\n");
allow_insecure = parse_webpa_url (get_parodus_cfg()->webpa_url, server_Address, (int) sizeof(server_Address), port, (int) sizeof(port));
}
}
ParodusInfo("Waiting with backoffRetryTime %d seconds\n", backoffRetryTime);
sleep(backoffRetryTime);
toggleIPFlag(&fallback);
c++;
}
//reset httpStatus before next retry
ParodusPrint("reset httpStatus from server before next retry\n");
status = 0;
close_and_unref_connection(get_global_conn());
set_global_conn(NULL);
initial_retry = true;
}
else
{
initial_retry = false;
ParodusInfo("Connection is ready\n");
}
}
else
{
/* If the connect error is due to DNS resolving to 10.0.0.1 then start timer.
* Timeout after 15 minutes if the error repeats continuously and kill itself.
*/
if((checkHostIp(server_Address) == -2))
{
if(connErr == 0)
{
getCurrentTime(connErr_startPtr);
connErr = 1;
ParodusInfo("First connect error occurred, initialized the connect error timer\n");
}
else
{
getCurrentTime(connErr_endPtr);
ParodusPrint("checking timeout difference:%ld\n", timeValDiff(connErr_startPtr, connErr_endPtr));
if(timeValDiff(connErr_startPtr, connErr_endPtr) >= (15*60*1000))
{
ParodusError("WebPA unable to connect due to DNS resolving to 10.0.0.1 for over 15 minutes; crashing service.\n");
set_global_reconnect_reason("Dns_Res_webpa_reconnect");
set_global_reconnect_status(true);
kill(getpid(),SIGTERM);
}
}
}
initial_retry = true;
toggleIPFlag(&fallback);
ParodusInfo("Waiting with backoffRetryTime %d seconds\n", backoffRetryTime);
sleep(backoffRetryTime);
c++;
// Copy the server address and port from config to avoid retrying to the same failing talaria redirected node
if (get_parodus_cfg()->acquire_jwt == 0)
{
ParodusInfo("acquire_jwt is 0, retrying with config server address\n");
allow_insecure = parse_webpa_url (get_parodus_cfg()->webpa_url, server_Address, (int) sizeof(server_Address), port, (int) sizeof(port));
}
else
{
if( (jwt_server_url != NULL) && strlen(jwt_server_url) != 0 )
{
ParodusInfo("acquire_jwt is 1, retrying with jwt_server_url\n");
parStrncpy(server_Address, jwt_server_url, sizeof(server_Address));
}
else
{
ParodusError("acquire_jwt is 1 & unable to get jwt_server_url, retrying with config server address\n");
allow_insecure = parse_webpa_url (get_parodus_cfg()->webpa_url, server_Address, (int) sizeof(server_Address), port, (int) sizeof(port));
}
}
}
}while(initial_retry);
if(allow_insecure <= 0)
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))
break;
// retry dns query
}
if(conn_ctx.current_server->allow_insecure <= 0)
{
ParodusInfo("Connected to server over SSL\n");
}
@@ -418,40 +576,29 @@ int createNopollConnection(noPollCtx *ctx)
ParodusInfo("Connected to server\n");
}
if (NULL != jwt_server_url)
{
free (jwt_server_url);
get_parodus_cfg()->cloud_status = CLOUD_STATUS_ONLINE;
ParodusInfo("cloud_status set as %s after successful connection\n", get_parodus_cfg()->cloud_status);
if(get_parodus_cfg()->boot_time != 0) {
getCurrentTime(connectTimePtr);
ParodusInfo("connect_time-diff-boot_time=%d\n", connectTimePtr->tv_sec - get_parodus_cfg()->boot_time);
}
if(redirectURL != NULL)
{
free(redirectURL);
redirectURL = NULL;
}
if (NULL != extra_headers)
{
free (extra_headers);
extra_headers = NULL;
}
free_extra_headers (&conn_ctx);
free_header_info (&conn_ctx.header_info);
free_server_list (&conn_ctx.server_list);
// Reset close_retry flag and heartbeatTimer once the connection retry is successful
ParodusPrint("createNopollConnection(): close_mut lock\n");
pthread_mutex_lock (&close_mut);
close_retry = false;
pthread_mutex_unlock (&close_mut);
ParodusPrint("createNopollConnection(): close_mut unlock\n");
ParodusPrint("createNopollConnection(): reset_close_retry\n");
reset_close_retry();
reset_heartBeatTimer();
// Reset connErr flag on successful connection
connErr = 0;
set_global_reconnect_reason("webpa_process_starts");
set_global_reconnect_status(false);
ParodusPrint("LastReasonStatus reset after successful connection\n");
setMessageHandlers();
return nopoll_true;
}
}
/* Build the extra headers string with any/all conditional logic in one place. */
static char* build_extra_headers( const char *auth, const char *device_id,
@@ -472,51 +619,6 @@ static char* build_extra_headers( const char *auth, const char *device_id,
(NULL != convey) ? convey : "" );
}
static noPollConn * nopoll_tls_common_conn (noPollCtx * ctx,char * serverAddr,char *serverPort,char * extra_headers,unsigned int *fallback)
{
unsigned int flags = 0;
noPollConnOpts * opts;
noPollConn *connection = NULL;
opts = createConnOpts(extra_headers, true);
flags = get_parodus_cfg()->flags;
if( FLAGS_IPV4_ONLY == (FLAGS_IPV4_ONLY & flags) ) {
ParodusInfo("Connecting in Ipv4 mode\n");
connection = nopoll_conn_tls_new (ctx, opts,serverAddr,serverPort,NULL,get_parodus_cfg()->webpa_path_url,NULL,NULL);
} else if( FLAGS_IPV6_ONLY == (FLAGS_IPV6_ONLY & flags) ) {
ParodusInfo("Connecting in Ipv6 mode\n");
connection = nopoll_conn_tls_new6 (ctx, opts,serverAddr,serverPort,NULL,get_parodus_cfg()->webpa_path_url,NULL,NULL);
} else {
connection = __internal_fallbackConn(ctx,opts,serverAddr,serverPort,extra_headers,fallback);
}
return connection;
}
static noPollConn * __internal_fallbackConn(noPollCtx * ctx,noPollConnOpts * opts,char * serverAddr,char *serverPort,char * extra_headers,unsigned int *fallback)
{
noPollConn *connection = NULL;
if(FLAGS_IPV6_ONLY == (FLAGS_IPV6_IPV4 & *fallback))
{
ParodusInfo("Try connecting with Ipv6 mode\n");
connection = nopoll_conn_tls_new6 (ctx, opts,serverAddr,serverPort,NULL,get_parodus_cfg()->webpa_path_url,NULL,NULL);
}
if(FLAGS_IPV4_ONLY == (FLAGS_IPV6_IPV4 & *fallback) || !nopoll_conn_is_ok (connection) )
{
ParodusInfo("Ipv6 connection failed. Try connecting with Ipv4 mode \n");
// fallback is to detect the current connection mode either IPv6/IPv4. if the fallback flag is true for IPv6 connection, then change it here to IPv4. or if the fallback flag is already in IPv4 mode, then skip it.
if(!nopoll_conn_is_ok (connection) && FLAGS_IPV6_ONLY == (FLAGS_IPV6_IPV4 & *fallback))
toggleIPFlag(fallback);
opts = createConnOpts(extra_headers, true);
connection = nopoll_conn_tls_new (ctx, opts,serverAddr,serverPort,NULL,get_parodus_cfg()->webpa_path_url,NULL,NULL);
}
return connection;
}
static noPollConnOpts * createConnOpts (char * extra_headers, bool secure)
{

View File

@@ -34,8 +34,6 @@ extern "C" {
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
extern bool close_retry;
extern pthread_mutex_t close_mut;
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
@@ -57,6 +55,8 @@ void set_global_reconnect_reason(char *reason);
bool get_global_reconnect_status();
void set_global_reconnect_status(bool status);
int get_cloud_disconnect_time();
void set_cloud_disconnect_time(int disconnTime);
#ifdef __cplusplus
}
#endif

View File

@@ -42,8 +42,6 @@ typedef struct CrudMsg__
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
//void *CRUDHandlerTask();
//void addCRUDmsgToQueue(wrp_msg_t *crudMsg);
void addCRUDresponseToUpstreamQ(void *response_bytes, ssize_t response_size);
#ifdef __cplusplus

View File

@@ -24,11 +24,15 @@
#include "crud_tasks.h"
#include "crud_internal.h"
#include "config.h"
#include "connection.h"
#include "close_retry.h"
static void freeObjArray(char *(*obj)[], int size);
static int writeIntoCrudJson(cJSON *res_obj, char * object, cJSON *objValue, int freeFlag);
static int parse_dest_elements_to_string(wrp_msg_t *reqMsg, char *(*obj)[]);
static char* strdupptr( const char *s, const char *e );
static int ConnDisconnectFromCloud(char *reason);
static int validateDisconnectString(char *reason);
int writeToJSON(char *data)
{
@@ -582,6 +586,24 @@ int retrieveFromMemory(char *keyName, cJSON **jsonresponse)
ParodusInfo("retrieveFromMemory: keyName:%s value:%s\n",keyName,get_parodus_cfg()->webpa_uuid);
cJSON_AddItemToObject( *jsonresponse, WEBPA_UUID , cJSON_CreateString(get_parodus_cfg()->webpa_uuid));
}
else if(strcmp(CLOUD_STATUS, keyName)==0)
{
if(get_parodus_cfg()->cloud_status ==NULL)
{
ParodusError("retrieveFromMemory: cloud_status value is NULL\n");
return -1;
}
else if((get_parodus_cfg()->cloud_status !=NULL) && (strlen(get_parodus_cfg()->cloud_status)==0))
{
ParodusError("retrieveFromMemory: cloud_status value is empty\n");
return -1;
}
else
{
ParodusInfo("retrieveFromMemory: keyName:%s value:%s\n", keyName, get_parodus_cfg()->cloud_status);
cJSON_AddItemToObject( *jsonresponse, CLOUD_STATUS , cJSON_CreateString(get_parodus_cfg()->cloud_status));
}
}
else if(strcmp(BOOT_TIME, keyName)==0)
{
ParodusInfo("retrieveFromMemory: keyName:%s value:%d\n",keyName,get_parodus_cfg()->boot_time);
@@ -852,8 +874,10 @@ int updateObject( wrp_msg_t *reqMsg, wrp_msg_t **response )
int jsontagitemSize = 0, value =0;
char *key = NULL, *testkey = NULL;
const char *parse_error = NULL;
int status =0;
int status =0, valid =0;
int expireFlag = 0;
int disconnStatus = 0;
char *disconn_str = NULL;
status = readFromJSON(&jsonData);
ParodusPrint("read status %d\n", status);
@@ -1188,12 +1212,121 @@ int updateObject( wrp_msg_t *reqMsg, wrp_msg_t **response )
}
else
{
// Return error for request format other than parodus/tag/${name}
ParodusError("Invalid UPDATE request\n");
(*response)->u.crud.status = 400;
freeObjArray(&obj, objlevel);
cJSON_Delete( json );
return -1;
//Checks for parodus/cloud-disconnect request with objlevel = 3
if(objlevel == 3 && ((obj[3] != NULL) && (strcmp(obj[3] , "cloud-disconnect") == 0)))
{
if(reqMsg->u.crud.payload != NULL)
{
jsonPayload = cJSON_Parse( reqMsg->u.crud.payload );
if(jsonPayload !=NULL)
{
if((cJSON_GetObjectItem( jsonPayload, CLOUD_DISCONNECT_REASON )) !=NULL)
{
if (cJSON_String == cJSON_GetObjectItem( jsonPayload, CLOUD_DISCONNECT_REASON )->type)
{
disconn_str = cJSON_GetObjectItem( jsonPayload, CLOUD_DISCONNECT_REASON )->valuestring;
if (disconn_str != NULL && strlen(disconn_str) == 0)
{
ParodusError("Invalid cloud-disconnect request. disconnect reason is NULL\n");
(*response)->u.crud.status = 400;
cJSON_Delete( jsonPayload );
jsonPayload = NULL;
cJSON_Delete(json);
json = NULL;
freeObjArray(&obj, objlevel);
return -1;
}
else
{
//check disconnection reason is character string of [a-zA-Z0-9 ]*
valid = validateDisconnectString(disconn_str);
if(valid >0)
{
//set the disconnection reason value to in-memory
set_cloud_disconnect_reason(get_parodus_cfg(), disconn_str);
ParodusInfo("set cloud-disconnect reason as %s \n", get_parodus_cfg()->cloud_disconnect);
}
else
{
ParodusError("Invalid cloud-disconnect request. disconnect reason is not alphanumeric\n");
(*response)->u.crud.status = 400;
cJSON_Delete( jsonPayload );
jsonPayload = NULL;
cJSON_Delete(json);
json = NULL;
freeObjArray(&obj, objlevel);
return -1;
}
}
}
else
{
ParodusError("Invalid cloud-disconnect request, disconnect reason is not string\n");
(*response)->u.crud.status = 400;
cJSON_Delete( jsonPayload );
jsonPayload = NULL;
cJSON_Delete(json);
json = NULL;
freeObjArray(&obj, objlevel);
return -1;
}
}
else
{
ParodusError("Invalid cloud-disconnect request, disconnection-reason not found\n");
(*response)->u.crud.status = 400;
freeObjArray(&obj, objlevel);
cJSON_Delete( jsonPayload );
jsonPayload = NULL;
cJSON_Delete( json);
return -1;
}
cJSON_Delete( jsonPayload );
jsonPayload = NULL;
}
else
{
ParodusError("Invalid cloud-disconnect request, payload is not json\n");
(*response)->u.crud.status = 400;
freeObjArray(&obj, objlevel);
cJSON_Delete( json);
return -1;
}
}
else
{
ParodusInfo("cloud-disconnect failed as payload is NULL\n");
(*response)->u.crud.status = 400;
freeObjArray(&obj, objlevel);
return -1;
}
char *reason = strdup(get_parodus_cfg()->cloud_disconnect);
disconnStatus = ConnDisconnectFromCloud(reason);
freeObjArray(&obj, objlevel);
cJSON_Delete( json );
if (disconnStatus >0)
{
ParodusInfo("Sending update response for cloud-disconnect\n");
(*response)->u.crud.status = 200;
}
else
{
ParodusInfo("Failure in disconnecting from cloud ..\n");
(*response)->u.crud.status = 500;
return -1;
}
}
else
{
// Return error for request format other than parodus/tag/${name}
ParodusError("Invalid UPDATE request\n");
(*response)->u.crud.status = 400;
freeObjArray(&obj, objlevel);
cJSON_Delete( json );
return -1;
}
}
}
else
@@ -1206,6 +1339,24 @@ int updateObject( wrp_msg_t *reqMsg, wrp_msg_t **response )
return 0;
}
static int ConnDisconnectFromCloud(char *disconn_reason)
{
bool close_retry = false;
close_retry = get_close_retry();
if(!close_retry)
{
ParodusInfo("Reconnect detected, setting reason %s for Reconnect\n", disconn_reason);
set_global_reconnect_reason(disconn_reason);
set_global_reconnect_status(true);
set_close_retry();
}
else
{
ParodusInfo("close_retry is %d, connection close and retrying is already in progress\n", close_retry);
return -1;
}
return 1;
}
int deleteObject( wrp_msg_t *reqMsg, wrp_msg_t **response )
{
@@ -1387,7 +1538,7 @@ static int parse_dest_elements_to_string(wrp_msg_t *reqMsg, char *(*obj)[])
for( i = 0; i <= WRP_ID_ELEMENT__APPLICATION; i++ )
{
(*obj)[i] = wrp_get_msg_dest_element(i, reqMsg);
(*obj)[i] = wrp_get_msg_element(i, reqMsg, DEST);
if((*obj)[i] ==NULL)
{
break;
@@ -1450,3 +1601,29 @@ static char* strdupptr( const char *s, const char *e )
return strndup(s, (size_t) (((uintptr_t)e) - ((uintptr_t)s)));
}
static int validateDisconnectString(char *reason)
{
int k=0, rv =1;
if(reason !=NULL && strlen(reason) >0 )
{
for( k = 0; k < (int)strlen(reason); k++ )
{
if ((isalpha(reason[k])) || ((isdigit(reason[k])) != 0))
{
ParodusPrint("disconnection string is valid\n");
}
else
{
ParodusError("disconnection string is Invalid\n");
rv = -1;
break;
}
}
}
else
{
rv = -1;
}
return rv;
}

View File

@@ -75,6 +75,7 @@ void listenerOnMessage(void * msg, size_t msgSize)
case WRP_MSG_TYPE__AUTH:
{
ParodusInfo("Authorization Status received with Status code :%d\n", message->u.auth.status);
wrp_free_struct(message);
break;
}
@@ -90,7 +91,7 @@ void listenerOnMessage(void * msg, size_t msgSize)
if(ret < 0)
{
response = cJSON_CreateObject();
cJSON_AddNumberToObject(response, "statusCode", 430);
cJSON_AddNumberToObject(response, "statusCode", 403);
cJSON_AddStringToObject(response, "message", "Invalid partner_id");
}

View File

@@ -103,7 +103,7 @@ static void sig_handler(int sig)
{
signal(SIGINT, sig_handler); /* reset it to this function */
ParodusInfo("SIGINT received!\n");
exit(0);
shutdownSocketConnection();
}
else if ( sig == SIGUSR1 )
{
@@ -132,7 +132,7 @@ static void sig_handler(int sig)
else
{
ParodusInfo("Signal %d received!\n", sig);
exit(0);
shutdownSocketConnection();
}
}

View File

@@ -25,6 +25,7 @@
#include "nopoll_handlers.h"
#include "connection.h"
#include "heartBeat.h"
#include "close_retry.h"
/*----------------------------------------------------------------------------*/
/* Macros */
@@ -175,9 +176,7 @@ void listenerOnCloseMessage (noPollCtx * ctx, noPollConn * conn, noPollPtr user_
set_global_reconnect_reason("Unknown");
}
pthread_mutex_lock (&close_mut);
close_retry = true;
pthread_mutex_unlock (&close_mut);
set_close_retry();
ParodusPrint("listenerOnCloseMessage(): mutex unlock in producer thread\n");
}

View File

@@ -36,8 +36,6 @@ extern "C" {
extern pthread_mutex_t g_mutex;
extern pthread_cond_t g_cond;
extern pthread_mutex_t close_mut;
extern bool close_retry;
/*----------------------------------------------------------------------------*/
/* Function Prototypes */

View File

@@ -39,85 +39,183 @@
/*----------------------------------------------------------------------------*/
/* External functions */
/*----------------------------------------------------------------------------*/
static void parse_partner_id(char *partnerId, partners_t **partnersList)
{
char *token;
int i = 0, j = 0, count = 0;
ParodusPrint("********* %s ********\n",__FUNCTION__);
while(partnerId[i] != '\0')
{
if(partnerId[i] == ',')
{
count++;
}
i++;
}
ParodusPrint("count = %d\n", count+1);
*partnersList = (partners_t *)malloc(sizeof(partners_t)+ sizeof( char * ) * (count+1));
memset(*partnersList, 0, sizeof(partners_t));
(*partnersList)->count = count+1;
while ((token = strsep(&partnerId, ",")) != NULL)
{
ParodusPrint("token=%s\n", token);
(*partnersList)->partner_ids[j] = strdup(token);
ParodusPrint("(*partnersList)->partner_ids[%d] = %s\n",j,(*partnersList)->partner_ids[j]);
j++;
}
}
int validate_partner_id(wrp_msg_t *msg, partners_t **partnerIds)
{
int matchFlag = 0, i = 0, count = 0;
size_t j = 0;
partners_t *partnersList = NULL;
char *partnerId = NULL;
ParodusPrint("********* %s ********\n",__FUNCTION__);
char *partnerId = get_parodus_cfg()->partner_id;
if(strlen(partnerId) <= 0)
char *temp = get_parodus_cfg()->partner_id;
ParodusPrint("temp = %s\n",temp);
if(temp[0] != '\0' && strlen(temp) > 0)
{
partnerId = strdup(temp);
}
ParodusPrint("partnerId = %s\n",partnerId);
if(partnerId != NULL)
{
parse_partner_id(partnerId, &partnersList);
ParodusPrint("partnersList->count = %lu\n", partnersList->count);
if(msg->msg_type == WRP_MSG_TYPE__EVENT)
{
if(msg->u.event.partner_ids != NULL)
{
count = (int) msg->u.event.partner_ids->count;
ParodusPrint("partner_ids count is %d\n",count);
for(i = 0; i < count; i++)
{
for(j = 0; j<partnersList->count; j++)
{
if(NULL != partnersList->partner_ids[j]) {
ParodusPrint("partnersList->partner_ids[%lu] = %s\n",j, partnersList->partner_ids[j]);
ParodusPrint("msg->u.event.partner_ids->partner_ids[%lu] = %s\n",i, msg->u.event.partner_ids->partner_ids[i]);
if(strcasecmp(partnersList->partner_ids[j], msg->u.event.partner_ids->partner_ids[i]) == 0)
{
ParodusInfo("partner_id match found\n");
matchFlag = 1;
break;
}
}
else
ParodusError("partner Id in partnersList is NULL but count is not 0");
}
/* Commandline input partner_ids matched with partner_ids from request */
if(matchFlag == 1)
{
break;
}
}
/* Commandline input partner_ids not matching with partner_ids from request, appending to request partner_ids*/
if(matchFlag != 1)
{
(*partnerIds) = (partners_t *) malloc(sizeof(partners_t) + (sizeof(char *) * (count+partnersList->count)));
(*partnerIds)->count = count+partnersList->count;
for(i = 0; i < count; i++)
{
(*partnerIds)->partner_ids[i] = msg->u.event.partner_ids->partner_ids[i];
ParodusPrint("(*partnerIds)->partner_ids[%d] : %s\n",i,(*partnerIds)->partner_ids[i]);
}
i = 0;
for(j = count; j<(count+partnersList->count); j++)
{
(*partnerIds)->partner_ids[j] = (char *) malloc(sizeof(char) * 64);
parStrncpy((*partnerIds)->partner_ids[j], partnersList->partner_ids[i], 64);
ParodusPrint("(*partnerIds)->partner_ids[%lu] : %s\n",j,(*partnerIds)->partner_ids[j]);
i++;
}
}
}
else
{
ParodusPrint("partner_ids list is NULL\n");
(*partnerIds) = (partners_t *) malloc(sizeof(partners_t) + (sizeof(char *) * partnersList->count));
(*partnerIds)->count = partnersList->count;
i=0;
for(j = 0; j<partnersList->count; j++)
{
(*partnerIds)->partner_ids[j] = (char *) malloc(sizeof(char) * 64);
parStrncpy((*partnerIds)->partner_ids[j], partnersList->partner_ids[i], 64);
ParodusPrint("(*partnerIds)->partner_ids[%lu] : %s\n",j,(*partnerIds)->partner_ids[j]);
i++;
}
}
}
else if(msg->msg_type == WRP_MSG_TYPE__REQ)
{
if(msg->u.req.partner_ids != NULL)
{
count = (int) msg->u.req.partner_ids->count;
ParodusPrint("partner_ids count is %d\n",count);
for(i = 0; i < count; i++)
{
for(j = 0; j<partnersList->count; j++)
{
if(NULL != partnersList->partner_ids[j])
{
ParodusPrint("partnersList->partner_ids[%lu] = %s\n",j, partnersList->partner_ids[j]);
ParodusPrint("msg->u.req.partner_ids->partner_ids[%lu] = %s\n",i, msg->u.req.partner_ids->partner_ids[i]);
if(strcasecmp(partnersList->partner_ids[j], msg->u.req.partner_ids->partner_ids[i]) == 0)
{
ParodusInfo("partner_id match found\n");
matchFlag = 1;
break;
}
}
else
ParodusError("partner Id in partnersList is NULL but count is not 0");
}
}
/* Commandline input partner_ids not matching with partner_ids from request, ignoring request*/
if(matchFlag != 1)
{
ParodusError("Invalid partner_id %s\n",temp);
if(partnersList != NULL)
{
for(j=0; j<partnersList->count; j++)
{
if(NULL != partnersList->partner_ids[j])
{
free(partnersList->partner_ids[j]);
}
}
free(partnersList);
}
free(partnerId);
return -1;
}
}
else
{
ParodusPrint("partner_ids list is NULL\n");
}
}
if(partnersList != NULL)
{
for(j=0; j<partnersList->count; j++)
{
if(NULL != partnersList->partner_ids[j])
{
free(partnersList->partner_ids[j]);
}
}
free(partnersList);
}
free(partnerId);
}
else
{
ParodusPrint("partner_id is not available to validate\n");
return 0;
}
if(msg->msg_type == WRP_MSG_TYPE__EVENT)
{
if(msg->u.event.partner_ids != NULL)
{
count = (int) msg->u.event.partner_ids->count;
ParodusPrint("partner_ids count is %d\n",count);
for(i = 0; i < count; i++)
{
if(strcmp(partnerId, msg->u.event.partner_ids->partner_ids[i]) == 0)
{
ParodusInfo("partner_id match found\n");
matchFlag = 1;
break;
}
}
if(matchFlag != 1)
{
(*partnerIds) = (partners_t *) malloc(sizeof(partners_t) + (sizeof(char *) * (count+1)));
(*partnerIds)->count = count+1;
for(i = 0; i < count; i++)
{
(*partnerIds)->partner_ids[i] = msg->u.event.partner_ids->partner_ids[i];
ParodusPrint("(*partnerIds)->partner_ids[%d] : %s\n",i,(*partnerIds)->partner_ids[i]);
}
(*partnerIds)->partner_ids[count] = (char *) malloc(sizeof(char) * 64);
parStrncpy((*partnerIds)->partner_ids[count], partnerId, 64);
ParodusPrint("(*partnerIds)->partner_ids[%d] : %s\n",count,(*partnerIds)->partner_ids[count]);
}
}
else
{
ParodusPrint("partner_ids list is NULL\n");
(*partnerIds) = (partners_t *) malloc(sizeof(partners_t) + (sizeof(char *) * 1));
(*partnerIds)->count = 1;
(*partnerIds)->partner_ids[0] = (char *) malloc(sizeof(char) * 64);
parStrncpy((*partnerIds)->partner_ids[0], partnerId, 64);
ParodusPrint("(*partnerIds)->partner_ids[0] : %s\n",(*partnerIds)->partner_ids[0]);
}
}
else if(msg->msg_type == WRP_MSG_TYPE__REQ)
{
if(msg->u.req.partner_ids != NULL)
{
count = (int) msg->u.req.partner_ids->count;
ParodusPrint("partner_ids count is %d\n",count);
for(i = 0; i < count; i++)
{
if(strcmp(partnerId, msg->u.req.partner_ids->partner_ids[i]) == 0)
{
ParodusInfo("partner_id match found\n");
matchFlag = 1;
break;
}
}
if(matchFlag != 1)
{
ParodusError("Invalid partner_id %s\n",partnerId);
return -1;
}
}
else
{
ParodusPrint("partner_ids list is NULL\n");
}
}
return 1;
}

View File

@@ -111,8 +111,7 @@ static void show_times (time_t exp_time, time_t cur_time)
}
// returns 1 if insecure, 0 if secure, < 0 if error
int analyze_jwt (const cjwt_t *jwt, char *url_buf, int url_buflen,
char *port_buf, int port_buflen)
int analyze_jwt (const cjwt_t *jwt, char **url_buf, unsigned int *port)
{
cJSON *claims = jwt->private_claims;
cJSON *endpoint = NULL;
@@ -144,7 +143,7 @@ int analyze_jwt (const cjwt_t *jwt, char *url_buf, int url_buflen,
}
}
http_match = parse_webpa_url (endpoint->valuestring,
url_buf, url_buflen, port_buf, port_buflen);
url_buf, port);
if (http_match < 0) {
ParodusError ("Invalid endpoint claim in JWT\n");
return TOKEN_ERR_BAD_ENDPOINT;
@@ -474,8 +473,7 @@ static void get_dns_txt_record_id (char *buf)
}
#endif
int allow_insecure_conn(char *url_buf, int url_buflen,
char *port_buf, int port_buflen)
int allow_insecure_conn(char **server_addr, unsigned int *port)
{
#ifdef FEATURE_DNS_QUERY
int insecure=0, ret = -1;
@@ -523,7 +521,7 @@ int allow_insecure_conn(char *url_buf, int url_buflen,
//validate algo from --jwt_algo
if( validate_algo(jwt) ) {
insecure = analyze_jwt (jwt, url_buf, url_buflen, port_buf, port_buflen);
insecure = analyze_jwt (jwt, server_addr, port);
} else {
insecure = TOKEN_ERR_ALGO_NOT_ALLOWED;
}
@@ -537,10 +535,8 @@ end:
if (NULL != jwt_token)
free (jwt_token);
#else
(void) url_buf;
(void) url_buflen;
(void) port_buf;
(void) port_buflen;
(void) server_addr;
(void) port;
int insecure = TOKEN_NO_DNS_QUERY;
#endif
ParodusPrint ("Allow Insecure %d\n", insecure);

View File

@@ -78,15 +78,13 @@ Yes Yes http True Default
* query the dns server, obtain a jwt, determine if insecure
* connections can be allowed.
*
* @param url_buf buffer containing endpoint value found in JWT
* @param url_buflen len of the url buffer provided by caller
* @param port_buf buffer containing port value found in JWT
* @param port_buflen len of the port buffer provided by caller
* @param server_addr ptr to buffer ptr containing endpoint value found in JWT
* will be NULL if invalid, otherwise needs to be freed
* @param port ptr to variable receiving the port number
* @return 1 if insecure connection is allowed, 0 if not,
* or one of the error codes given above.
*/
int allow_insecure_conn(char *url_buf, int url_buflen,
char *port_buf, int port_buflen);
int allow_insecure_conn (char **server_addr, unsigned int *port);
#endif

View File

@@ -28,12 +28,13 @@
#include "connection.h"
#include "client_list.h"
#include "nopoll_helpers.h"
#include "close_retry.h"
/*----------------------------------------------------------------------------*/
/* Macros */
/*----------------------------------------------------------------------------*/
#define METADATA_COUNT 12
#define CLOUD_STATUS_FORMAT "parodus/cloud-status"
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
@@ -191,11 +192,16 @@ void *processUpstreamMessage()
{
int rv=-1, rc = -1;
int msgType;
wrp_msg_t *msg;
wrp_msg_t *msg,*retrieve_msg = NULL;
void *bytes;
reg_list_item_t *temp = NULL;
int matchFlag = 0;
int status = -1;
char *serviceName = NULL;
char *macId = NULL;
char *destService, *destApplication =NULL;
char *sourceService, *sourceApplication =NULL;
int sendStatus =-1;
while(FOREVER())
{
@@ -288,6 +294,7 @@ void *processUpstreamMessage()
{
ParodusInfo(" Received upstream event data: dest '%s'\n", msg->u.event.dest);
partners_t *partnersList = NULL;
int j = 0;
int ret = validate_partner_id(msg, &partnersList);
if(ret == 1)
@@ -316,27 +323,126 @@ void *processUpstreamMessage()
{
sendUpstreamMsgToServer(&message->msg, message->len);
}
if(partnersList != NULL)
{
for(j=0; j<(int)partnersList->count; j++)
{
if(NULL != partnersList->partner_ids[j])
{
free(partnersList->partner_ids[j]);
}
}
free(partnersList);
}
partnersList = NULL;
}
else
{
//Sending to server for msgTypes 3, 5, 6, 7, 8.
if( WRP_MSG_TYPE__REQ == msgType ) {
ParodusInfo(" Received upstream data with MsgType: %d dest: '%s' transaction_uuid: %s\n",
msgType, msg->u.req.dest, msg->u.req.transaction_uuid );
} else {
ParodusInfo(" Received upstream data with MsgType: %d dest: '%s' transaction_uuid: %s status: %d\n",
msgType, msg->u.crud.dest, msg->u.crud.transaction_uuid, msg->u.crud.status );
}
sendUpstreamMsgToServer(&message->msg, message->len);
}
}
//Sending to server for msgTypes 3, 5, 6, 7, 8.
if( WRP_MSG_TYPE__REQ == msgType )
{
ParodusInfo(" Received upstream data with MsgType: %d dest: '%s' transaction_uuid: %s\n", msgType, msg->u.req.dest, msg->u.req.transaction_uuid );
sendUpstreamMsgToServer(&message->msg, message->len);
}
else
{
ParodusInfo(" Received upstream data with MsgType: %d dest: '%s' transaction_uuid: %s status: %d\n",msgType, msg->u.crud.dest, msg->u.crud.transaction_uuid, msg->u.crud.status );
if(WRP_MSG_TYPE__RETREIVE == msgType && msg->u.crud.dest !=NULL && msg->u.crud.source != NULL)
{
macId = wrp_get_msg_element(WRP_ID_ELEMENT__ID, msg, DEST);
destService = wrp_get_msg_element(WRP_ID_ELEMENT__SERVICE, msg, DEST);
destApplication = wrp_get_msg_element(WRP_ID_ELEMENT__APPLICATION, msg, DEST);
sourceService = wrp_get_msg_element(WRP_ID_ELEMENT__SERVICE, msg, SOURCE);
sourceApplication = wrp_get_msg_element(WRP_ID_ELEMENT__APPLICATION, msg, SOURCE);
/* Handle cloud-status retrieve request here
Expecting dest format as mac:xxxxxxxxxxxx/parodus/cloud-status
Parse dest field and check destService is "parodus" and destApplication is "cloud-status"
*/
if(macId != NULL)
{
if(destService != NULL && destApplication != NULL && strcmp(destService,"parodus")== 0 && strcmp(destApplication,"cloud-status")== 0)
{
retrieve_msg = ( wrp_msg_t *)malloc( sizeof( wrp_msg_t ) );
memset(retrieve_msg, 0, sizeof(wrp_msg_t));
retrieve_msg->msg_type = msg->msg_type;
retrieve_msg->u.crud.transaction_uuid = strdup(msg->u.crud.transaction_uuid);
retrieve_msg->u.crud.source = strdup(msg->u.crud.source);
retrieve_msg->u.crud.dest = strdup(msg->u.crud.dest);
addCRUDmsgToQueue(retrieve_msg);
}
else if(sourceService != NULL && sourceApplication != NULL && strcmp(sourceService,"parodus")== 0 && strcmp(sourceApplication,"cloud-status")== 0 && strncmp(msg->u.crud.dest,"mac:", 4)==0)
{
/* Handle cloud-status retrieve response here to send it to registered client
Expecting src format as mac:xxxxxxxxxxxx/parodus/cloud-status and dest as mac:
Parse src field and check sourceService is "parodus" and sourceApplication is "cloud-status"
*/
serviceName = wrp_get_msg_element(WRP_ID_ELEMENT__SERVICE, msg, DEST);
if ( serviceName != NULL)
{
//Send Client cloud-status response back to registered client
ParodusInfo("Sending cloud-status response to %s client\n",serviceName);
sendStatus=sendMsgtoRegisteredClients(serviceName,(const char **)&message->msg,message->len);
if(sendStatus ==1)
{
ParodusInfo("Send upstreamMsg successfully to registered client %s\n", serviceName);
}
else
{
ParodusError("Failed to send upstreamMsg to registered client %s\n", serviceName);
}
free(serviceName);
serviceName = NULL;
}
else
{
ParodusError("serviceName is NULL,not sending cloud-status response to client\n");
}
}
else
{
ParodusInfo("sendUpstreamMsgToServer \n");
sendUpstreamMsgToServer(&message->msg, message->len);
}
}
else
{
ParodusError("MAC is null, not handling retrieve wrp message \n");
}
if(sourceService !=NULL)
{
free(sourceService);
sourceService = NULL;
}
if(sourceApplication !=NULL)
{
free(sourceApplication);
sourceApplication = NULL;
}
if(destService !=NULL)
{
free(destService);
destService = NULL;
}
if(destApplication !=NULL)
{
free(destApplication);
destApplication = NULL;
}
}
else
{
sendUpstreamMsgToServer(&message->msg, message->len);
}
}
}
}
else
{
ParodusError("Error in msgpack decoding for upstream\n");
}
//nn_freemsg should not be done for parodus/tags/ CRUD requests as it is not received through nanomsg.
if ((msg && (msg->u.crud.source !=NULL) && strstr(msg->u.crud.source, "parodus") != NULL))
if ((msg && (msg->u.crud.source !=NULL) && wrp_does_service_match("parodus", msg->u.crud.source) == 0))
{
free(message->msg);
}
@@ -370,6 +476,7 @@ void sendUpstreamMsgToServer(void **resp_bytes, size_t resp_size)
{
void *appendData;
size_t encodedSize;
bool close_retry = false;
//appending response with metadata
if(metaPackSize > 0)
{
@@ -378,8 +485,18 @@ void sendUpstreamMsgToServer(void **resp_bytes, size_t resp_size)
ParodusPrint("encodedSize after appending :%zu\n", encodedSize);
ParodusInfo("Sending response to server\n");
sendMessage(get_global_conn(),appendData, encodedSize);
close_retry = get_close_retry();
/* send response when connection retry is not in progress. Also during cloud_disconnect UPDATE request. Here, close_retry becomes 1 hence check is added to send disconnect response to server. */
//TODO: Upstream and downstream messages in queue should be handled and queue should be empty before parodus forcefully disconnect from cloud.
if(!close_retry || (get_parodus_cfg()->cloud_disconnect !=NULL))
{
sendMessage(get_global_conn(),appendData, encodedSize);
}
else
{
ParodusInfo("close_retry is %d, unable to send response as connection retry is in progress\n", close_retry);
}
free(appendData);
appendData =NULL;
}

View File

@@ -25,7 +25,7 @@
#define _UPSTREAM_H_
#include <pthread.h>
#include <wrp-c.h>
#ifdef __cplusplus
extern "C" {
#endif

View File

@@ -18,7 +18,7 @@ set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -W -g -fprofile-arcs -ftest-cove
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_LIBS gcov -lcunit -lcimplog -lwrp-c
-luuid -lpthread -lmsgpackc -lnopoll -lnanomsg
-luuid -lmsgpackc -lnopoll -lnanomsg -lpthread
-Wl,--no-as-needed -lcjson -lcjwt -ltrower-base64
-lssl -lcrypto -lrt -lm)
@@ -36,6 +36,20 @@ endif ()
link_directories ( ${LIBRARY_DIR} )
#-------------------------------------------------------------------------------
# test_heartBeatTimer
#-------------------------------------------------------------------------------
add_test(NAME test_heartBeatTimer COMMAND ${MEMORY_CHECK} ./test_heartBeatTimer)
add_executable(test_heartBeatTimer test_heartBeatTimer.c ../src/heartBeat.c)
target_link_libraries (test_heartBeatTimer ${PARODUS_COMMON_LIBS} -lcmocka)
#-------------------------------------------------------------------------------
# test_close_retry
#-------------------------------------------------------------------------------
add_test(NAME test_close_retry COMMAND ${MEMORY_CHECK} ./test_close_retry)
add_executable(test_close_retry test_close_retry.c ../src/close_retry.c)
target_link_libraries (test_close_retry ${PARODUS_COMMON_LIBS} -lcmocka)
#-------------------------------------------------------------------------------
# test_mutex
#-------------------------------------------------------------------------------
@@ -57,26 +71,6 @@ add_test(NAME test_nopoll_helpers COMMAND ${MEMORY_CHECK} ./test_nopoll_helpers)
add_executable(test_nopoll_helpers test_nopoll_helpers.c ../src/nopoll_helpers.c)
target_link_libraries (test_nopoll_helpers -Wl,--no-as-needed -lrt -lcmocka -lcimplog -lnopoll)
#-------------------------------------------------------------------------------
# libpd_test
#-------------------------------------------------------------------------------
add_executable (libpd_test libpd_test.c ../src/string_helpers.c)
target_link_libraries (libpd_test
cunit
-llibparodus
-lwrp-c
-luuid
-lmsgpackc
-ltrower-base64
-lnanomsg
-lcimplog
-lm
-lpthread
-lrt)
if (ENABLE_SESHAT)
target_link_libraries (libpd_test -llibseshat)
endif (ENABLE_SESHAT)
#-------------------------------------------------------------------------------
# test_time
#-------------------------------------------------------------------------------
@@ -109,7 +103,7 @@ target_link_libraries (test_string_helpers ${PARODUS_COMMON_LIBS} )
# test_nopoll_handlers
#-------------------------------------------------------------------------------
add_test(NAME test_nopoll_handlers COMMAND ${MEMORY_CHECK} ./test_nopoll_handlers)
add_executable(test_nopoll_handlers test_nopoll_handlers.c ../src/nopoll_handlers.c ../src/heartBeat.c)
add_executable(test_nopoll_handlers test_nopoll_handlers.c ../src/nopoll_handlers.c ../src/heartBeat.c ../src/close_retry.c)
target_link_libraries (test_nopoll_handlers -lnopoll -lcunit -lcimplog -Wl,--no-as-needed -lrt -lpthread -lm)
@@ -117,29 +111,29 @@ target_link_libraries (test_nopoll_handlers -lnopoll -lcunit -lcimplog -Wl,--no-
# test_nopoll_handlers_fragment
#-------------------------------------------------------------------------------
add_test(NAME test_nopoll_handlers_fragment COMMAND ${MEMORY_CHECK} ./test_nopoll_handlers_fragment)
add_executable(test_nopoll_handlers_fragment test_nopoll_handlers_fragment.c ../src/nopoll_handlers.c ../src/heartBeat.c)
add_executable(test_nopoll_handlers_fragment test_nopoll_handlers_fragment.c ../src/nopoll_handlers.c ../src/heartBeat.c ../src/close_retry.c)
target_link_libraries (test_nopoll_handlers_fragment -lnopoll -lcunit -lcimplog -Wl,--no-as-needed -lrt -lpthread -lm -lcmocka)
#-------------------------------------------------------------------------------
# test_connection
#-------------------------------------------------------------------------------
add_test(NAME test_connection COMMAND ${MEMORY_CHECK} ./test_connection)
#add_executable(test_connection test_connection.c ../src/connection.c ${PARODUS_COMMON_SRC})
#target_link_libraries (test_connection ${PARODUS_COMMON_LIBS} -lcmocka)
set(CONN_SRC test_connection.c ../src/connection.c ../src/heartBeat.c ${PARODUS_COMMON_SRC})
add_executable(test_connection ${CONN_SRC})
#target_link_libraries (test_connection ${PARODUS_CONN_LIBS} ${PARODUS_COMMON_LIBS} -lcmocka)
set (CONN_SRC ../src/connection.c
../src/string_helpers.c ../src/mutex.c ../src/time.c
../src/config.c ../src/spin_thread.c ../src/heartBeat.c ../src/close_retry.c)
#set(CONN_SRC ../src/connection.c ${PARODUS_COMMON_SRC})
add_executable(test_connection test_connection.c ${CONN_SRC})
target_link_libraries (test_connection ${PARODUS_COMMON_LIBS} -lcmocka)
#-------------------------------------------------------------------------------
# test_connection - function createNopollConnection
#-------------------------------------------------------------------------------
add_test(NAME test_createConnection COMMAND ${MEMORY_CHECK} ./test_createConnection)
#add_test(NAME test_createConnection COMMAND ${MEMORY_CHECK} ./test_createConnection)
#add_executable(test_createConnection test_createConnection.c ../src/connection.c ../src/string_helpers.c ../src/config.c)
#target_link_libraries (test_createConnection ${PARODUS_COMMON_LIBS} -lcmocka)
add_executable(test_createConnection test_createConnection.c ../src/connection.c ../src/string_helpers.c ../src/config.c ../src/heartBeat.c)
#add_executable(test_createConnection test_createConnection.c ../src/connection.c ../src/string_helpers.c ../src/config.c ../src/heartBeat.c)
#target_link_libraries (test_createConnection ${PARODUS_CONN_LIBS} ${PARODUS_COMMON_LIBS} -lcmocka )
target_link_libraries (test_createConnection ${PARODUS_COMMON_LIBS} -lcmocka )
#target_link_libraries (test_createConnection ${PARODUS_COMMON_LIBS} -lcmocka )
#-------------------------------------------------------------------------------
# test_client_list
@@ -149,7 +143,7 @@ add_test(NAME test_client_list COMMAND ${MEMORY_CHECK} ./test_client_list)
#target_link_libraries (test_client_list ${PARODUS_COMMON_LIBS})
set(CLIST_SRC test_client_list.c ../src/client_list.c
../src/service_alive.c ../src/upstream.c ../src/networking.c ../src/nopoll_helpers.c
../src/downstream.c ../src/connection.c ../src/nopoll_handlers.c ../src/heartBeat.c
../src/downstream.c ../src/connection.c ../src/nopoll_handlers.c ../src/heartBeat.c ../src/close_retry.c
../src/ParodusInternal.c ../src/thread_tasks.c ../src/conn_interface.c
../src/partners_check.c ../src/crud_interface.c ../src/crud_tasks.c ../src/crud_internal.c ${PARODUS_COMMON_SRC})
@@ -169,7 +163,7 @@ target_link_libraries (test_client_list ${PARODUS_COMMON_LIBS})
add_test(NAME test_service_alive COMMAND ${MEMORY_CHECK} ./test_service_alive)
#add_executable(test_service_alive test_service_alive.c ../src/client_list.c ../src/service_alive.c ../src/upstream.c ../src/networking.c ../src/nopoll_helpers.c ../src/nopoll_handlers.c ../src/config.c ../src/connection.c ../src/ParodusInternal.c ../src/downstream.c ../src/thread_tasks.c ../src/conn_interface.c ../src/partners_check.c ${PARODUS_COMMON_SRC})
#target_link_libraries (test_service_alive ${PARODUS_COMMON_LIBS})
set(SVA_SRC test_service_alive.c ../src/client_list.c ../src/service_alive.c ../src/upstream.c ../src/networking.c ../src/nopoll_helpers.c ../src/nopoll_handlers.c ../src/config.c ../src/connection.c ../src/ParodusInternal.c ../src/downstream.c ../src/thread_tasks.c ../src/conn_interface.c ../src/partners_check.c ../src/heartBeat.c ${PARODUS_COMMON_SRC})
set(SVA_SRC test_service_alive.c ../src/client_list.c ../src/service_alive.c ../src/upstream.c ../src/networking.c ../src/nopoll_helpers.c ../src/nopoll_handlers.c ../src/config.c ../src/connection.c ../src/ParodusInternal.c ../src/downstream.c ../src/thread_tasks.c ../src/conn_interface.c ../src/partners_check.c ../src/heartBeat.c ../src/close_retry.c ${PARODUS_COMMON_SRC})
if (ENABLE_SESHAT)
set(SVA_SRC ${SVA_SRC} ../src/seshat_interface.c)
else()
@@ -208,22 +202,28 @@ target_link_libraries (test_crud_tasks -lcmocka ${PARODUS_COMMON_LIBS} )
# test_crud_internal
#-------------------------------------------------------------------------------
add_test(NAME test_crud_internal COMMAND ${MEMORY_CHECK} ./test_crud_internal)
add_executable(test_crud_internal test_crud_internal.c ../src/config.c ../src/string_helpers.c ../src/crud_internal.c )
add_executable(test_crud_internal test_crud_internal.c ../src/config.c ../src/close_retry.c ../src/string_helpers.c ../src/crud_internal.c )
target_link_libraries (test_crud_internal -lcmocka ${PARODUS_COMMON_LIBS} )
#-------------------------------------------------------------------------------
# test_upstream
#-------------------------------------------------------------------------------
add_test(NAME test_upstream COMMAND ${MEMORY_CHECK} ./test_upstream)
add_executable(test_upstream test_upstream.c ../src/upstream.c ../src/string_helpers.c)
target_link_libraries (test_upstream -lcmocka ${PARODUS_COMMON_LIBS} )
add_executable(test_upstream test_upstream.c ../src/upstream.c ../src/close_retry.c ../src/string_helpers.c)
target_link_libraries (test_upstream -lcmocka gcov -lcunit -lcimplog
-lwrp-c -luuid -lpthread -lmsgpackc -lnopoll
-Wl,--no-as-needed -lcjson -lcjwt -ltrower-base64
-lssl -lcrypto -lrt -lm)
#-------------------------------------------------------------------------------
# test_downstream
#-------------------------------------------------------------------------------
add_test(NAME test_downstream COMMAND ${MEMORY_CHECK} ./test_downstream)
add_executable(test_downstream test_downstream.c ../src/downstream.c ../src/string_helpers.c)
target_link_libraries (test_downstream -lcmocka ${PARODUS_COMMON_LIBS} )
target_link_libraries (test_downstream -lcmocka gcov -lcunit -lcimplog
-lwrp-c -luuid -lpthread -lmsgpackc -lnopoll
-Wl,--no-as-needed -lcjson -lcjwt -ltrower-base64
-lssl -lcrypto -lrt -lm)
#-------------------------------------------------------------------------------
# test_downstream_more
@@ -251,6 +251,7 @@ set(CONIFC_SRC test_conn_interface.c
../src/string_helpers.c
../src/mutex.c
../src/heartBeat.c
../src/close_retry.c
)
if (ENABLE_SESHAT)
set(CONIFC_SRC ${CONIFC_SRC} ../src/seshat_interface.c)
@@ -288,6 +289,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
)
if (ENABLE_SESHAT)
@@ -346,5 +348,5 @@ set(SIMPLE_SRC ${SIMPLE_SRC} ../src/seshat_interface_stub.c)
endif (ENABLE_SESHAT)
add_executable(simple ${SIMPLE_SRC})
target_link_libraries (simple ${PARODUS_CONN_LIBS} ${PARODUS_COMMON_LIBS} gcov -lnopoll -lnanomsg )
target_link_libraries (simple ${PARODUS_CONN_LIBS} ${PARODUS_COMMON_LIBS} gcov -lnopoll )
endif (INTEGRATION_TESTING)

View File

@@ -1,409 +0,0 @@
/**
* Copyright 2010-2016 Comcast Cable Communications Management, LLC
*
* 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.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
#include <CUnit/Basic.h>
#include <stdbool.h>
#include <libparodus.h>
#include <pthread.h>
#include "../src/ParodusInternal.h"
#define SEND_EVENT_MSGS 1
//#define TCP_URL(ip) "tcp://" ip
#define GOOD_CLIENT_URL "tcp://127.0.0.1:6667"
//#define PARODUS_URL "ipc:///tmp/parodus_server.ipc"
#define GOOD_PARODUS_URL "tcp://127.0.0.1:6666"
//#define CLIENT_URL "ipc:///tmp/parodus_client.ipc"
static void initEndKeypressHandler();
static void *endKeypressHandlerTask();
static pthread_t endKeypressThreadId;
static const char *service_name = "iot";
//static const char *service_name = "config";
static bool no_mock_send_only_test = false;
static libpd_instance_t test_instance;
// libparodus functions to be tested
extern int flush_wrp_queue (uint32_t delay_ms);
extern int connect_receiver (const char *rcv_url);
extern int connect_sender (const char *send_url);
extern void shutdown_socket (int *sock);
extern bool is_auth_received (void);
extern int libparodus_receive__ (wrp_msg_t **msg, uint32_t ms);
// libparodus_log functions to be tested
extern int get_valid_file_num (const char *file_name, const char *date);
extern int get_last_file_num_in_dir (const char *date, const char *log_dir);
extern const char *wrp_queue_name;
extern const char *parodus_url;
extern const char *client_url;
extern volatile int keep_alive_count;
extern volatile int reconnect_count;
void show_src_dest_payload (char *src, char *dest, void *payload, size_t payload_size)
{
size_t i;
char *payload_str = (char *) payload;
printf (" SOURCE: %s\n", src);
printf (" DEST : %s\n", dest);
printf (" PAYLOAD: ");
for (i=0; i<payload_size; i++)
putchar (payload_str[i]);
putchar ('\n');
}
void show_wrp_req_msg (struct wrp_req_msg *msg)
{
show_src_dest_payload (msg->source, msg->dest, msg->payload, msg->payload_size);
}
void show_wrp_event_msg (struct wrp_event_msg *msg)
{
show_src_dest_payload (msg->source, msg->dest, msg->payload, msg->payload_size);
}
void show_wrp_msg (wrp_msg_t *wrp_msg)
{
printf ("Received WRP Msg type %d\n", wrp_msg->msg_type);
if (wrp_msg->msg_type == WRP_MSG_TYPE__REQ) {
show_wrp_req_msg (&wrp_msg->u.req);
return;
}
if (wrp_msg->msg_type == WRP_MSG_TYPE__EVENT) {
show_wrp_event_msg (&wrp_msg->u.event);
return;
}
return;
}
void send_reply (wrp_msg_t *wrp_msg)
{
size_t i;
size_t payload_size = wrp_msg->u.req.payload_size;
char *payload = (char *) wrp_msg->u.req.payload;
char *temp;
// swap source and dest
temp = wrp_msg->u.req.source;
wrp_msg->u.req.source = wrp_msg->u.req.dest;
wrp_msg->u.req.dest = temp;
// Alter the payload
for (i=0; i<payload_size; i++)
payload[i] = tolower (payload[i]);
libparodus_send (test_instance, wrp_msg);
}
char *new_str (const char *str)
{
char *buf = malloc (strlen(str) + 1);
if (NULL == buf)
return NULL;
parStrncpy(buf, str, (strlen(str)+1));
return buf;
}
void insert_number_into_buf (char *buf, unsigned num)
{
char *pos = strrchr (buf, '#');
if (NULL == pos)
return;
while (true) {
*pos = (num%10) + '0';
num /= 10;
if (pos <= buf)
break;
pos--;
if (*pos != '#')
break;
}
}
int send_event_msg (const char *src, const char *dest,
const char *payload, unsigned event_num)
{
int rtn = 0;
char *payload_buf;
wrp_msg_t *new_msg;
#ifndef SEND_EVENT_MSGS
return 0;
#endif
new_msg = malloc (sizeof (wrp_msg_t));
if (NULL == new_msg)
return -1;
printf ("Making event msg\n");
new_msg->msg_type = WRP_MSG_TYPE__EVENT;
new_msg->u.event.source = new_str (src);
new_msg->u.event.dest = new_str (dest);
new_msg->u.event.headers = NULL;
new_msg->u.event.metadata = NULL;
payload_buf = new_str (payload);
insert_number_into_buf (payload_buf, event_num);
new_msg->u.event.payload = (void*) payload_buf;
new_msg->u.event.payload_size = strlen (payload) + 1;
printf ("Sending event msg %u\n", event_num);
rtn = libparodus_send (test_instance, new_msg);
//printf ("Freeing event msg\n");
wrp_free_struct (new_msg);
//printf ("Freed event msg\n");
return rtn;
}
int send_event_msgs (unsigned *msg_num, unsigned *event_num, int count)
{
int i;
unsigned msg_num_mod;
#ifndef SEND_EVENT_MSGS
return 0;
#endif
if (NULL != msg_num) {
(*msg_num)++;
msg_num_mod = (*msg_num) % 3;
if (msg_num_mod != 0)
return 0;
}
for (i=0; i<count; i++) {
(*event_num)++;
if (send_event_msg ("---LIBPARODUS---", "---ParodusService---",
"---EventMessagePayload####", *event_num) != 0)
return -1;
}
return 0;
}
int get_msg_num (const char *msg)
{
int num = -1;
bool found_pound = false;
int i;
char c;
for (i=0; (c=msg[i]) != 0; i++)
{
if (!found_pound) {
if (c == '#')
found_pound = true;
continue;
}
if ((c>='0') && (c<='9')) {
if (num == -1)
num = c - '0';
else
num = 10*num + (c - '0');
}
}
return num;
}
static int flush_queue_count = 0;
void qfree (void * msg)
{
flush_queue_count++;
free (msg);
}
void delay_ms(unsigned int secs, unsigned int msecs)
{
struct timespec ts;
ts.tv_sec = (time_t) secs;
ts.tv_nsec = (long) msecs * 1000000L;
nanosleep (&ts, NULL);
}
void dbg_log_err (const char *fmt, ...)
{
char errbuf[100];
va_list arg_ptr;
va_start(arg_ptr, fmt);
vprintf(fmt, arg_ptr);
va_end(arg_ptr);
if( 0 == strerror_r (errno, errbuf, 100) ) {
printf("LIBPD_TEST: %s\n", errbuf);
} else {
printf("LIBPD_TEST: strerror_r returned failure!\n");
}
}
void wait_auth_received (void)
{
if (!is_auth_received ()) {
printf ("Waiting for auth received\n");
sleep(1);
}
if (!is_auth_received ()) {
printf ("Waiting for auth received\n");
sleep(1);
}
CU_ASSERT (is_auth_received ());
}
void test_send_only (void)
{
unsigned event_num = 0;
libpd_cfg_t cfg = {.service_name = service_name,
.receive = false, .keepalive_timeout_secs = 0};
CU_ASSERT (libparodus_init (&test_instance, &cfg) == 0);
CU_ASSERT (send_event_msgs (NULL, &event_num, 10) == 0);
CU_ASSERT (libparodus_shutdown (&test_instance) == 0);
}
void test_1(void)
{
unsigned msgs_received_count = 0;
int rtn;
wrp_msg_t *wrp_msg;
unsigned event_num = 0;
unsigned msg_num = 0;
libpd_cfg_t cfg = {.service_name = service_name,
.receive = true, .keepalive_timeout_secs = 0};
if (no_mock_send_only_test) {
test_send_only ();
return;
}
cfg.parodus_url = GOOD_PARODUS_URL;
cfg.client_url = GOOD_CLIENT_URL;
CU_ASSERT (libparodus_init (&test_instance, &cfg) == 0);
printf ("LIBPD_TEST: libparodus_init successful\n");
initEndKeypressHandler ();
wait_auth_received ();
printf ("LIBPD_TEST: starting msg receive loop\n");
while (true) {
rtn = libparodus_receive (test_instance, &wrp_msg, 2000);
if (rtn == 1) {
printf ("LIBPD_TEST: Timed out waiting for msg\n");
if (msgs_received_count > 0)
if (send_event_msgs (&msg_num, &event_num, 5) != 0)
break;
continue;
}
if (rtn != 0)
break;
show_wrp_msg (wrp_msg);
msgs_received_count++;
if (wrp_msg->msg_type == WRP_MSG_TYPE__REQ)
send_reply (wrp_msg);
wrp_free_struct (wrp_msg);
if (send_event_msgs (&msg_num, &event_num, 5) != 0)
break;
}
printf ("Messages received %u\n", msgs_received_count);
CU_ASSERT (libparodus_shutdown (&test_instance) == 0);
}
/*
* @brief To initiate end keypress handler
*/
static void initEndKeypressHandler()
{
int err = 0;
err = pthread_create(&endKeypressThreadId, NULL, endKeypressHandlerTask, NULL);
if (err != 0)
{
libpd_log (LEVEL_ERROR, "Error creating End Keypress Handler thread\n");
}
else
{
printf ("End Keypress handler Thread created successfully\n");
printf ("\n--->> Press <Enter> to shutdown the test. ---\n");
}
}
/*
* @brief To handle End Keypress
*/
static void *endKeypressHandlerTask()
{
char inbuf[10];
memset(inbuf, 0, 10);
while (true) {
fgets (inbuf, 10, stdin);
if ((inbuf[0] != '\n') && (inbuf[0] != '\0')) {
printf ("endKeyPressHandler exiting\n");
break;
}
}
libparodus_close_receiver (test_instance);
return NULL;
}
void add_suites( CU_pSuite *suite )
{
*suite = CU_add_suite( "libparodus tests", NULL, NULL );
CU_add_test( *suite, "Test 1", test_1 );
}
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
int main( int argc, char **argv __attribute__((unused)) )
{
unsigned rv = 1;
CU_pSuite suite = NULL;
if (argc > 1) {
const char *arg = argv[1];
if ((arg[0] == 's') || (arg[0] == 'S'))
no_mock_send_only_test = true;
}
if( CUE_SUCCESS == CU_initialize_registry() ) {
add_suites( &suite );
if( NULL != suite ) {
CU_basic_set_mode( CU_BRM_VERBOSE );
CU_basic_run_tests();
printf( "\n" );
CU_basic_show_failures( CU_get_failure_list() );
printf( "\n\n" );
rv = CU_get_number_of_tests_failed();
}
CU_cleanup_registry();
}
if( 0 != rv ) {
return 1;
}
return 0;
}

1
tests/return_failure.bsh Executable file
View File

@@ -0,0 +1 @@
echo -n FAILURE

1
tests/return_ser_mac.bsh Executable file
View File

@@ -0,0 +1 @@
echo -n SER_MAC $1 $2

1
tests/return_success.bsh Executable file
View File

@@ -0,0 +1 @@
echo -n SUCCESS

View File

@@ -108,7 +108,7 @@ void test_timespec_diff()
clock_gettime(CLOCK_REALTIME, &stop);
timespec_diff(&start, &stop, &diff);
time_taken_ms = diff.tv_sec * 1000 + (diff.tv_nsec / 1000000);
assert_int_equal(time_taken_ms, 1000);
assert_true(time_taken_ms >= 0);
}
/*
@@ -124,7 +124,7 @@ void test_timespec_diff1()
clock_gettime(CLOCK_REALTIME, &stop);
timespec_diff(&stop, &start, &diff);
time_taken_ms = diff.tv_sec * 1000 + (diff.tv_nsec / 1000000);
assert_int_equal(time_taken_ms, -1001);
assert_true(time_taken_ms <= 0);
}
/*----------------------------------------------------------------------------*/

93
tests/test_close_retry.c Normal file
View File

@@ -0,0 +1,93 @@
/**
* Copyright 2018 Comcast Cable Communications Management, LLC
*
* 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.
*
*/
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <pthread.h>
#include "../src/close_retry.h"
#include "../src/parodus_log.h"
/*----------------------------------------------------------------------------*/
/* Tests */
/*----------------------------------------------------------------------------*/
void test_close_retry() {
/* get close_retry initial value */
bool close_retry =false;
close_retry = get_close_retry();
ParodusInfo("close_retry initial value is: %d\n", close_retry);
assert_int_equal(close_retry, 0);
/* set close_retry value and check whether its returning modified value or not*/
set_close_retry();
close_retry = get_close_retry();
ParodusInfo("close_retry modified to: %d\n", close_retry);
assert_int_equal(close_retry,1);
/* reset close_retry */
reset_close_retry();
close_retry = get_close_retry();
ParodusInfo("close_retry reset to: %d\n", close_retry);
assert_int_equal(close_retry,0);
}
void *test_mutex_set_close_retry() {
set_close_retry();
return NULL;
}
void *test_mutex_reset_close_retry() {
reset_close_retry();
return NULL;
}
void test_mutex_close_retry() {
bool close_retry;
pthread_t thread[3];
pthread_create(&thread[0], NULL, test_mutex_set_close_retry, NULL);
pthread_create(&thread[1], NULL, test_mutex_set_close_retry, NULL);
pthread_join(thread[0], NULL);
pthread_join(thread[1], NULL);
/* After execution of threads check the value of close_retry */
close_retry = get_close_retry();
ParodusInfo("Threads execution is completed, close_retry is: %d\n", close_retry);
assert_int_equal(close_retry, 1);
pthread_create(&thread[2], NULL, test_mutex_reset_close_retry, NULL);
pthread_join(thread[2], NULL);
close_retry = get_close_retry();
ParodusInfo("close_retry reset to: %d\n", close_retry);
assert_int_equal(close_retry, 0);
}
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_close_retry),
cmocka_unit_test(test_mutex_close_retry)
};
return cmocka_run_group_tests(tests, NULL, NULL);
}

View File

@@ -30,11 +30,15 @@
extern int parse_mac_address (char *target, const char *arg);
extern int server_is_http (const char *full_url,
const char **server_ptr);
extern int parse_webpa_url(const char *full_url,
extern int parse_webpa_url__(const char *full_url,
char *server_addr, int server_addr_buflen,
char *port_buf, int port_buflen);
extern int parse_webpa_url (const char *full_url,
char **server_addr, unsigned int *port);
extern unsigned int get_algo_mask (const char *algo_str);
extern unsigned int parse_num_arg (const char *arg, const char *arg_name);
extern void execute_token_script(char *token, char *name, size_t len, char *mac, char *serNum);
extern void createNewAuthToken(char *newToken, size_t len);
/*----------------------------------------------------------------------------*/
/* Mocks */
@@ -413,6 +417,7 @@ void test_setDefaultValuesToCfg()
assert_int_equal((int)cfg->flags, 0);
assert_string_equal(cfg->webpa_path_url, WEBPA_PATH_URL);
assert_string_equal(cfg->webpa_uuid, "1234567-345456546");
assert_string_equal(cfg->cloud_status, CLOUD_STATUS_OFFLINE);
}
void err_setDefaultValuesToCfg()
@@ -453,35 +458,89 @@ void test_server_is_http ()
}
void test_parse_webpa_url ()
void test_parse_webpa_url__ ()
{
char addr_buf[80];
char port_buf[8];
assert_int_equal (parse_webpa_url ("mydns.mycom.net:8080",
assert_int_equal (parse_webpa_url__ ("mydns.mycom.net:8080",
addr_buf, 80, port_buf, 8), -1);
assert_int_equal (parse_webpa_url ("https://mydns.mycom.net:8080",
assert_int_equal (parse_webpa_url__ ("https://mydns.mycom.net:8080",
addr_buf, 80, port_buf, 8), 0);
assert_string_equal (addr_buf, "mydns.mycom.net");
assert_string_equal (port_buf, "8080");
assert_int_equal (parse_webpa_url ("https://mydns.mycom.net/",
assert_int_equal (parse_webpa_url__ ("https://mydns.mycom.net/",
addr_buf, 80, port_buf, 8), 0);
assert_string_equal (addr_buf, "mydns.mycom.net");
assert_string_equal (port_buf, "443");
assert_int_equal (parse_webpa_url ("https://mydns.mycom.net/api/v2/",
assert_int_equal (parse_webpa_url__ ("https://mydns.mycom.net/api/v2/",
addr_buf, 80, port_buf, 8), 0);
assert_string_equal (addr_buf, "mydns.mycom.net");
assert_string_equal (port_buf, "443");
assert_int_equal (parse_webpa_url ("http://mydns.mycom.net:8080",
assert_int_equal (parse_webpa_url__ ("http://mydns.mycom.net:8080",
addr_buf, 80, port_buf, 8), 1);
assert_string_equal (addr_buf, "mydns.mycom.net");
assert_string_equal (port_buf, "8080");
assert_int_equal (parse_webpa_url ("http://mydns.mycom.net",
assert_int_equal (parse_webpa_url__ ("http://mydns.mycom.net",
addr_buf, 80, port_buf, 8), 1);
assert_string_equal (addr_buf, "mydns.mycom.net");
assert_string_equal (port_buf, "80");
assert_int_equal (parse_webpa_url__ ("https://[2001:558:fc18:2:f816:3eff:fe7f:6efa]:8080",
addr_buf, 80, port_buf, 8), 0);
assert_string_equal (addr_buf, "2001:558:fc18:2:f816:3eff:fe7f:6efa");
assert_string_equal (port_buf, "8080");
assert_int_equal (parse_webpa_url__ ("https://[2001:558:fc18:2:f816:3eff:fe7f:6efa]",
addr_buf, 80, port_buf, 8), 0);
assert_string_equal (addr_buf, "2001:558:fc18:2:f816:3eff:fe7f:6efa");
assert_string_equal (port_buf, "443");
assert_int_equal (parse_webpa_url__ ("http://[2001:558:fc18:2:f816:3eff:fe7f:6efa]:8080",
addr_buf, 80, port_buf, 8), 1);
assert_string_equal (addr_buf, "2001:558:fc18:2:f816:3eff:fe7f:6efa");
assert_string_equal (port_buf, "8080");
assert_int_equal (parse_webpa_url__ ("http://[2001:558:fc18:2:f816:3eff:fe7f:6efa]",
addr_buf, 80, port_buf, 8), 1);
assert_string_equal (addr_buf, "2001:558:fc18:2:f816:3eff:fe7f:6efa");
assert_string_equal (port_buf, "80");
assert_int_equal (parse_webpa_url__ ("http://2001:558:fc18:2:f816:3eff:fe7f:6efa]",
addr_buf, 80, port_buf, 8), -1);
assert_int_equal (parse_webpa_url__ ("http://[2001:558:fc18:2:f816:3eff:fe7f:6efa",
addr_buf, 80, port_buf, 8), -1);
assert_int_equal (parse_webpa_url__ ("[2001:558:fc18:2:f816:3eff:fe7f:6efa",
addr_buf, 80, port_buf, 8), -1);
assert_int_equal (parse_webpa_url__ ("https://[2001:558:fc18:2:f816:3eff:fe7f:6efa]:8080/api/v2/",
addr_buf, 80, port_buf, 8), 0);
assert_string_equal (addr_buf, "2001:558:fc18:2:f816:3eff:fe7f:6efa");
assert_string_equal (port_buf, "8080");
}
void test_parse_webpa_url ()
{
char *addr;
unsigned int port;
assert_int_equal (parse_webpa_url ("mydns.mycom.net:8080",
&addr, &port), -1);
assert_int_equal (parse_webpa_url ("https://mydns.mycom.net:8080",
&addr, &port), 0);
assert_string_equal (addr, "mydns.mycom.net");
assert_int_equal (port, 8080);
free (addr);
assert_int_equal (parse_webpa_url ("https://mydns.mycom.net/",
&addr, &port), 0);
assert_string_equal (addr, "mydns.mycom.net");
assert_int_equal (port, 443);
free (addr);
assert_int_equal (parse_webpa_url ("http://mydns.mycom.net:8080",
&addr, &port), 1);
assert_string_equal (addr, "mydns.mycom.net");
assert_int_equal (port, 8080);
free (addr);
assert_int_equal (parse_webpa_url ("http://mydns.mycom.net",
&addr, &port), 1);
assert_string_equal (addr, "mydns.mycom.net");
assert_int_equal (port, 80);
free(addr);
}
void test_get_algo_mask ()
{
assert_true (get_algo_mask ("RS256:RS512") == 5120);
@@ -494,6 +553,46 @@ void test_get_algo_mask ()
#endif
}
void test_execute_token_script()
{
char *cmd1 = "../../tests/return_ser_mac.bsh";
char *cmd2 = "nosuch";
char token[32];
memset (token, '\0', sizeof(token));
execute_token_script (token, cmd1, sizeof(token), "mac123", "ser456");
assert_string_equal (token, "SER_MAC ser456 mac123");
memset (token, '\0', sizeof(token));
execute_token_script (token, cmd2, sizeof(token), "mac123", "ser456");
assert_string_equal (token, "");
}
void test_new_auth_token ()
{
char token[64];
ParodusCfg cfg;
memset(&cfg,0,sizeof(cfg));
parStrncpy (cfg.token_acquisition_script, "../../tests/return_success.bsh",
sizeof(cfg.token_acquisition_script));
parStrncpy (cfg.token_read_script, "../../tests/return_ser_mac.bsh",
sizeof(cfg.token_read_script));
parStrncpy(cfg.hw_serial_number, "Fer23u948590", sizeof(cfg.hw_serial_number));
parStrncpy(cfg.hw_mac , "123567892366", sizeof(cfg.hw_mac));
set_parodus_cfg(&cfg);
createNewAuthToken (token, sizeof(token));
assert_string_equal (token, "SER_MAC Fer23u948590 123567892366");
memset (token, 0, sizeof(token));
parStrncpy (cfg.token_acquisition_script, "../../tests/return_failure.bsh",
sizeof(cfg.token_acquisition_script));
set_parodus_cfg(&cfg);
createNewAuthToken (token, sizeof(token));
assert_string_equal (token, "");
}
/*----------------------------------------------------------------------------*/
/* External Functions */
@@ -511,13 +610,16 @@ int main(void)
cmocka_unit_test(test_parse_mac_address),
cmocka_unit_test(test_get_algo_mask),
cmocka_unit_test(test_server_is_http),
cmocka_unit_test(test_parse_webpa_url__),
cmocka_unit_test(test_parse_webpa_url),
cmocka_unit_test(test_parseCommandLine),
cmocka_unit_test(test_parseCommandLineNull),
cmocka_unit_test(err_parseCommandLine),
cmocka_unit_test(test_parodusGitVersion),
//cmocka_unit_test(test_parodusGitVersion),
cmocka_unit_test(test_setDefaultValuesToCfg),
cmocka_unit_test(err_setDefaultValuesToCfg),
cmocka_unit_test(test_execute_token_script),
cmocka_unit_test(test_new_auth_token)
};
return cmocka_run_group_tests(tests, NULL, NULL);

View File

@@ -28,14 +28,13 @@
#include "../src/connection.h"
#include "../src/config.h"
#include "../src/heartBeat.h"
#include "../src/close_retry.h"
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
UpStreamMsg *UpStreamMsgQ;
ParodusMsg *ParodusMsgQ;
extern bool close_retry;
extern pthread_mutex_t close_mut;
pthread_mutex_t nano_mut;
pthread_cond_t nano_con;
@@ -77,6 +76,17 @@ void packMetaData()
}
int get_cloud_disconnect_time(void)
{
function_called();
return (int) (intptr_t)mock();
}
void set_cloud_disconnect_time(int Time)
{
UNUSED(Time);
function_called();
}
void *handle_upstream()
{
@@ -204,10 +214,7 @@ void test_createSocketConnection()
noPollCtx *ctx;
ParodusCfg cfg;
memset(&cfg,0,sizeof(ParodusCfg));
pthread_mutex_lock (&close_mut);
close_retry = false;
pthread_mutex_unlock (&close_mut);
reset_close_retry();
expect_function_call(nopoll_thread_handlers);
will_return(nopoll_ctx_new, (intptr_t)&ctx);
@@ -243,9 +250,7 @@ void test_createSocketConnection1()
noPollCtx *ctx;
ParodusCfg cfg;
memset(&cfg,0, sizeof(ParodusCfg));
pthread_mutex_lock (&close_mut);
close_retry = true;
pthread_mutex_unlock (&close_mut);
set_close_retry();
expect_function_call(nopoll_thread_handlers);
will_return(nopoll_ctx_new, (intptr_t)&ctx);
@@ -271,6 +276,7 @@ void test_createSocketConnection1()
expect_function_call(nopoll_ctx_unref);
expect_function_call(nopoll_cleanup_library);
createSocketConnection(NULL);
assert_string_equal(get_parodus_cfg()->cloud_status, CLOUD_STATUS_OFFLINE);
}
@@ -294,9 +300,7 @@ void test_PingMissIntervalTime()
cfg.webpa_ping_timeout = 6;
set_parodus_cfg(&cfg);
pthread_mutex_lock (&close_mut);
close_retry = false;
pthread_mutex_unlock (&close_mut);
reset_close_retry();
expect_function_call(nopoll_thread_handlers);
will_return(nopoll_ctx_new, (intptr_t)&ctx);
@@ -336,9 +340,7 @@ void test_PingMissIntervalTime()
void err_createSocketConnection()
{
pthread_mutex_lock (&close_mut);
close_retry = true;
pthread_mutex_unlock (&close_mut);
set_close_retry();
reset_heartBeatTimer();
expect_function_call(nopoll_thread_handlers);
@@ -367,6 +369,53 @@ void err_createSocketConnection()
createSocketConnection(NULL);
}
void test_createSocketConnection_cloud_disconn()
{
ParodusCfg cfg;
memset(&cfg,0,sizeof(ParodusCfg));
cfg.cloud_disconnect = strdup("XPC");
set_parodus_cfg(&cfg);
set_close_retry();
reset_heartBeatTimer();
expect_function_call(nopoll_thread_handlers);
will_return(nopoll_ctx_new, (intptr_t)NULL);
expect_function_call(nopoll_ctx_new);
expect_function_call(nopoll_log_set_handler);
will_return(createNopollConnection, nopoll_true);
expect_function_call(createNopollConnection);
expect_function_call(packMetaData);
expect_function_calls(StartThread, 5);
will_return(nopoll_loop_wait, 1);
expect_function_call(nopoll_loop_wait);
will_return(get_global_conn, (intptr_t)NULL);
expect_function_call(get_global_conn);
expect_function_call(close_and_unref_connection);
expect_function_call(set_global_conn);
expect_function_call(set_cloud_disconnect_time);
will_return(get_cloud_disconnect_time, 0);
expect_function_call(get_cloud_disconnect_time);
will_return(get_cloud_disconnect_time, 0);
expect_function_call(get_cloud_disconnect_time);
will_return(get_cloud_disconnect_time, 0);
expect_function_call(get_cloud_disconnect_time);
will_return(createNopollConnection, nopoll_true);
expect_function_call(createNopollConnection);
will_return(get_global_conn, (intptr_t)NULL);
expect_function_call(get_global_conn);
expect_function_call(close_and_unref_connection);
expect_function_call(nopoll_ctx_unref);
expect_function_call(nopoll_cleanup_library);
createSocketConnection(NULL);
}
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
@@ -378,6 +427,7 @@ int main(void)
cmocka_unit_test(test_createSocketConnection1),
cmocka_unit_test(test_PingMissIntervalTime),
cmocka_unit_test(err_createSocketConnection),
cmocka_unit_test(test_createSocketConnection_cloud_disconn)
};
return cmocka_run_group_tests(tests, NULL, NULL);

File diff suppressed because it is too large Load Diff

View File

@@ -341,6 +341,7 @@ void test_createConnection()
int ret = createNopollConnection(ctx);
assert_int_equal(ret, nopoll_true);
assert_string_equal(get_parodus_cfg()->cloud_status, CLOUD_STATUS_ONLINE);
free(cfg);
if (g_jwt_server_ip !=NULL)
{

View File

@@ -29,6 +29,21 @@
#include "../src/crud_tasks.h"
#include "../src/config.h"
#include "../src/crud_internal.h"
#include "../src/connection.h"
#include "../src/close_retry.h"
bool LastReasonStatus;
pthread_mutex_t close_mut;
void set_global_reconnect_reason(char *reason)
{
UNUSED(reason);
}
void set_global_reconnect_status(bool status)
{
UNUSED(status);
}
void test_writeToJSON_Failure()
{
@@ -1420,7 +1435,6 @@ void test_retrieveObject_invalid()
memset(&cfg,0,sizeof(cfg));
cfg.crud_config_file = strdup("parodus_cfg.json");
set_parodus_cfg(&cfg);
//testdata=strdup("{\"test\":{}}}");
testdata=strdup("{\"tags\":{\"test1\":{\"expires\":1522451870}}}");
write_ret = writeToJSON(testdata);
assert_int_equal (write_ret, 1);
@@ -1487,6 +1501,130 @@ void test_retrieveObject_readOnlyObj()
wrp_free_struct(respMsg);
}
void test_retrieveObject_cloud_status()
{
int ret = 0;
int write_ret = -1;
FILE *fp;
char *testdata = NULL;
wrp_msg_t *reqMsg = NULL;
reqMsg = ( wrp_msg_t *)malloc( sizeof( wrp_msg_t ) );
memset(reqMsg, 0, sizeof(wrp_msg_t));
wrp_msg_t *respMsg = NULL;
respMsg = ( wrp_msg_t *)malloc( sizeof( wrp_msg_t ) );
memset(respMsg, 0, sizeof(wrp_msg_t));
ParodusCfg cfg;
memset(&cfg,0,sizeof(cfg));
cfg.cloud_status = CLOUD_STATUS_ONLINE;
cfg.crud_config_file = strdup("parodus_cfg.json");
set_parodus_cfg(&cfg);
testdata=strdup("{\"tags\":{\"test1\":{\"expires\":1522451870}}}");
write_ret = writeToJSON(testdata);
assert_int_equal (write_ret, 1);
reqMsg->msg_type = 6;
reqMsg->u.crud.transaction_uuid = strdup("1234");
reqMsg->u.crud.dest = strdup("mac:14xxx/parodus/cloud-status");
respMsg->msg_type = 6;
ret = retrieveObject(reqMsg, &respMsg);
assert_int_equal (respMsg->u.crud.status, 200);
assert_int_equal (ret, 0);
assert_string_equal(get_parodus_cfg()->cloud_status, CLOUD_STATUS_ONLINE);
assert_int_equal (respMsg->u.crud.payload_size, 25);
fp = fopen(cfg.crud_config_file, "r");
if (fp != NULL)
{
system("rm parodus_cfg.json");
fclose(fp);
}
if(cfg.crud_config_file !=NULL)
free(cfg.crud_config_file);
wrp_free_struct(reqMsg);
wrp_free_struct(respMsg);
}
void err_retrieveObject_cloud_statusNULL()
{
int ret = 0;
int write_ret = -1;
FILE *fp;
char *testdata = NULL;
wrp_msg_t *reqMsg = NULL;
reqMsg = ( wrp_msg_t *)malloc( sizeof( wrp_msg_t ) );
memset(reqMsg, 0, sizeof(wrp_msg_t));
wrp_msg_t *respMsg = NULL;
respMsg = ( wrp_msg_t *)malloc( sizeof( wrp_msg_t ) );
memset(respMsg, 0, sizeof(wrp_msg_t));
ParodusCfg cfg;
memset(&cfg,0,sizeof(cfg));
cfg.cloud_status = NULL;
cfg.crud_config_file = strdup("parodus_cfg.json");
set_parodus_cfg(&cfg);
testdata=strdup("{\"tags\":{\"test1\":{\"expires\":1522451870}}}");
write_ret = writeToJSON(testdata);
assert_int_equal (write_ret, 1);
reqMsg->msg_type = 6;
reqMsg->u.crud.transaction_uuid = strdup("1234");
reqMsg->u.crud.dest = strdup("mac:14xxx/parodus/cloud-status");
respMsg->msg_type = 6;
ret = retrieveObject(reqMsg, &respMsg);
assert_int_equal (respMsg->u.crud.status, 400);
assert_int_equal (ret, -1);
assert_int_equal (respMsg->u.crud.payload_size, 0);
fp = fopen(cfg.crud_config_file, "r");
if (fp != NULL)
{
system("rm parodus_cfg.json");
fclose(fp);
}
if(cfg.crud_config_file !=NULL)
free(cfg.crud_config_file);
wrp_free_struct(reqMsg);
wrp_free_struct(respMsg);
}
void err_retrieveObject_cloud_statusEmpty()
{
int ret = 0;
int write_ret = -1;
FILE *fp;
char *testdata = NULL;
wrp_msg_t *reqMsg = NULL;
reqMsg = ( wrp_msg_t *)malloc( sizeof( wrp_msg_t ) );
memset(reqMsg, 0, sizeof(wrp_msg_t));
wrp_msg_t *respMsg = NULL;
respMsg = ( wrp_msg_t *)malloc( sizeof( wrp_msg_t ) );
memset(respMsg, 0, sizeof(wrp_msg_t));
ParodusCfg cfg;
memset(&cfg,0,sizeof(cfg));
cfg.cloud_status = "";
cfg.crud_config_file = strdup("parodus_cfg.json");
set_parodus_cfg(&cfg);
testdata=strdup("{\"tags\":{\"test1\":{\"expires\":1522451870}}}");
write_ret = writeToJSON(testdata);
assert_int_equal (write_ret, 1);
reqMsg->msg_type = 6;
reqMsg->u.crud.transaction_uuid = strdup("1234");
reqMsg->u.crud.dest = strdup("mac:14xxx/parodus/cloud-status");
respMsg->msg_type = 6;
ret = retrieveObject(reqMsg, &respMsg);
assert_int_equal (respMsg->u.crud.status, 400);
assert_int_equal (ret, -1);
assert_int_equal (respMsg->u.crud.payload_size, 0);
fp = fopen(cfg.crud_config_file, "r");
if (fp != NULL)
{
system("rm parodus_cfg.json");
fclose(fp);
}
if(cfg.crud_config_file !=NULL)
free(cfg.crud_config_file);
wrp_free_struct(reqMsg);
wrp_free_struct(respMsg);
}
void test_retrieveObject_readOnlyFailure()
{
int ret = 0;
@@ -2244,6 +2382,192 @@ void err_updateObject_InvalidType()
wrp_free_struct(respMsg);
}
void err_updateObject_cloud_disconnectInvalid()
{
int ret = 0;
wrp_msg_t *reqMsg = NULL;
reqMsg = ( wrp_msg_t *)malloc( sizeof( wrp_msg_t ) );
memset(reqMsg, 0, sizeof(wrp_msg_t));
wrp_msg_t *respMsg = NULL;
respMsg = ( wrp_msg_t *)malloc( sizeof( wrp_msg_t ) );
memset(respMsg, 0, sizeof(wrp_msg_t));
reqMsg->msg_type = 7;
reqMsg->u.crud.transaction_uuid = strdup("1234");
reqMsg->u.crud.source = strdup("dns:tr1d1um.webpa.comcast.net/config");
reqMsg->u.crud.dest = strdup("mac:14cfe2142145/parodus/cloud-disconnect");
reqMsg->u.crud.payload = strdup("{ \"disconnection-reason\": \"***\" }");
respMsg->msg_type = 7;
ret = updateObject(reqMsg, &respMsg);
assert_int_equal (respMsg->u.crud.status, 400);
assert_int_equal (ret, -1);
wrp_free_struct(reqMsg);
wrp_free_struct(respMsg);
}
void err_updateObject_cloud_disconnectNULL()
{
int ret = 0;
wrp_msg_t *reqMsg = NULL;
reqMsg = ( wrp_msg_t *)malloc( sizeof( wrp_msg_t ) );
memset(reqMsg, 0, sizeof(wrp_msg_t));
wrp_msg_t *respMsg = NULL;
respMsg = ( wrp_msg_t *)malloc( sizeof( wrp_msg_t ) );
memset(respMsg, 0, sizeof(wrp_msg_t));
reqMsg->msg_type = 7;
reqMsg->u.crud.transaction_uuid = strdup("1234");
reqMsg->u.crud.source = strdup("dns:tr1d1um.webpa.comcast.net/config");
reqMsg->u.crud.dest = strdup("mac:14cfe2142145/parodus/cloud-disconnect");
reqMsg->u.crud.payload = strdup("{ \"disconnection-reason\": \"\" }");
respMsg->msg_type = 7;
ret = updateObject(reqMsg, &respMsg);
assert_int_equal (respMsg->u.crud.status, 400);
assert_int_equal (ret, -1);
wrp_free_struct(reqMsg);
wrp_free_struct(respMsg);
}
void err_updateObject_no_cloud_disconnectReason()
{
int ret = 0;
wrp_msg_t *reqMsg = NULL;
reqMsg = ( wrp_msg_t *)malloc( sizeof( wrp_msg_t ) );
memset(reqMsg, 0, sizeof(wrp_msg_t));
wrp_msg_t *respMsg = NULL;
respMsg = ( wrp_msg_t *)malloc( sizeof( wrp_msg_t ) );
memset(respMsg, 0, sizeof(wrp_msg_t));
reqMsg->msg_type = 7;
reqMsg->u.crud.transaction_uuid = strdup("1234");
reqMsg->u.crud.source = strdup("dns:tr1d1um.webpa.comcast.net/config");
reqMsg->u.crud.dest = strdup("mac:14cfe2142145/parodus/cloud-disconnect");
reqMsg->u.crud.payload = strdup("{ \"discon-val\": \"XPC\" }");
respMsg->msg_type = 7;
ret = updateObject(reqMsg, &respMsg);
assert_int_equal (respMsg->u.crud.status, 400);
assert_int_equal (ret, -1);
wrp_free_struct(reqMsg);
wrp_free_struct(respMsg);
}
void err_updateObject_cloud_disconnectNoPayload()
{
int ret = 0;
wrp_msg_t *reqMsg = NULL;
reqMsg = ( wrp_msg_t *)malloc( sizeof( wrp_msg_t ) );
memset(reqMsg, 0, sizeof(wrp_msg_t));
wrp_msg_t *respMsg = NULL;
respMsg = ( wrp_msg_t *)malloc( sizeof( wrp_msg_t ) );
memset(respMsg, 0, sizeof(wrp_msg_t));
reqMsg->msg_type = 7;
reqMsg->u.crud.transaction_uuid = strdup("1234");
reqMsg->u.crud.source = strdup("dns:tr1d1um.webpa.comcast.net/config");
reqMsg->u.crud.dest = strdup("mac:14cfe2142145/parodus/cloud-disconnect");
respMsg->msg_type = 7;
ret = updateObject(reqMsg, &respMsg);
assert_int_equal (respMsg->u.crud.status, 400);
assert_int_equal (ret, -1);
wrp_free_struct(reqMsg);
wrp_free_struct(respMsg);
}
void err_updateObject_cloud_disconnectInvalidPayload()
{
int ret = 0;
wrp_msg_t *reqMsg = NULL;
reqMsg = ( wrp_msg_t *)malloc( sizeof( wrp_msg_t ) );
memset(reqMsg, 0, sizeof(wrp_msg_t));
wrp_msg_t *respMsg = NULL;
respMsg = ( wrp_msg_t *)malloc( sizeof( wrp_msg_t ) );
memset(respMsg, 0, sizeof(wrp_msg_t));
reqMsg->msg_type = 7;
reqMsg->u.crud.transaction_uuid = strdup("1234");
reqMsg->u.crud.source = strdup("dns:tr1d1um.webpa.comcast.net/config");
reqMsg->u.crud.dest = strdup("mac:14cfe2142145/parodus/cloud-disconnect");
reqMsg->u.crud.payload = strdup("{ \"disconnection-reason\"\"XPC\" }");
respMsg->msg_type = 7;
ret = updateObject(reqMsg, &respMsg);
assert_int_equal (respMsg->u.crud.status, 400);
assert_int_equal (ret, -1);
wrp_free_struct(reqMsg);
wrp_free_struct(respMsg);
}
void err_updateObject_cloud_disconnectInvalidType()
{
int ret = 0;
wrp_msg_t *reqMsg = NULL;
reqMsg = ( wrp_msg_t *)malloc( sizeof( wrp_msg_t ) );
memset(reqMsg, 0, sizeof(wrp_msg_t));
wrp_msg_t *respMsg = NULL;
respMsg = ( wrp_msg_t *)malloc( sizeof( wrp_msg_t ) );
memset(respMsg, 0, sizeof(wrp_msg_t));
reqMsg->msg_type = 7;
reqMsg->u.crud.transaction_uuid = strdup("1234");
reqMsg->u.crud.source = strdup("dns:tr1d1um.webpa.comcast.net/config");
reqMsg->u.crud.dest = strdup("mac:14cfe2142145/parodus/cloud-disconnect");
reqMsg->u.crud.payload = strdup("{ \"disconnection-reason\":123 }");
respMsg->msg_type = 7;
ret = updateObject(reqMsg, &respMsg);
assert_int_equal (respMsg->u.crud.status, 400);
assert_int_equal (ret, -1);
wrp_free_struct(reqMsg);
wrp_free_struct(respMsg);
}
void err_updateObject_cloud_disconnectFailure()
{
int ret = 0;
wrp_msg_t *reqMsg = NULL;
set_close_retry();
reqMsg = ( wrp_msg_t *)malloc( sizeof( wrp_msg_t ) );
memset(reqMsg, 0, sizeof(wrp_msg_t));
wrp_msg_t *respMsg = NULL;
respMsg = ( wrp_msg_t *)malloc( sizeof( wrp_msg_t ) );
memset(respMsg, 0, sizeof(wrp_msg_t));
reqMsg->msg_type = 7;
reqMsg->u.crud.transaction_uuid = strdup("1234");
reqMsg->u.crud.source = strdup("dns:tr1d1um.webpa.comcast.net/config");
reqMsg->u.crud.dest = strdup("mac:14cfe2142145/parodus/cloud-disconnect");
reqMsg->u.crud.payload = strdup("{ \"disconnection-reason\":\"XPC09\" }");
respMsg->msg_type = 7;
ret = updateObject(reqMsg, &respMsg);
assert_int_equal (respMsg->u.crud.status, 500);
assert_int_equal (ret, -1);
wrp_free_struct(reqMsg);
wrp_free_struct(respMsg);
reset_close_retry();
}
void test_updateObject_cloud_disconnect()
{
int ret = 0;
wrp_msg_t *reqMsg = NULL;
reqMsg = ( wrp_msg_t *)malloc( sizeof( wrp_msg_t ) );
memset(reqMsg, 0, sizeof(wrp_msg_t));
wrp_msg_t *respMsg = NULL;
respMsg = ( wrp_msg_t *)malloc( sizeof( wrp_msg_t ) );
memset(respMsg, 0, sizeof(wrp_msg_t));
reqMsg->msg_type = 7;
reqMsg->u.crud.transaction_uuid = strdup("1234");
reqMsg->u.crud.source = strdup("dns:tr1d1um.webpa.comcast.net/config");
reqMsg->u.crud.dest = strdup("mac:14cfe2142145/parodus/cloud-disconnect");
reqMsg->u.crud.payload = strdup("{ \"disconnection-reason\":\"XPC\" }");
respMsg->msg_type = 7;
ret = updateObject(reqMsg, &respMsg);
assert_int_equal (respMsg->u.crud.status, 200);
assert_int_equal (ret, 0);
wrp_free_struct(reqMsg);
wrp_free_struct(respMsg);
}
void test_deleteObject_JsonEmpty()
{
int ret = 0;
@@ -2657,6 +2981,10 @@ int main(void)
cmocka_unit_test(test_retrieveObject_readOnlyObj),
cmocka_unit_test(test_retrieveObject_readOnlyFailure),
cmocka_unit_test(test_retrieveObject_cloud_status),
cmocka_unit_test(err_retrieveObject_cloud_statusNULL),
cmocka_unit_test(err_retrieveObject_cloud_statusEmpty),
cmocka_unit_test(test_updateObject_JsonEmpty),
cmocka_unit_test(test_updateObject_destNull),
cmocka_unit_test(test_updateObjectWithNoConfigJson),
@@ -2675,6 +3003,15 @@ int main(void)
cmocka_unit_test(err_updateObject_NonExisting_InvalidType),
cmocka_unit_test(err_updateObject_existingObj_InvalidType),
cmocka_unit_test(test_updateObject_cloud_disconnect),
cmocka_unit_test(err_updateObject_cloud_disconnectNULL),
cmocka_unit_test(err_updateObject_cloud_disconnectInvalid),
cmocka_unit_test(err_updateObject_cloud_disconnectFailure),
cmocka_unit_test(err_updateObject_no_cloud_disconnectReason),
cmocka_unit_test(err_updateObject_cloud_disconnectNoPayload),
cmocka_unit_test(err_updateObject_cloud_disconnectInvalidType),
cmocka_unit_test(err_updateObject_cloud_disconnectInvalidPayload),
cmocka_unit_test(test_deleteObject_JsonEmpty),
cmocka_unit_test(test_deleteObject_destNull),
cmocka_unit_test(test_deleteObjectWithNoConfigJson),
@@ -2684,7 +3021,6 @@ int main(void)
cmocka_unit_test(test_deleteObject_NonExistObj),
cmocka_unit_test(test_deleteObject_withTagsEmpty),
cmocka_unit_test(test_deleteObject_tagsFailure)
};
return cmocka_run_group_tests(tests, NULL, NULL);

View File

@@ -0,0 +1,94 @@
/**
* Copyright 2018 Comcast Cable Communications Management, LLC
*
* 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.
*
*/
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <pthread.h>
#include "../src/heartBeat.h"
#include "../src/parodus_log.h"
/*----------------------------------------------------------------------------*/
/* Tests */
/*----------------------------------------------------------------------------*/
void test_heartBeatTimer() {
/* get heartBeat timer's initial value */
unsigned int heartBeatTimer =5;
heartBeatTimer = get_heartBeatTimer();
ParodusInfo("heartBeatTimer initial vaule is: %d\n", heartBeatTimer);
assert_int_equal(heartBeatTimer, 0);
/* increment heartbeat timer value and check whether its returning modified value or not*/
unsigned int inc_time_ms =5;
increment_heartBeatTimer(inc_time_ms);
heartBeatTimer = get_heartBeatTimer();
ParodusInfo("heartBeatTimer incremented to: %d\n", heartBeatTimer);
assert_int_equal(heartBeatTimer,5);
/* reset heartBeat timer to 0 */
reset_heartBeatTimer();
heartBeatTimer = get_heartBeatTimer();
ParodusInfo("heartBeatTimer reset to: %d\n", heartBeatTimer);
assert_int_equal(heartBeatTimer,0);
}
void *test_mutexIncrementTimer() {
unsigned int inc_time_ms =5;
increment_heartBeatTimer(inc_time_ms);
return NULL;
}
void *test_mutexResetTimer() {
reset_heartBeatTimer();
return NULL;
}
void test_mutexHeartBeatTimer() {
unsigned int heartBeatTimer;
pthread_t thread[3];
pthread_create(&thread[0], NULL, test_mutexIncrementTimer, NULL);
pthread_create(&thread[1], NULL, test_mutexIncrementTimer, NULL);
pthread_join(thread[0], NULL);
pthread_join(thread[1], NULL);
/* After execution of both the threads check the value of timer */
heartBeatTimer = get_heartBeatTimer();
ParodusInfo("Threads execution is completed, heartBeatTimer is: %d\n", heartBeatTimer);
assert_int_equal(heartBeatTimer, 10);
pthread_create(&thread[2], NULL, test_mutexResetTimer, NULL);
pthread_join(thread[2], NULL);
heartBeatTimer = get_heartBeatTimer();
ParodusInfo("heartBeatTimer reset to: %d\n", heartBeatTimer);
assert_int_equal(heartBeatTimer, 0);
}
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_heartBeatTimer),
cmocka_unit_test(test_mutexHeartBeatTimer),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}

View File

@@ -43,7 +43,26 @@ ParodusCfg *get_parodus_cfg(void)
void test_validate_partner_id_for_req()
{
static partners_t partner_ids = {1,{"comcast"}};
static partners_t partner_ids = {3,{"shaw","","comcast"}};
wrp_msg_t *msg = (wrp_msg_t*) malloc(sizeof(wrp_msg_t));
memset(msg, 0, sizeof(wrp_msg_t));
msg->msg_type = WRP_MSG_TYPE__REQ;
msg->u.req.partner_ids = &partner_ids;
ParodusCfg cfg;
memset(&cfg, 0, sizeof(ParodusCfg));
parStrncpy(cfg.partner_id, "shaw,bar,comcast", sizeof(cfg.partner_id));
will_return(get_parodus_cfg, (intptr_t)&cfg);
expect_function_call(get_parodus_cfg);
int ret = validate_partner_id(msg, NULL);
assert_int_equal(ret, 1);
free(msg);
}
void test_validate_partner_id_for_req_case_insensitive()
{
static partners_t partner_ids = {2,{"Shaw","Comcast"}};
wrp_msg_t *msg = (wrp_msg_t*) malloc(sizeof(wrp_msg_t));
memset(msg, 0, sizeof(wrp_msg_t));
msg->msg_type = WRP_MSG_TYPE__REQ;
@@ -68,7 +87,7 @@ void test_validate_partner_id_for_req_listNULL()
ParodusCfg cfg;
memset(&cfg, 0, sizeof(ParodusCfg));
parStrncpy(cfg.partner_id, "comcast", sizeof(cfg.partner_id));
parStrncpy(cfg.partner_id, "*,comcast", sizeof(cfg.partner_id));
will_return(get_parodus_cfg, (intptr_t)&cfg);
expect_function_call(get_parodus_cfg);
@@ -103,7 +122,7 @@ void err_validate_partner_id_for_req()
ParodusCfg cfg;
memset(&cfg, 0, sizeof(ParodusCfg));
parStrncpy(cfg.partner_id, "comcast", sizeof(cfg.partner_id));
parStrncpy(cfg.partner_id, "*,,comcast", sizeof(cfg.partner_id));
will_return(get_parodus_cfg, (intptr_t)&cfg);
expect_function_call(get_parodus_cfg);
@@ -114,7 +133,7 @@ void err_validate_partner_id_for_req()
void test_validate_partner_id_for_event()
{
static partners_t partner_ids = {1,{"comcast"}};
static partners_t partner_ids = {4,{"shaw","","*","comcast"}};
wrp_msg_t *msg = (wrp_msg_t*) malloc(sizeof(wrp_msg_t));
memset(msg, 0, sizeof(wrp_msg_t));
msg->msg_type = WRP_MSG_TYPE__EVENT;
@@ -122,7 +141,29 @@ void test_validate_partner_id_for_event()
ParodusCfg cfg;
memset(&cfg, 0, sizeof(ParodusCfg));
parStrncpy(cfg.partner_id, "comcast", sizeof(cfg.partner_id));
parStrncpy(cfg.partner_id, "abc,*,comcast", sizeof(cfg.partner_id));
will_return(get_parodus_cfg, (intptr_t)&cfg);
expect_function_call(get_parodus_cfg);
partners_t *list = NULL;
int ret = validate_partner_id(msg, &list);
assert_int_equal(ret, 1);
free(list);
free(msg);
}
void test_validate_partner_id_for_event_case_insensitive()
{
static partners_t partner_ids = {1,{"Comcast"}};
wrp_msg_t *msg = (wrp_msg_t*) malloc(sizeof(wrp_msg_t));
memset(msg, 0, sizeof(wrp_msg_t));
msg->msg_type = WRP_MSG_TYPE__EVENT;
msg->u.event.partner_ids = &partner_ids;
ParodusCfg cfg;
memset(&cfg, 0, sizeof(ParodusCfg));
parStrncpy(cfg.partner_id, "*,comcast", sizeof(cfg.partner_id));
will_return(get_parodus_cfg, (intptr_t)&cfg);
expect_function_call(get_parodus_cfg);
@@ -218,10 +259,12 @@ int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_validate_partner_id_for_req),
cmocka_unit_test(test_validate_partner_id_for_req_case_insensitive),
cmocka_unit_test(test_validate_partner_id_for_req_listNULL),
cmocka_unit_test(test_validate_partner_id_for_req_withoutId),
cmocka_unit_test(err_validate_partner_id_for_req),
cmocka_unit_test(test_validate_partner_id_for_event),
cmocka_unit_test(test_validate_partner_id_for_event_case_insensitive),
cmocka_unit_test(test_validate_partner_id_for_event_listNULL),
cmocka_unit_test(test_validate_partner_id_for_event_withoutId),
cmocka_unit_test(err_validate_partner_id_for_event),

View File

@@ -144,8 +144,7 @@ cjwt_t jwt3; // insecure
cjwt_t jwt4; // missing endpoint
// internal functions in token.c to be tested
extern int analyze_jwt (const cjwt_t *jwt, char *url_buf, int url_buflen,
char *port_buf, int port_buflen);
extern int analyze_jwt (const cjwt_t *jwt, char **url_buf, unsigned int *port);
extern bool validate_algo(const cjwt_t *jwt);
extern int nquery(const char* dns_txt_record_id,u_char *nsbuf);
extern bool valid_b64_char (char c);
@@ -323,23 +322,23 @@ void __res_nclose (res_state statp)
// Analyzes a jwt structure
void test_analyze_jwt ()
{
char port[8];
char server_Address[256];
unsigned int port;
char *server_Address;
int ret = setup_test_jwts ();
assert_int_equal (ret, 0);
ret = analyze_jwt (&jwt1, server_Address, (int) sizeof(server_Address),
port, (int) sizeof(port));
ret = analyze_jwt (&jwt1, &server_Address, &port);
assert_int_equal (ret, 0);
assert_string_equal (server_Address, "mydns.mycom.net");
assert_string_equal (port, "8080");
ret = analyze_jwt (&jwt2, server_Address, (int) sizeof(server_Address),
port, (int) sizeof(port));
assert_int_equal (port, 8080);
free (server_Address);
ret = analyze_jwt (&jwt2, &server_Address, &port);
assert_int_equal (ret, TOKEN_ERR_JWT_EXPIRED);
ret = analyze_jwt (&jwt3, server_Address, (int) sizeof(server_Address),
port, (int) sizeof(port));
ret = analyze_jwt (&jwt3, &server_Address, &port);
assert_int_equal (ret, 1);
ret = analyze_jwt (&jwt4, server_Address, (int) sizeof(server_Address),
port, (int) sizeof(port));
assert_string_equal (server_Address, "mydns.mycom.net");
assert_int_equal (port, 8080);
free (server_Address);
ret = analyze_jwt (&jwt4, &server_Address, &port);
assert_int_equal (ret, TOKEN_ERR_INVALID_JWT_CONTENT);
}
@@ -614,7 +613,8 @@ void test_query_dns ()
void test_allow_insecure_conn ()
{
int insecure;
char port_buf[6] = "8080";
char *server_addr;
unsigned int port;
ParodusCfg *cfg = get_parodus_cfg();
parStrncpy (cfg->hw_mac, "aabbccddeeff", sizeof(cfg->hw_mac));
@@ -627,10 +627,11 @@ void test_allow_insecure_conn ()
expect_function_call (__res_ninit);
expect_function_call (__res_nclose);
insecure = allow_insecure_conn (cfg->dns_txt_url, sizeof(cfg->dns_txt_url),
port_buf, sizeof(port_buf));
insecure = allow_insecure_conn (&server_addr, &port);
free (server_addr);
assert_int_equal (insecure, 0);
parStrncpy (cfg->hw_mac, "aabbccddeeff", sizeof(cfg->hw_mac));
parStrncpy (cfg->dns_txt_url, "err5.mydns.mycom.net", sizeof(cfg->dns_txt_url));
@@ -638,8 +639,7 @@ void test_allow_insecure_conn ()
expect_function_call (__res_ninit);
expect_function_call (__res_nclose);
insecure = allow_insecure_conn (cfg->dns_txt_url, sizeof(cfg->dns_txt_url),
port_buf, sizeof(port_buf));
insecure = allow_insecure_conn (&server_addr, &port);
assert_int_equal (insecure, TOKEN_ERR_QUERY_DNS_FAIL);
parStrncpy (cfg->hw_mac, "aabbccddeeff", sizeof(cfg->hw_mac));
@@ -651,8 +651,7 @@ void test_allow_insecure_conn ()
expect_function_call (__res_ninit);
expect_function_call (__res_nclose);
insecure = allow_insecure_conn (cfg->dns_txt_url, sizeof(cfg->dns_txt_url),
port_buf, sizeof(port_buf));
insecure = allow_insecure_conn (&server_addr, &port);
assert_int_equal (insecure, TOKEN_ERR_JWT_DECODE_FAIL);
parStrncpy (cfg->hw_mac, "aabbccddeeff", sizeof(cfg->hw_mac));
@@ -664,8 +663,7 @@ void test_allow_insecure_conn ()
expect_function_call (__res_ninit);
expect_function_call (__res_nclose);
insecure = allow_insecure_conn (cfg->dns_txt_url, sizeof(cfg->dns_txt_url),
port_buf, sizeof(port_buf));
insecure = allow_insecure_conn (&server_addr, &port);
assert_int_equal (insecure, TOKEN_ERR_ALGO_NOT_ALLOWED);
}

View File

@@ -46,10 +46,9 @@ void test_allow_insecure_conn ()
{
int insecure;
char *server_Address = NULL;
char *port = NULL;
insecure = allow_insecure_conn (server_Address,(int) sizeof(server_Address),
port, (int) sizeof(port));
assert_int_equal (insecure, -1);
unsigned int port;
insecure = allow_insecure_conn (&server_Address, &port);
assert_int_equal (insecure, TOKEN_NO_DNS_QUERY);
}
/*----------------------------------------------------------------------------*/

View File

@@ -31,6 +31,7 @@
#include "../src/client_list.h"
#include "../src/ParodusInternal.h"
#include "../src/partners_check.h"
#include "../src/close_retry.h"
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
@@ -70,6 +71,21 @@ int get_numOfClients()
function_called();
return (int)mock();
}
void addCRUDmsgToQueue(wrp_msg_t *crudMsg)
{
(void)crudMsg;
function_called();
return;
}
int sendMsgtoRegisteredClients(char *dest,const char **Msg,size_t msgSize)
{
UNUSED(dest); UNUSED(Msg); UNUSED(msgSize);
function_called();
return (int)mock();
}
void sendMessage(noPollConn *conn, void *msg, size_t len)
{
(void) conn; (void) msg; (void) len;
@@ -305,6 +321,39 @@ void test_processUpstreamMessage()
free(UpStreamMsgQ);
}
void test_processUpstreamReqMessage()
{
numLoops = 1;
metaPackSize = 20;
UpStreamMsgQ = (UpStreamMsg *) malloc(sizeof(UpStreamMsg));
UpStreamMsgQ->msg = "First Message";
UpStreamMsgQ->len = 13;
UpStreamMsgQ->next = (UpStreamMsg *) malloc(sizeof(UpStreamMsg));
UpStreamMsgQ->next->msg = "Second Message";
UpStreamMsgQ->next->len = 15;
UpStreamMsgQ->next->next = NULL;
temp = (wrp_msg_t *) malloc(sizeof(wrp_msg_t));
memset(temp,0,sizeof(wrp_msg_t));
temp->msg_type = 3;
will_return(wrp_to_struct, 12);
expect_function_call(wrp_to_struct);
will_return(appendEncodedData, 100);
expect_function_call(appendEncodedData);
expect_function_call(sendMessage);
will_return(nn_freemsg, 0);
expect_function_call(nn_freemsg);
expect_function_call(wrp_free_struct);
processUpstreamMessage();
free(temp);
free(UpStreamMsgQ->next);
free(UpStreamMsgQ);
}
void test_processUpstreamMessageInvalidPartner()
{
numLoops = 1;
@@ -576,6 +625,21 @@ void test_sendUpstreamMsgToServer()
free(bytes);
}
void test_sendUpstreamMsg_close_retry()
{
set_close_retry();
void *bytes = NULL;
wrp_msg_t msg;
memset(&msg, 0, sizeof(wrp_msg_t));
msg.msg_type = WRP_MSG_TYPE__EVENT;
wrp_struct_to( &msg, WRP_BYTES, &bytes );
metaPackSize = 10;
will_return(appendEncodedData, 100);
expect_function_call(appendEncodedData);
sendUpstreamMsgToServer(&bytes, 110);
free(bytes);
}
void err_sendUpstreamMsgToServer()
{
metaPackSize = 0;
@@ -628,9 +692,151 @@ void test_processUpstreamMsgCrud_nnfree()
expect_function_call(wrp_free_struct);
processUpstreamMessage();
free(UpStreamMsgQ);
crud_test = 0;
}
void test_processUpstreamMsg_cloud_status()
{
numLoops = 1;
metaPackSize = 20;
UpStreamMsgQ = (UpStreamMsg *) malloc(sizeof(UpStreamMsg));
UpStreamMsgQ->msg = "First Message";
UpStreamMsgQ->len = 13;
UpStreamMsgQ->next= NULL;
temp = (wrp_msg_t *) malloc(sizeof(wrp_msg_t));
memset(temp,0,sizeof(wrp_msg_t));
temp->msg_type = 6;
temp->u.crud.dest = "mac:14cfe2142xxx/parodus/cloud-status";
temp->u.crud.source = "mac:14cfe2142xxx/config";
temp->u.crud.transaction_uuid = "123";
will_return(wrp_to_struct, 12);
expect_function_call(wrp_to_struct);
expect_function_call(addCRUDmsgToQueue);
will_return(nn_freemsg, 0);
expect_function_call(nn_freemsg);
expect_function_call(wrp_free_struct);
processUpstreamMessage();
free(temp);
free(UpStreamMsgQ);
UpStreamMsgQ = NULL;
}
void test_processUpstreamMsg_sendToClient()
{
numLoops = 2;
metaPackSize = 20;
UpStreamMsgQ = (UpStreamMsg *) malloc(sizeof(UpStreamMsg));
UpStreamMsgQ->msg = strdup("First Message");
UpStreamMsgQ->len = 13;
UpStreamMsgQ->next= NULL;
UpStreamMsgQ->next = (UpStreamMsg *) malloc(sizeof(UpStreamMsg));
UpStreamMsgQ->next->msg = strdup("Second Message");
UpStreamMsgQ->next->len = 15;
UpStreamMsgQ->next->next = NULL;
temp = (wrp_msg_t *) malloc(sizeof(wrp_msg_t));
memset(temp,0,sizeof(wrp_msg_t));
temp->msg_type = 6;
temp->u.crud.dest = strdup("mac:14cfe2142xxx/config");
temp->u.crud.source = strdup("mac:14cfe2142xxx/parodus/cloud-status");
temp->u.crud.transaction_uuid = strdup("123");
will_return(wrp_to_struct, 12);
expect_function_call(wrp_to_struct);
will_return(sendMsgtoRegisteredClients, 1);
expect_function_call(sendMsgtoRegisteredClients);
expect_function_call(wrp_free_struct);
will_return(wrp_to_struct, 12);
expect_function_call(wrp_to_struct);
will_return(sendMsgtoRegisteredClients, 0);
expect_function_call(sendMsgtoRegisteredClients);
expect_function_call(wrp_free_struct);
processUpstreamMessage();
free(temp);
free(UpStreamMsgQ);
UpStreamMsgQ = NULL;
}
void test_processUpstreamMessageNullCheck()
{
numLoops = 1;
metaPackSize = 20;
UpStreamMsgQ = (UpStreamMsg *) malloc(sizeof(UpStreamMsg));
UpStreamMsgQ->msg = strdup("First Message");
UpStreamMsgQ->len = 13;
UpStreamMsgQ->next= NULL;
temp = (wrp_msg_t *) malloc(sizeof(wrp_msg_t));
memset(temp,0,sizeof(wrp_msg_t));
temp->msg_type = WRP_MSG_TYPE__RETREIVE;
temp->u.crud.dest = strdup("mac:14cfe2142xxx/parodus/cloud-status");
temp->u.crud.source = strdup("mac:14cfe2142xxx/config");
temp->u.crud.transaction_uuid = strdup("123");
will_return(wrp_to_struct, 12);
expect_function_call(wrp_to_struct);
expect_function_call(addCRUDmsgToQueue);
will_return(nn_freemsg, 0);
expect_function_call(nn_freemsg);
expect_function_call(wrp_free_struct);
processUpstreamMessage();
free(temp);
free(UpStreamMsgQ);
UpStreamMsgQ = NULL;
}
void err_processUpstreamMessageNullCheck()
{
numLoops = 1;
metaPackSize = 20;
UpStreamMsgQ = (UpStreamMsg *) malloc(sizeof(UpStreamMsg));
UpStreamMsgQ->msg = strdup("First Message");
UpStreamMsgQ->len = 13;
UpStreamMsgQ->next= NULL;
temp = (wrp_msg_t *) malloc(sizeof(wrp_msg_t));
memset(temp,0,sizeof(wrp_msg_t));
temp->msg_type = WRP_MSG_TYPE__RETREIVE;
temp->u.crud.dest = strdup("mac:/parodus/cloud-status");
temp->u.crud.source = strdup("mac:14cfe2142xxx/config");
temp->u.crud.transaction_uuid = strdup("123");
will_return(wrp_to_struct, 12);
expect_function_call(wrp_to_struct);
will_return(nn_freemsg, 0);
expect_function_call(nn_freemsg);
expect_function_call(wrp_free_struct);
processUpstreamMessage();
free(temp);
free(UpStreamMsgQ);
UpStreamMsgQ = NULL;
}
void err_processUpstreamMessageWithoutMac()
{
numLoops = 1;
metaPackSize = 20;
UpStreamMsgQ = (UpStreamMsg *) malloc(sizeof(UpStreamMsg));
UpStreamMsgQ->msg = strdup("First Message");
UpStreamMsgQ->len = 13;
UpStreamMsgQ->next= NULL;
temp = (wrp_msg_t *) malloc(sizeof(wrp_msg_t));
memset(temp,0,sizeof(wrp_msg_t));
temp->msg_type = WRP_MSG_TYPE__RETREIVE;
temp->u.crud.dest = strdup("/parodus/cloud-status");
temp->u.crud.source = strdup("mac:14cfe2142xxx/config");
temp->u.crud.transaction_uuid = strdup("123");
will_return(wrp_to_struct, 12);
expect_function_call(wrp_to_struct);
will_return(nn_freemsg, 0);
expect_function_call(nn_freemsg);
expect_function_call(wrp_free_struct);
processUpstreamMessage();
free(temp);
free(UpStreamMsgQ);
UpStreamMsgQ = NULL;
}
/*----------------------------------------------------------------------------*/
/* External Functions */
@@ -646,6 +852,7 @@ int main(void)
cmocka_unit_test(err_handleUpstreamBindFailure),
cmocka_unit_test(err_handleUpstreamSockFailure),
cmocka_unit_test(test_processUpstreamMessage),
cmocka_unit_test(test_processUpstreamReqMessage),
cmocka_unit_test(test_processUpstreamMessageInvalidPartner),
cmocka_unit_test(test_processUpstreamMessageRegMsg),
cmocka_unit_test(test_processUpstreamMessageRegMsgNoClients),
@@ -654,12 +861,18 @@ int main(void)
cmocka_unit_test(err_processUpstreamMessageMetapackFailure),
cmocka_unit_test(err_processUpstreamMessageRegMsg),
cmocka_unit_test(test_sendUpstreamMsgToServer),
cmocka_unit_test(test_sendUpstreamMsg_close_retry),
cmocka_unit_test(err_sendUpstreamMsgToServer),
cmocka_unit_test(test_get_global_UpStreamMsgQ),
cmocka_unit_test(test_set_global_UpStreamMsgQ),
cmocka_unit_test(test_get_global_nano_con),
cmocka_unit_test(test_get_global_nano_mut),
cmocka_unit_test(test_processUpstreamMsgCrud_nnfree),
cmocka_unit_test(test_processUpstreamMsg_cloud_status),
cmocka_unit_test(test_processUpstreamMsg_sendToClient),
cmocka_unit_test(test_processUpstreamMessageNullCheck),
cmocka_unit_test(err_processUpstreamMessageNullCheck),
cmocka_unit_test(err_processUpstreamMessageWithoutMac),
};
return cmocka_run_group_tests(tests, NULL, NULL);