Compare commits

...

39 Commits

Author SHA1 Message Date
Shilpa Seshadri
4676697b6b Clear auth token if fetch fails
(cherry picked from commit b134a646e5)
2019-08-26 02:52:34 -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
40 changed files with 3122 additions and 615 deletions

View File

@@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Configurable security flag and port.
- Default HTTP port to 80 and HTTPS port to 443.
- Updates to how `nopoll` is called have been implemented.
- Refactored connection.c and updated corresponding unit tests
### Fixed
- 64 bit pointer fixes (#144, #145).

View File

@@ -151,7 +151,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 "c2bc9be9dad6b0e4f7f9138f3d1074702ace7976"
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR}
-DMSGPACK_ENABLE_CXX=OFF
-DMSGPACK_BUILD_EXAMPLES=OFF

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,52 @@ 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 max_delay;
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':
@@ -520,6 +615,7 @@ void createNewAuthToken(char *newToken, size_t len)
{
//Call create script
char output[12] = {'\0'};
memset (newToken, 0, len);
execute_token_script(output,get_parodus_cfg()->token_acquisition_script,sizeof(output),get_parodus_cfg()->hw_mac,get_parodus_cfg()->hw_serial_number);
if (strlen(output)>0 && strcmp(output,"SUCCESS")==0)
{
@@ -541,7 +637,7 @@ void getAuthToken(ParodusCfg *cfg)
{
//local var to update cfg->webpa_auth_token only in success case
char output[4069] = {'\0'} ;
memset (cfg->webpa_auth_token, 0, sizeof(cfg->webpa_auth_token));
if( strlen(cfg->token_read_script) !=0 && strlen(cfg->token_acquisition_script) !=0)
{
execute_token_script(output,cfg->token_read_script,sizeof(output),cfg->hw_mac,cfg->hw_serial_number);
@@ -600,6 +696,8 @@ void setDefaultValuesToCfg(ParodusCfg *cfg)
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->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,14 +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;
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
@@ -86,7 +85,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 +124,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,14 +147,28 @@ 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());
close_and_unref_connection(get_global_conn());
nopoll_ctx_unref(ctx);

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,46 +83,465 @@ 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_delay)
{
timer->max_delay = max_delay;
timer->delay = 1;
}
int update_backoff_delay (backoff_timer_t *timer)
{
if (timer->delay < timer->max_delay)
timer->delay = timer->delay + timer->delay + 1;
// 3,7,15,31 ..
if (timer->delay > timer->max_delay)
timer->delay = timer->max_delay;
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,
int max_retry_sleep,
int query_dns_status)
{
backoff_timer_t backoff_timer;
int rtn;
init_backoff_timer (&backoff_timer, max_retry_sleep);
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)
if (query_dns_status < 0)
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_sleep;
int query_dns_status;
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);
@@ -131,285 +549,25 @@ int createNopollConnection(noPollCtx *ctx)
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
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);
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, max_retry_sleep, query_dns_status))
break;
// retry dns query
}
if(conn_ctx.current_server->allow_insecure <= 0)
{
ParodusInfo("Connected to server over SSL\n");
}
@@ -418,40 +576,24 @@ int createNopollConnection(noPollCtx *ctx)
ParodusInfo("Connected to server\n");
}
if (NULL != jwt_server_url)
{
free (jwt_server_url);
}
if(redirectURL != NULL)
{
free(redirectURL);
redirectURL = NULL;
}
if (NULL != extra_headers)
{
free (extra_headers);
extra_headers = NULL;
}
get_parodus_cfg()->cloud_status = CLOUD_STATUS_ONLINE;
ParodusInfo("cloud_status set as %s after successful connection\n", get_parodus_cfg()->cloud_status);
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 +614,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

@@ -90,7 +90,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

@@ -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,172 @@
/*----------------------------------------------------------------------------*/
/* 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++)
{
ParodusPrint("partnersList->partner_ids[%lu] = %s\n",j, partnersList->partner_ids[j]);
if(strcmp(partnersList->partner_ids[j], msg->u.event.partner_ids->partner_ids[i]) == 0)
{
ParodusInfo("partner_id match found\n");
matchFlag = 1;
break;
}
}
/* 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++)
{
ParodusPrint("partnersList->partner_ids[%lu] = %s\n",j, partnersList->partner_ids[j]);
if(strcmp(partnersList->partner_ids[j], msg->u.req.partner_ids->partner_ids[i]) == 0)
{
ParodusInfo("partner_id match found\n");
matchFlag = 1;
break;
}
}
}
/* 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(partnersList->partner_ids[j] != NULL)
{
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(partnersList->partner_ids[j] != NULL)
{
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,15 @@ 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 *destService, *destApplication =NULL;
char *sourceService, *sourceApplication =NULL;
int sendStatus =-1;
while(FOREVER())
{
@@ -319,24 +324,103 @@ void *processUpstreamMessage()
}
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)
{
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(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);
}
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 +454,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 +463,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

@@ -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
#-------------------------------------------------------------------------------
@@ -109,7 +123,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 +131,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 +163,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 +183,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,14 +222,14 @@ 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)
add_executable(test_upstream test_upstream.c ../src/upstream.c ../src/close_retry.c ../src/string_helpers.c)
target_link_libraries (test_upstream -lcmocka ${PARODUS_COMMON_LIBS} )
#-------------------------------------------------------------------------------
@@ -251,6 +265,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 +303,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)

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[3], NULL, test_mutex_reset_close_retry, NULL);
pthread_join(thread[3], 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);

View File

@@ -22,38 +22,173 @@
#include <setjmp.h>
#include <cmocka.h>
#include <assert.h>
#include <CUnit/Basic.h>
#include <nopoll.h>
#include "../src/ParodusInternal.h"
#include "../src/connection.h"
#include "../src/config.h"
extern void set_server_null (server_t *server);
extern void set_server_list_null (server_list_t *server_list);
extern int server_is_null (server_t *server);
extern server_t *get_current_server (server_list_t *server_list);
extern int parse_server_url (const char *full_url, server_t *server);
extern void init_expire_timer (expire_timer_t *timer);
extern int check_timer_expired (expire_timer_t *timer, long timeout_ms);
extern void init_backoff_timer (backoff_timer_t *timer, int max_delay);
extern int update_backoff_delay (backoff_timer_t *timer);
extern int init_header_info (header_info_t *header_info);
extern void free_header_info (header_info_t *header_info);
extern char *build_extra_hdrs (header_info_t *header_info);
extern void set_current_server (create_connection_ctx_t *ctx);
extern void set_extra_headers (create_connection_ctx_t *ctx, int reauthorize);
extern void free_extra_headers (create_connection_ctx_t *ctx);
extern void free_server_list (server_list_t *server_list);
extern void free_server (server_t *server);
extern int find_servers (server_list_t *server_list);
extern int nopoll_connect (create_connection_ctx_t *ctx, int is_ipv6);
extern int wait_connection_ready (create_connection_ctx_t *ctx);
extern int connect_and_wait (create_connection_ctx_t *ctx);
extern int keep_trying_to_connect (create_connection_ctx_t *ctx,
int max_retry_sleep,
int query_dns_status);
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
bool close_retry;
bool LastReasonStatus;
volatile unsigned int heartBeatTimer;
pthread_mutex_t close_mut;
// Mock values
char *mock_server_addr;
unsigned int mock_port;
int mock_wait_status;
char *mock_redirect;
noPollConn connection1;
noPollConn connection2;
noPollConn connection3;
/*----------------------------------------------------------------------------*/
/* Mocks */
/*----------------------------------------------------------------------------*/
char* getWebpaConveyHeader()
{
return NULL;
return (char*) "WebPA-1.6 (TG1682)";
}
noPollConn * nopoll_conn_new_opts (noPollCtx * ctx, noPollConnOpts * opts, const char * host_ip, const char * host_port, const char * host_name,const char * get_url,const char * protocols, const char * origin)
{
UNUSED(host_port); UNUSED(host_name); UNUSED(get_url); UNUSED(protocols);
UNUSED(origin); UNUSED(opts); UNUSED(ctx); UNUSED(host_ip);
function_called();
//check_expected((intptr_t)ctx);
//check_expected((intptr_t)host_ip);
return (noPollConn *) (intptr_t)mock();
}
noPollConn * nopoll_conn_tls_new (noPollCtx * ctx, noPollConnOpts * options, const char * host_ip, const char * host_port, const char * host_name, const char * get_url, const char * protocols, const char * origin)
{
UNUSED(options); UNUSED(host_port); UNUSED(host_name); UNUSED(get_url); UNUSED(protocols);
UNUSED(origin); UNUSED(ctx); UNUSED(host_ip);
function_called();
//check_expected((intptr_t)ctx);
//check_expected((intptr_t)host_ip);
return (noPollConn *) (intptr_t)mock();
}
noPollConn * nopoll_conn_tls_new6 (noPollCtx * ctx, noPollConnOpts * options, const char * host_ip, const char * host_port, const char * host_name, const char * get_url, const char * protocols, const char * origin)
{
UNUSED(options); UNUSED(host_port); UNUSED(host_name); UNUSED(get_url); UNUSED(protocols);
UNUSED(origin); UNUSED(ctx); UNUSED(host_ip);
function_called();
//check_expected((intptr_t)ctx);
//check_expected((intptr_t)host_ip);
return (noPollConn *) (intptr_t)mock();
}
nopoll_bool nopoll_conn_wait_for_status_until_connection_ready (noPollConn * conn,
int timeout, int *status, char ** message)
{
UNUSED(conn); UNUSED(timeout);
*status = mock_wait_status;
if ((NULL != mock_redirect) &&
((mock_wait_status == 307) || (mock_wait_status == 302) ||
(mock_wait_status == 303)) )
{
*message = malloc (strlen(mock_redirect) + 10);
sprintf (*message, "Redirect:%s", mock_redirect);
}
function_called();
return (nopoll_bool) mock();
}
nopoll_bool nopoll_conn_is_ok (noPollConn * conn)
{
UNUSED(conn);
function_called ();
return (nopoll_bool) mock();
}
void nopoll_conn_close (noPollConn *conn)
{
UNUSED(conn);
}
int nopoll_conn_ref_count (noPollConn *conn)
{
UNUSED(conn);
function_called ();
return (nopoll_bool) mock();
}
int checkHostIp(char * serverIP)
{
UNUSED(serverIP);
return 0;
function_called();
return (int) mock();
}
int kill(pid_t pid, int sig)
{
UNUSED(pid); UNUSED(sig);
function_called();
return (int) mock();
}
void setMessageHandlers()
{
}
int allow_insecure_conn (char **server_addr, unsigned int *port)
{
int rtn;
function_called ();
rtn = (int) mock();
if (rtn < 0) {
*server_addr = NULL;
return rtn;
}
if (NULL != mock_server_addr) {
size_t len = strlen(mock_server_addr) + 1;
*server_addr = malloc (len);
if (NULL != *server_addr) {
strncpy (*server_addr, mock_server_addr, len);
}
}
*port = mock_port;
return rtn;
}
/*----------------------------------------------------------------------------*/
/* Tests */
/*----------------------------------------------------------------------------*/
@@ -87,6 +222,778 @@ void test_closeConnection()
close_and_unref_connection(get_global_conn());
}
void test_server_is_null()
{
server_t test_server;
memset (&test_server, 0xFF, sizeof(test_server));
assert_int_equal (0, server_is_null (&test_server));
set_server_null (&test_server);
assert_int_equal (1, server_is_null (&test_server));
}
void test_server_list_null()
{
server_list_t server_list;
memset (&server_list, 0xFF, sizeof(server_list));
assert_int_equal (0, server_is_null (&server_list.defaults));
assert_int_equal (0, server_is_null (&server_list.jwt));
assert_int_equal (0, server_is_null (&server_list.redirect));
set_server_list_null (&server_list);
assert_int_equal (1, server_is_null (&server_list.defaults));
assert_int_equal (1, server_is_null (&server_list.jwt));
assert_int_equal (1, server_is_null (&server_list.redirect));
}
void test_get_current_server()
{
server_list_t server_list;
memset (&server_list, 0xFF, sizeof(server_list));
assert_ptr_equal (&server_list.redirect, get_current_server (&server_list));
set_server_null (&server_list.redirect);
assert_ptr_equal (&server_list.jwt, get_current_server (&server_list));
set_server_null (&server_list.jwt);
assert_ptr_equal (&server_list.defaults, get_current_server (&server_list));
}
void test_parse_server_url ()
{
server_t test_server;
assert_int_equal (parse_server_url ("mydns.mycom.net:8080",
&test_server), -1);
assert_int_equal (-1, test_server.allow_insecure);
assert_int_equal (parse_server_url ("https://mydns.mycom.net:8080",
&test_server), 0);
assert_string_equal (test_server.server_addr, "mydns.mycom.net");
assert_int_equal (test_server.port, 8080);
assert_int_equal (0, test_server.allow_insecure);
assert_int_equal (parse_server_url ("https://mydns.mycom.net/",
&test_server), 0);
assert_string_equal (test_server.server_addr, "mydns.mycom.net");
assert_int_equal (test_server.port, 443);
assert_int_equal (0, test_server.allow_insecure);
assert_int_equal (parse_server_url ("http://mydns.mycom.net:8080",
&test_server), 1);
assert_string_equal (test_server.server_addr, "mydns.mycom.net");
assert_int_equal (test_server.port, 8080);
assert_int_equal (1, test_server.allow_insecure);
assert_int_equal (parse_server_url ("http://mydns.mycom.net",
&test_server), 1);
assert_string_equal (test_server.server_addr, "mydns.mycom.net");
assert_int_equal (test_server.port, 80);
assert_int_equal (1, test_server.allow_insecure);
}
void test_expire_timer()
{
expire_timer_t exp_timer;
init_expire_timer (&exp_timer);
assert_int_equal (false, check_timer_expired (&exp_timer, 1000));
sleep (2);
assert_int_equal (false, check_timer_expired (&exp_timer, 3000));
assert_int_equal (true, check_timer_expired (&exp_timer, 1000));
}
void test_backoff_delay_timer()
{
backoff_timer_t btimer;
init_backoff_timer (&btimer, 30);
assert_int_equal (3, update_backoff_delay (&btimer));
assert_int_equal (7, update_backoff_delay (&btimer));
assert_int_equal (15, update_backoff_delay (&btimer));
assert_int_equal (30, update_backoff_delay (&btimer));
assert_int_equal (30, update_backoff_delay (&btimer));
}
void test_header_info ()
{
header_info_t hinfo;
ParodusCfg Cfg;
memset(&Cfg, 0, sizeof(ParodusCfg));
parStrncpy(Cfg.hw_model, "TG1682", sizeof(Cfg.hw_model));
parStrncpy(Cfg.hw_manufacturer , "ARRISGroup,Inc.", sizeof(Cfg.hw_manufacturer));
parStrncpy(Cfg.hw_mac , "123567892366", sizeof(Cfg.hw_mac));
parStrncpy(Cfg.fw_name , "2.364s2", sizeof(Cfg.fw_name));
parStrncpy(Cfg.webpa_protocol , "WebPA-1.6", sizeof(Cfg.webpa_protocol));
set_parodus_cfg(&Cfg);
init_header_info (&hinfo);
assert_string_equal (hinfo.conveyHeader, "WebPA-1.6 (TG1682)");
assert_string_equal (hinfo.device_id, "mac:123567892366");
assert_string_equal (hinfo.user_agent,
"WebPA-1.6 (2.364s2; TG1682/ARRISGroup,Inc.;)");
free_header_info (&hinfo);
}
void test_extra_headers ()
{
header_info_t hinfo;
ParodusCfg Cfg;
const char *expected_extra_headers =
"\r\nAuthorization: Bearer Auth---"
"\r\nX-WebPA-Device-Name: mac:123567892366"
"\r\nX-WebPA-Device-Protocols: wrp-0.11,getset-0.1"
"\r\nUser-Agent: WebPA-1.6 (2.364s2; TG1682/ARRISGroup,Inc.;)"
"\r\nX-WebPA-Convey: WebPA-1.6 (TG1682)";
char *extra_headers;
memset(&Cfg, 0, sizeof(ParodusCfg));
parStrncpy (Cfg.webpa_auth_token, "Auth---", sizeof (Cfg.webpa_auth_token));
parStrncpy(Cfg.hw_model, "TG1682", sizeof(Cfg.hw_model));
parStrncpy(Cfg.hw_manufacturer , "ARRISGroup,Inc.", sizeof(Cfg.hw_manufacturer));
parStrncpy(Cfg.hw_mac , "123567892366", sizeof(Cfg.hw_mac));
parStrncpy(Cfg.fw_name , "2.364s2", sizeof(Cfg.fw_name));
parStrncpy(Cfg.webpa_protocol , "WebPA-1.6", sizeof(Cfg.webpa_protocol));
set_parodus_cfg(&Cfg);
init_header_info (&hinfo);
extra_headers = build_extra_hdrs (&hinfo);
assert_string_equal (extra_headers, expected_extra_headers);
free (extra_headers);
free_header_info (&hinfo);
}
void test_set_current_server()
{
create_connection_ctx_t ctx;
memset (&ctx, 0xFF, sizeof(ctx));
set_current_server (&ctx);
assert_ptr_equal (&ctx.server_list.redirect, ctx.current_server);
set_server_null (&ctx.server_list.redirect);
set_current_server (&ctx);
assert_ptr_equal (&ctx.server_list.jwt, ctx.current_server);
set_server_null (&ctx.server_list.jwt);
set_current_server (&ctx);
assert_ptr_equal (&ctx.server_list.defaults, ctx.current_server);
}
void test_set_extra_headers ()
{
int rtn;
create_connection_ctx_t ctx;
ParodusCfg cfg;
const char *expected_extra_headers =
"\r\nAuthorization: Bearer SER_MAC Fer23u948590 123567892366"
"\r\nX-WebPA-Device-Name: mac:123567892366"
"\r\nX-WebPA-Device-Protocols: wrp-0.11,getset-0.1"
"\r\nUser-Agent: WebPA-1.6 (2.364s2; TG1682/ARRISGroup,Inc.;)"
"\r\nX-WebPA-Convey: WebPA-1.6 (TG1682)";
memset(&cfg,0,sizeof(cfg));
memset (&ctx, 0, sizeof(ctx));
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));
parStrncpy(cfg.hw_model, "TG1682", sizeof(cfg.hw_model));
parStrncpy(cfg.hw_manufacturer , "ARRISGroup,Inc.", sizeof(cfg.hw_manufacturer));
parStrncpy(cfg.fw_name , "2.364s2", sizeof(cfg.fw_name));
parStrncpy(cfg.webpa_protocol , "WebPA-1.6", sizeof(cfg.webpa_protocol));
set_parodus_cfg(&cfg);
rtn = init_header_info (&ctx.header_info);
assert_int_equal (rtn, 0);
assert_string_equal (ctx.header_info.device_id, "mac:123567892366");
assert_string_equal (ctx.header_info.user_agent,
"WebPA-1.6 (2.364s2; TG1682/ARRISGroup,Inc.;)");
assert_string_equal (ctx.header_info.conveyHeader, "WebPA-1.6 (TG1682)");
set_extra_headers (&ctx, true);
assert_string_equal (get_parodus_cfg()->webpa_auth_token,
"SER_MAC Fer23u948590 123567892366");
assert_string_equal (ctx.extra_headers, expected_extra_headers);
free (ctx.extra_headers);
free_header_info (&ctx.header_info);
}
void test_find_servers ()
{
ParodusCfg cfg;
server_list_t server_list;
server_t *default_server = &server_list.defaults;
#ifdef FEATURE_DNS_QUERY
server_t *jwt_server = &server_list.jwt;
#endif
memset(&cfg,0,sizeof(cfg));
set_server_list_null (&server_list);
parStrncpy (cfg.webpa_url, "mydns.mycom.net:8080", sizeof(cfg.webpa_url));
set_parodus_cfg(&cfg);
assert_int_equal (find_servers(&server_list), FIND_INVALID_DEFAULT);
assert_int_equal (default_server->allow_insecure, -1);
parStrncpy (cfg.webpa_url, "https://mydns.mycom.net:8080", sizeof(cfg.webpa_url));
#ifdef FEATURE_DNS_QUERY
cfg.acquire_jwt = 0;
set_parodus_cfg(&cfg);
assert_int_equal (find_servers(&server_list), FIND_SUCCESS);
assert_int_equal (default_server->allow_insecure, 0);
assert_string_equal (default_server->server_addr, "mydns.mycom.net");
assert_int_equal (default_server->port, 8080);
cfg.acquire_jwt = 1;
mock_server_addr = "mydns.myjwtcom.net";
mock_port = 80;
set_parodus_cfg(&cfg);
will_return (allow_insecure_conn, -1);
expect_function_call (allow_insecure_conn);
assert_int_equal (find_servers(&server_list), FIND_JWT_FAIL);
assert_int_equal (jwt_server->allow_insecure, -1);
will_return (allow_insecure_conn, 0);
expect_function_call (allow_insecure_conn);
assert_int_equal (find_servers(&server_list), FIND_SUCCESS);
assert_int_equal (jwt_server->allow_insecure, 0);
assert_string_equal (jwt_server->server_addr, "mydns.myjwtcom.net");
assert_int_equal (jwt_server->port, 80);
#else
set_parodus_cfg(&cfg);
assert_int_equal (find_servers(&server_list), FIND_SUCCESS);
assert_int_equal (default_server->allow_insecure, 0);
assert_string_equal (default_server->server_addr, "mydns.mycom.net");
assert_int_equal (default_server->port, 8080);
free_server_list (&server_list);
#endif
}
void test_nopoll_connect ()
{
ParodusCfg cfg;
create_connection_ctx_t ctx;
noPollCtx test_nopoll_ctx;
server_t test_server;
char *test_extra_headers =
"\r\nAuthorization: Bearer SER_MAC Fer23u948590 123567892366"
"\r\nX-WebPA-Device-Name: mac:123567892366"
"\r\nX-WebPA-Device-Protocols: wrp-0.11,getset-0.1"
"\r\nUser-Agent: WebPA-1.6 (2.364s2; TG1682/ARRISGroup,Inc.;)"
"\r\nX-WebPA-Convey: WebPA-1.6 (TG1682)";
ctx.nopoll_ctx = &test_nopoll_ctx;
ctx.current_server = &test_server;
ctx.extra_headers = test_extra_headers;
memset(&cfg,0,sizeof(cfg));
parStrncpy (cfg.webpa_url, "http://mydns.mycom.net:8080", sizeof(cfg.webpa_url));
set_parodus_cfg(&cfg);
init_expire_timer (&ctx.connect_timer);
test_server.allow_insecure = 1;
test_server.server_addr = "mydns.mycom.net";
test_server.port = 8080;
will_return (nopoll_conn_new_opts, &connection1);
expect_function_call (nopoll_conn_new_opts);
assert_int_equal (nopoll_connect (&ctx, true), 1);
assert_ptr_equal(&connection1, get_global_conn());
test_server.allow_insecure = 0;
will_return (nopoll_conn_tls_new6, &connection2);
expect_function_call (nopoll_conn_tls_new6);
assert_int_equal (nopoll_connect (&ctx, true), 1);
assert_ptr_equal(&connection2, get_global_conn());
will_return (nopoll_conn_tls_new, &connection3);
expect_function_call (nopoll_conn_tls_new);
assert_int_equal (nopoll_connect (&ctx, false), 1);
assert_ptr_equal(&connection3, get_global_conn());
test_server.allow_insecure = 1;
will_return (nopoll_conn_new_opts, NULL);
expect_function_call (nopoll_conn_new_opts);
will_return (checkHostIp, 0);
expect_function_call (checkHostIp);
assert_int_equal (nopoll_connect (&ctx, true), 0);
assert_ptr_equal(NULL, get_global_conn());
test_server.allow_insecure = 0;
will_return (nopoll_conn_tls_new6, NULL);
expect_function_call (nopoll_conn_tls_new6);
will_return (checkHostIp, 0);
expect_function_call (checkHostIp);
assert_int_equal (nopoll_connect (&ctx, true), 0);
assert_ptr_equal(NULL, get_global_conn());
will_return (nopoll_conn_tls_new6, NULL);
expect_function_call (nopoll_conn_tls_new6);
will_return (checkHostIp, -2);
expect_function_call (checkHostIp);
assert_int_equal (nopoll_connect (&ctx, true), 0);
assert_ptr_equal(NULL, get_global_conn());
will_return (nopoll_conn_tls_new6, NULL);
expect_function_call (nopoll_conn_tls_new6);
will_return (checkHostIp, -2);
expect_function_call (checkHostIp);
ctx.connect_timer.start_time.tv_sec -= (15*60);
will_return(kill, 1);
expect_function_call(kill);
assert_int_equal (nopoll_connect (&ctx, true), 0);
assert_ptr_equal(NULL, get_global_conn());
init_expire_timer (&ctx.connect_timer);
will_return (nopoll_conn_tls_new, NULL);
expect_function_call (nopoll_conn_tls_new);
will_return (checkHostIp, 0);
expect_function_call (checkHostIp);
assert_int_equal (nopoll_connect (&ctx, false), 0);
assert_ptr_equal(NULL, get_global_conn());
}
// 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
void test_wait_connection_ready ()
{
create_connection_ctx_t ctx;
ParodusCfg Cfg;
const char *expected_extra_headers =
"\r\nAuthorization: Bearer Auth---"
"\r\nX-WebPA-Device-Name: mac:123567892366"
"\r\nX-WebPA-Device-Protocols: wrp-0.11,getset-0.1"
"\r\nUser-Agent: WebPA-1.6 (2.364s2; TG1682/ARRISGroup,Inc.;)"
"\r\nX-WebPA-Convey: WebPA-1.6 (TG1682)";
memset(&ctx,0,sizeof(ctx));
set_server_list_null (&ctx.server_list);
mock_wait_status = 0;
mock_redirect = NULL;
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_true);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
assert_int_equal (wait_connection_ready (&ctx), WAIT_SUCCESS);
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_false);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
assert_int_equal (wait_connection_ready (&ctx), WAIT_FAIL);
mock_wait_status = 307;
mock_redirect = "mydns.mycom.net";
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_false);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
assert_int_equal (wait_connection_ready (&ctx), WAIT_FAIL);
mock_wait_status = 302;
mock_redirect = "https://mydns.mycom.net:8080";
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_false);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
assert_int_equal (wait_connection_ready (&ctx), WAIT_ACTION_RETRY);
assert_string_equal (ctx.server_list.redirect.server_addr, "mydns.mycom.net");
assert_int_equal (ctx.server_list.redirect.port, 8080);
assert_int_equal (0, ctx.server_list.redirect.allow_insecure);
assert_ptr_equal (ctx.current_server, &ctx.server_list.redirect);
free_server (&ctx.server_list.redirect);
mock_wait_status = 303;
mock_redirect = "http://mydns.mycom.net";
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_false);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
assert_int_equal (wait_connection_ready (&ctx), WAIT_ACTION_RETRY);
assert_string_equal (ctx.server_list.redirect.server_addr, "mydns.mycom.net");
assert_int_equal (ctx.server_list.redirect.port, 80);
assert_int_equal (1, ctx.server_list.redirect.allow_insecure);
assert_ptr_equal (ctx.current_server, &ctx.server_list.redirect);
free_server (&ctx.server_list.redirect);
mock_wait_status = 403;
memset(&Cfg, 0, sizeof(ParodusCfg));
parStrncpy (Cfg.webpa_auth_token, "Auth---", sizeof (Cfg.webpa_auth_token));
parStrncpy(Cfg.hw_model, "TG1682", sizeof(Cfg.hw_model));
parStrncpy(Cfg.hw_manufacturer , "ARRISGroup,Inc.", sizeof(Cfg.hw_manufacturer));
parStrncpy(Cfg.hw_mac , "123567892366", sizeof(Cfg.hw_mac));
parStrncpy(Cfg.fw_name , "2.364s2", sizeof(Cfg.fw_name));
parStrncpy(Cfg.webpa_protocol , "WebPA-1.6", sizeof(Cfg.webpa_protocol));
set_parodus_cfg(&Cfg);
init_header_info (&ctx.header_info);
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_false);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
assert_int_equal (wait_connection_ready (&ctx), WAIT_ACTION_RETRY);
assert_string_equal (ctx.extra_headers, expected_extra_headers);
free_extra_headers (&ctx);
free_header_info (&ctx.header_info);
}
// 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
void test_connect_and_wait ()
{
create_connection_ctx_t ctx;
noPollCtx test_nopoll_ctx;
server_t test_server;
ParodusCfg Cfg;
char *test_extra_headers =
"\r\nAuthorization: Bearer SER_MAC Fer23u948590 123567892366"
"\r\nX-WebPA-Device-Name: mac:123567892366"
"\r\nX-WebPA-Device-Protocols: wrp-0.11,getset-0.1"
"\r\nUser-Agent: WebPA-1.6 (2.364s2; TG1682/ARRISGroup,Inc.;)"
"\r\nX-WebPA-Convey: WebPA-1.6 (TG1682)";
memset(&Cfg, 0, sizeof(ParodusCfg));
parStrncpy (Cfg.webpa_url, "http://mydns.mycom.net:8080", sizeof(Cfg.webpa_url));
mock_wait_status = 0;
memset(&ctx,0,sizeof(ctx));
ctx.nopoll_ctx = &test_nopoll_ctx;
ctx.current_server = &test_server;
ctx.extra_headers = test_extra_headers;
Cfg.flags = FLAGS_IPV4_ONLY;
set_parodus_cfg(&Cfg);
test_server.allow_insecure = 1;
test_server.server_addr = "mydns.mycom.net";
test_server.port = 8080;
will_return (nopoll_conn_new_opts, NULL);
expect_function_call (nopoll_conn_new_opts);
will_return (checkHostIp, 0);
expect_function_call (checkHostIp);
assert_int_equal (connect_and_wait (&ctx), CONN_WAIT_RETRY_DNS);
Cfg.flags = 0;
set_parodus_cfg(&Cfg);
will_return (nopoll_conn_new_opts, &connection1);
expect_function_call (nopoll_conn_new_opts);
will_return (nopoll_conn_is_ok, nopoll_false);
expect_function_call (nopoll_conn_is_ok);
will_return (nopoll_conn_ref_count, 0);
expect_function_call (nopoll_conn_ref_count);
assert_int_equal (connect_and_wait (&ctx), CONN_WAIT_RETRY_DNS);
will_return (nopoll_conn_new_opts, &connection1);
expect_function_call (nopoll_conn_new_opts);
will_return (nopoll_conn_is_ok, nopoll_true);
expect_function_call (nopoll_conn_is_ok);
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_true);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
assert_int_equal (connect_and_wait (&ctx), CONN_WAIT_SUCCESS);
Cfg.flags = FLAGS_IPV6_ONLY;
set_parodus_cfg(&Cfg);
test_server.allow_insecure = 0;
will_return (nopoll_conn_tls_new6, NULL);
expect_function_call (nopoll_conn_tls_new6);
will_return (checkHostIp, 0);
expect_function_call (checkHostIp);
assert_int_equal (connect_and_wait (&ctx), CONN_WAIT_RETRY_DNS);
Cfg.flags = 0;
set_parodus_cfg(&Cfg);
will_return (nopoll_conn_tls_new6, NULL);
expect_function_call (nopoll_conn_tls_new6);
will_return (checkHostIp, 0);
expect_function_call (checkHostIp);
will_return (nopoll_conn_tls_new, NULL);
expect_function_call (nopoll_conn_tls_new);
will_return (checkHostIp, 0);
expect_function_call (checkHostIp);
assert_int_equal (connect_and_wait (&ctx), CONN_WAIT_RETRY_DNS);
will_return (nopoll_conn_tls_new6, &connection1);
expect_function_call (nopoll_conn_tls_new6);
will_return (nopoll_conn_is_ok, nopoll_false);
expect_function_call (nopoll_conn_is_ok);
will_return (nopoll_conn_ref_count, 0);
expect_function_call (nopoll_conn_ref_count);
will_return (nopoll_conn_tls_new, NULL);
expect_function_call (nopoll_conn_tls_new);
will_return (checkHostIp, 0);
expect_function_call (checkHostIp);
assert_int_equal (connect_and_wait (&ctx), CONN_WAIT_RETRY_DNS);
will_return (nopoll_conn_tls_new6, &connection1);
expect_function_call (nopoll_conn_tls_new6);
will_return (nopoll_conn_is_ok, nopoll_false);
expect_function_call (nopoll_conn_is_ok);
will_return (nopoll_conn_ref_count, 0);
expect_function_call (nopoll_conn_ref_count);
will_return (nopoll_conn_tls_new, &connection1);
expect_function_call (nopoll_conn_tls_new);
will_return (nopoll_conn_is_ok, nopoll_true);
expect_function_call (nopoll_conn_is_ok);
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_true);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
assert_int_equal (connect_and_wait (&ctx), CONN_WAIT_SUCCESS);
Cfg.flags = FLAGS_IPV4_ONLY;
set_parodus_cfg(&Cfg);
will_return (nopoll_conn_tls_new, &connection1);
expect_function_call (nopoll_conn_tls_new);
will_return (nopoll_conn_is_ok, nopoll_true);
expect_function_call (nopoll_conn_is_ok);
mock_wait_status = 307;
mock_redirect = "mydns.mycom.net";
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_false);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
will_return (nopoll_conn_ref_count, 0);
expect_function_call (nopoll_conn_ref_count);
assert_int_equal (connect_and_wait (&ctx), CONN_WAIT_RETRY_DNS);
will_return (nopoll_conn_tls_new, &connection1);
expect_function_call (nopoll_conn_tls_new);
will_return (nopoll_conn_is_ok, nopoll_true);
expect_function_call (nopoll_conn_is_ok);
mock_wait_status = 302;
mock_redirect = "https://mydns.mycom.net";
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_false);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
will_return (nopoll_conn_ref_count, 0);
expect_function_call (nopoll_conn_ref_count);
assert_int_equal (connect_and_wait (&ctx), CONN_WAIT_ACTION_RETRY);
}
void test_keep_trying ()
{
int rtn;
create_connection_ctx_t ctx;
noPollCtx test_nopoll_ctx;
server_t test_server;
ParodusCfg Cfg;
char *test_extra_headers =
"\r\nAuthorization: Bearer SER_MAC Fer23u948590 123567892366"
"\r\nX-WebPA-Device-Name: mac:123567892366"
"\r\nX-WebPA-Device-Protocols: wrp-0.11,getset-0.1"
"\r\nUser-Agent: WebPA-1.6 (2.364s2; TG1682/ARRISGroup,Inc.;)"
"\r\nX-WebPA-Convey: WebPA-1.6 (TG1682)";
memset(&Cfg, 0, sizeof(ParodusCfg));
parStrncpy (Cfg.webpa_url, "http://mydns.mycom.net:8080", sizeof(Cfg.webpa_url));
mock_wait_status = 0;
memset(&ctx,0,sizeof(ctx));
ctx.nopoll_ctx = &test_nopoll_ctx;
ctx.current_server = &test_server;
ctx.extra_headers = test_extra_headers;
test_server.allow_insecure = 1;
test_server.server_addr = "mydns.mycom.net";
test_server.port = 8080;
Cfg.flags = 0;
set_parodus_cfg(&Cfg);
will_return (nopoll_conn_new_opts, &connection1);
expect_function_call (nopoll_conn_new_opts);
will_return (nopoll_conn_is_ok, nopoll_true);
expect_function_call (nopoll_conn_is_ok);
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_true);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
rtn = keep_trying_to_connect (&ctx, 30, -1);
assert_int_equal (rtn, true);
test_server.allow_insecure = 0;
Cfg.flags = FLAGS_IPV4_ONLY;
set_parodus_cfg(&Cfg);
will_return (nopoll_conn_tls_new, &connection1);
expect_function_call (nopoll_conn_tls_new);
will_return (nopoll_conn_is_ok, nopoll_true);
expect_function_call (nopoll_conn_is_ok);
mock_wait_status = 302;
mock_redirect = "https://mydns.mycom.net";
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_false);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
will_return (nopoll_conn_ref_count, 0);
expect_function_call (nopoll_conn_ref_count);
will_return (nopoll_conn_tls_new, &connection1);
expect_function_call (nopoll_conn_tls_new);
will_return (nopoll_conn_is_ok, nopoll_true);
expect_function_call (nopoll_conn_is_ok);
mock_wait_status = 0;
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_true);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
rtn = keep_trying_to_connect (&ctx, 30, 0);
assert_int_equal (rtn, true);
will_return (nopoll_conn_tls_new, NULL);
expect_function_call (nopoll_conn_tls_new);
will_return (checkHostIp, 0);
expect_function_call (checkHostIp);
will_return (nopoll_conn_tls_new, &connection1);
expect_function_call (nopoll_conn_tls_new);
will_return (nopoll_conn_is_ok, nopoll_true);
expect_function_call (nopoll_conn_is_ok);
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_true);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
rtn = keep_trying_to_connect (&ctx, 30, 0);
assert_int_equal (rtn, true);
mock_wait_status = 302;
mock_redirect = "mydns.mycom.net";
will_return (nopoll_conn_tls_new, &connection1);
expect_function_call (nopoll_conn_tls_new);
will_return (nopoll_conn_is_ok, nopoll_true);
expect_function_call (nopoll_conn_is_ok);
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_false);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
will_return (nopoll_conn_ref_count, 0);
expect_function_call (nopoll_conn_ref_count);
rtn = keep_trying_to_connect (&ctx, 30, -1);
assert_int_equal (rtn, false);
}
void test_create_nopoll_connection()
{
int rtn;
ParodusCfg cfg;
noPollCtx test_nopoll_ctx;
memset(&cfg,0,sizeof(cfg));
cfg.flags = 0;
parStrncpy (cfg.webpa_url, "mydns.mycom.net:8080", sizeof(cfg.webpa_url));
cfg.boot_time = 25;
parStrncpy (cfg.hw_last_reboot_reason, "Test reason", sizeof(cfg.hw_last_reboot_reason));
cfg.webpa_backoff_max = 30;
parStrncpy (cfg.webpa_auth_token, "Auth---", sizeof (cfg.webpa_auth_token));
parStrncpy(cfg.hw_model, "TG1682", sizeof(cfg.hw_model));
parStrncpy(cfg.hw_manufacturer , "ARRISGroup,Inc.", sizeof(cfg.hw_manufacturer));
parStrncpy(cfg.hw_mac , "123567892366", sizeof(cfg.hw_mac));
parStrncpy(cfg.fw_name , "2.364s2", sizeof(cfg.fw_name));
parStrncpy(cfg.webpa_protocol , "WebPA-1.6", sizeof(cfg.webpa_protocol));
set_parodus_cfg(&cfg);
rtn = createNopollConnection (&test_nopoll_ctx);
assert_int_equal (rtn, nopoll_false);
parStrncpy (cfg.webpa_url, "http://mydns.mycom.net:8080", sizeof(cfg.webpa_url));
set_parodus_cfg(&cfg);
mock_wait_status = 0;
will_return (nopoll_conn_new_opts, &connection1);
expect_function_call (nopoll_conn_new_opts);
will_return (nopoll_conn_is_ok, nopoll_true);
expect_function_call (nopoll_conn_is_ok);
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_true);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
rtn = createNopollConnection (&test_nopoll_ctx);
assert_int_equal (rtn, nopoll_true);
parStrncpy (cfg.webpa_url, "https://mydns.mycom.net:8080", sizeof(cfg.webpa_url));
cfg.flags = 0;
set_parodus_cfg(&cfg);
will_return (nopoll_conn_tls_new6, &connection1);
expect_function_call (nopoll_conn_tls_new6);
will_return (nopoll_conn_is_ok, nopoll_false);
expect_function_call (nopoll_conn_is_ok);
will_return (nopoll_conn_ref_count, 0);
expect_function_call (nopoll_conn_ref_count);
will_return (nopoll_conn_tls_new, &connection1);
expect_function_call (nopoll_conn_tls_new);
will_return (nopoll_conn_is_ok, nopoll_true);
expect_function_call (nopoll_conn_is_ok);
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_true);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
rtn = createNopollConnection (&test_nopoll_ctx);
assert_int_equal (rtn, nopoll_true);
will_return (nopoll_conn_tls_new6, &connection1);
expect_function_call (nopoll_conn_tls_new6);
will_return (nopoll_conn_is_ok, nopoll_false);
expect_function_call (nopoll_conn_is_ok);
will_return (nopoll_conn_ref_count, 0);
expect_function_call (nopoll_conn_ref_count);
will_return (nopoll_conn_tls_new, &connection1);
expect_function_call (nopoll_conn_tls_new);
will_return (nopoll_conn_is_ok, nopoll_true);
expect_function_call (nopoll_conn_is_ok);
mock_wait_status = 302;
mock_redirect = "https://mydns.mycom.net";
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_false);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
will_return (nopoll_conn_ref_count, 0);
expect_function_call (nopoll_conn_ref_count);
will_return (nopoll_conn_tls_new6, &connection1);
expect_function_call (nopoll_conn_tls_new6);
will_return (nopoll_conn_is_ok, nopoll_false);
expect_function_call (nopoll_conn_is_ok);
will_return (nopoll_conn_ref_count, 0);
expect_function_call (nopoll_conn_ref_count);
will_return (nopoll_conn_tls_new, &connection1);
expect_function_call (nopoll_conn_tls_new);
will_return (nopoll_conn_is_ok, nopoll_true);
expect_function_call (nopoll_conn_is_ok);
mock_wait_status = 0;
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_true);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
rtn = createNopollConnection (&test_nopoll_ctx);
assert_int_equal (rtn, nopoll_true);
#ifdef FEATURE_DNS_QUERY
cfg.acquire_jwt = 1;
cfg.flags = FLAGS_IPV4_ONLY;
set_parodus_cfg(&cfg);
will_return (allow_insecure_conn, -1);
expect_function_call (allow_insecure_conn);
will_return (nopoll_conn_tls_new, NULL);
expect_function_call (nopoll_conn_tls_new);
will_return (checkHostIp, 0);
expect_function_call (checkHostIp);
mock_server_addr = "mydns.myjwtcom.net";
mock_port = 80;
will_return (allow_insecure_conn, 0);
expect_function_call (allow_insecure_conn);
will_return (nopoll_conn_tls_new, &connection1);
expect_function_call (nopoll_conn_tls_new);
will_return (nopoll_conn_is_ok, nopoll_true);
expect_function_call (nopoll_conn_is_ok);
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_true);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
rtn = createNopollConnection (&test_nopoll_ctx);
assert_int_equal (rtn, nopoll_true);
cfg.flags = 0;
set_parodus_cfg(&cfg);
will_return (allow_insecure_conn, -1);
expect_function_call (allow_insecure_conn);
will_return (nopoll_conn_tls_new6, &connection1);
expect_function_call (nopoll_conn_tls_new6);
will_return (nopoll_conn_is_ok, nopoll_false);
expect_function_call (nopoll_conn_is_ok);
will_return (nopoll_conn_ref_count, 0);
expect_function_call (nopoll_conn_ref_count);
mock_wait_status = 0;
will_return (nopoll_conn_tls_new, &connection1);
expect_function_call (nopoll_conn_tls_new);
will_return (nopoll_conn_is_ok, nopoll_true);
expect_function_call (nopoll_conn_is_ok);
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_true);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
rtn = createNopollConnection (&test_nopoll_ctx);
assert_int_equal (rtn, nopoll_true);
#endif
}
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
@@ -98,6 +1005,22 @@ int main(void)
cmocka_unit_test(test_get_global_reconnect_reason),
cmocka_unit_test(test_set_global_reconnect_reason),
cmocka_unit_test(test_closeConnection),
cmocka_unit_test(test_server_is_null),
cmocka_unit_test(test_server_list_null),
cmocka_unit_test(test_get_current_server),
cmocka_unit_test(test_parse_server_url),
cmocka_unit_test(test_expire_timer),
cmocka_unit_test(test_backoff_delay_timer),
cmocka_unit_test(test_header_info),
cmocka_unit_test(test_extra_headers),
cmocka_unit_test(test_set_current_server),
cmocka_unit_test(test_set_extra_headers),
cmocka_unit_test(test_find_servers),
cmocka_unit_test(test_nopoll_connect),
cmocka_unit_test(test_wait_connection_ready),
cmocka_unit_test(test_connect_and_wait),
cmocka_unit_test(test_keep_trying),
cmocka_unit_test(test_create_nopoll_connection)
};
return cmocka_run_group_tests(tests, NULL, NULL);

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[3], NULL, test_mutexResetTimer, NULL);
pthread_join(thread[3], 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,7 @@ 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;
@@ -51,7 +51,7 @@ void test_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, "shaw,bar,comcast", sizeof(cfg.partner_id));
will_return(get_parodus_cfg, (intptr_t)&cfg);
expect_function_call(get_parodus_cfg);
@@ -68,7 +68,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 +103,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 +114,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 +122,7 @@ 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);

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,76 @@ 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;
}
/*----------------------------------------------------------------------------*/
/* External Functions */
@@ -646,6 +777,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 +786,15 @@ 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),
};
return cmocka_run_group_tests(tests, NULL, NULL);