Compare commits

..

78 Commits

Author SHA1 Message Date
shilpa24balaji
f032d2ca30 Merge pull request #347 from xmidt-org/4.1_pb
4.1 pb
2020-03-18 14:28:54 -07:00
shilpa24balaji
9cfc734c51 Merge pull request #331 from rajnishdey/errMsgUpdate
Change Info log level from error log level for "received temporary re…
2019-11-18 10:51:06 -08:00
Rajnish
153add9bec Change Info log level from error log level for "received temporary redirection response". 2019-11-18 11:28:43 -05:00
shilpa24balaji
7679fdaf4a Merge pull request #327 from bill1600/ifcdown
update backoff delay and interface down logic
2019-11-15 12:27:41 -08:00
Bill Williams
1c09a80493 fix condition test in wait_while_interface_down 2019-11-14 15:31:28 -08:00
Bill Williams
bfad8ed44b fix deadlock in wait_while_interface_down 2019-11-14 10:56:47 -08:00
Shilpa Seshadri
8c576f8f48 Merge tag '1.1.2' of https://github.com/Comcast/parodus into parodus_debug
Nov 2019 release
2019-11-13 12:58:37 -08:00
Shilpa Seshadri
dacac5fe8d To print nopoll debug logs changing level to info 2019-11-13 12:02:01 -08:00
Bill Williams
17c7faff50 update backoff delay error logging 2019-11-12 15:12:53 -08:00
Bill Williams
01120da9ac backoff delay updates 2019-11-12 14:37:10 -08:00
shilpa24balaji
c7c6fb4926 Merge pull request #328 from bill1600/nosig9
Nosig9
2019-11-12 10:30:59 -08:00
Bill Williams
f4b2c252ae update changelog for nosig9 2019-11-12 10:18:40 -08:00
Bill Williams
8794ce2092 dont try to install handler for signal 9 2019-11-12 10:17:01 -08:00
Bill Williams
a61e97633b update backoff delay for interface down 2019-11-11 13:24:07 -08:00
shilpa24balaji
4d3d6ec99d Merge pull request #326 from bill1600/bkpshut
update parodus shutdown
2019-11-06 10:42:54 -08:00
shilpa24balaji
e6ac264e47 Update CHANGELOG.md 2019-11-06 10:31:53 -08:00
Bill Williams
70c9975ae9 remove leftover local test 2019-11-05 14:21:37 -08:00
Bill Williams
11a2b6f123 restore test_interface_down_retry 2019-11-04 15:29:43 -08:00
Bill Williams
81d8f59bbd fix so that parodus can be killed if it connection fail loop 2019-11-01 14:14:18 -07:00
Bill Williams
846b0588c2 pu cloud status back 2019-11-01 11:40:35 -07:00
Bill Williams
ad44ff0221 remove 403 upgrade from this build 2019-11-01 10:00:39 -07:00
Bill Williams
513647ceef remove unnecessary nopoll_con_ref_count 2019-10-31 15:26:51 -07:00
Bill Williams
2ec3443b1d update parodus shutdown 2019-10-29 11:34:29 -07:00
shilpa24balaji
55e10aa051 Merge pull request #325 from shilpa24balaji/3.12_p3b
Update retry time in connection-health-file
2019-10-25 11:56:33 -07:00
Shilpa Seshadri
879a585b66 Update retry time in connection-health-file 2019-10-24 18:20:20 -07:00
shilpa24balaji
ea3534678b Merge pull request #321 from xmidt-org/unref_crash
nopoll_conn_unref crash fix
2019-09-18 16:49:19 -07:00
Shilpa Seshadri
6ebb62ead4 Removing the additional conn_unref as conn_close handles this 2019-09-18 11:18:26 -07:00
Shilpa Seshadri
5ec16a7370 Re-order the cloud status update to prevent the nopoll_conn_unref crash 2019-09-16 16:26:56 -07:00
shilpa24balaji
7b81cb4efd Update README.md 2019-09-12 17:12:48 -07:00
shilpa24balaji
4c6a6a99e6 Merge pull request #320 from xmidt-org/event_handler
Ping Status change event handler
2019-09-12 16:42:01 -07:00
shilpa24balaji
106e1bfeb3 Merge pull request #318 from bill1600/waitconrdy
initialize wait_status in wait_connection_ready
2019-09-10 10:28:27 -07:00
Shilpa Seshadri
4f01170670 Handler definition for Ping Status change event 2019-09-09 16:51:39 -07:00
shilpa24balaji
f37d1911d6 Merge pull request #319 from xmidt-org/master
Sync from master branch
2019-09-09 13:13:29 -07:00
Bill Williams
3a436999fc initialize wait_status in wait_connection_ready 2019-09-06 11:56:56 -07:00
shilpa24balaji
016c80960c Merge pull request #316 from guruchandru/parodus_event
Parodus cloud Status update and Unit tests
2019-08-22 16:34:48 -07:00
Guru Chandru
b286857a22 Parodus cloud Status update and Unit tests 2019-08-22 11:50:56 +05:30
Shilpa Seshadri
f998106aed Log reconnect reason and update change log 2019-08-19 21:46:45 -07:00
shilpa24balaji
2d209b2a0d Merge pull request #315 from xmidt-org/event_handler
Pause connection retry when interface is down
2019-08-19 16:41:41 -07:00
Shilpa Seshadri
3f471100db Pause retry when interface is down and until its up 2019-08-17 03:43:50 -07:00
shilpa24balaji
ddc04f9da0 Merge pull request #313 from guruchandru/parodus_checkin
Parodus cloud-status shows "online" when connection is closed during …
2019-08-15 15:34:09 -07:00
Guru Chandru
a23615f3a5 Parodus cloud-status shows "online" when connection is closed during interface-down 2019-08-14 18:39:01 +05:30
shilpa24balaji
b1caff4a1a Merge pull request #312 from guruchandru/parodus_handler
parodus event handler to listen to interface_down and interface_up event
2019-08-09 12:41:59 -07:00
Sadhyama Vengilat
11c9052d77 parodus event handler to listen to interface_down and interface_up event 2019-08-07 12:19:38 +05:30
guruchandru
5ceb57a8c3 Merge pull request #1 from bill1600/sysevent
add pause/resume heartBeatTimer
2019-08-06 10:48:59 +05:30
guruchandru
c4ebe239ac Merge branch 'parodus_handler' into sysevent 2019-08-06 10:39:45 +05:30
shilpa24balaji
1622c44c89 Merge pull request #307 from gbuddappagari/parodus_onboard
RDKB-20643:Add OnBoarding logs
2019-07-24 20:15:06 -07:00
shilpa24balaji
fb542586e7 Update CMakeLists.txt 2019-07-24 20:13:40 -07:00
Gayathri Buddappagari
0afb87c29b RDKB-20643:Add OnBoarding logs 2019-07-15 17:02:01 +05:30
shilpa24balaji
f168e4d148 Merge pull request #308 from bill1600/nopoll_102
Use nopoll version 1.0.2
2019-07-02 14:52:36 -07:00
Bill Williams
97570a24d5 Use nopoll version 1.0.2 2019-07-02 13:24:20 -07:00
shilpa24balaji
95b6f75284 Merge pull request #306 from bill1600/newauthtoken
request new auth token on every retry, not just after 403
2019-06-12 11:38:10 -07:00
Bill Williams
f87e69c07b no need for backoff after 403 2019-06-11 14:20:45 -07:00
Bill Williams
647905639c refine connect/auth-token logic 2019-06-05 08:56:28 -07:00
Bill Williams
ceadc4b51f refine fetch auth token 2019-06-03 16:55:29 -07:00
Bill Williams
38dee179e7 request new auth token on every retry, not just after 403 2019-05-30 13:44:49 -07:00
shilpa24balaji
9feafedff8 Merge pull request #302 from bill1600/clrtoken
requestNewAuthToken will clear token if it fails
2019-05-21 17:49:33 -07:00
Bill Williams
2807f8e43a add test_auth_token_more.c 2019-05-16 13:48:02 -07:00
Bill Williams
5132675700 add unit tests for auth_token 2019-05-16 13:41:19 -07:00
Bill Williams
e166b9fdf5 use memset to clear auth token in requestNewAuthToken 2019-05-14 13:34:35 -07:00
Bill Williams
60789f0ec8 requestNewAuthToken will clear token if it fails 2019-05-14 11:51:40 -07:00
Bill Williams
3fb0708b15 add pause/resume heartBeatTimer 2019-05-07 16:19:37 -07:00
shilpa24balaji
65098e36cb Merge pull request #298 from bill1600/nano_115
Update to use nanomsg v 1.1.4
2019-04-24 10:30:41 -07:00
shilpa24balaji
c585300f76 Merge pull request #297 from bill1600/test_upstream
Add unit test for re-registrations
2019-04-24 10:27:48 -07:00
Bill Williams
e4e78118cf Use nanomsg version 1.1.4 2019-04-23 17:12:48 -07:00
Bill Williams
8b4541b570 Update to use nanomsg v 1.1.5 2019-04-23 13:29:35 -07:00
Bill Williams
acc542647b Add unit test for re-registrations 2019-04-12 09:09:23 -07:00
shilpa24balaji
da6614b19d Merge pull request #294 from bill1600/cnheal
Add logic to save parodus connection status in health file
2019-04-04 11:28:23 -07:00
Bill Williams
096271279d new self heal version woth merged close/endpoint 2019-04-01 09:22:40 -07:00
shilpa24balaji
50176fb120 Merge pull request #292 from bill1600/close_endpt
Fix nanomsg client close handling
2019-03-29 14:31:57 -07:00
Bill Williams
2ad896abc6 log all nn_close 2019-03-27 11:35:16 -07:00
Bill Williams
f58f85bc32 close client when deleting from client list 2019-03-26 16:54:52 -07:00
Bill Williams
4fef26c082 use endpoint in nn_shutdown and log nn_close errors 2019-03-26 16:26:09 -07:00
shilpa24balaji
1995a664ad Merge pull request #291 from sadhyama/master
Rename command line options for MTLS cert and Key #290
2019-03-22 10:39:44 -07:00
Weston Schmidt
f1b2add244 Merge branch 'nosinovacao-feature_mutual_auth_v1' 2019-03-20 09:08:47 -07:00
Weston Schmidt
13739786a0 Resolve the merge conflicts in PR 246. Remove the ifdef flag as this should always be available. Fix a mistake in the commandline option parsing of the C flag ... needs to be C:. 2019-03-20 09:05:20 -07:00
Sadhyama Vengilat
4fc082cb43 Updated CHANGELOG.md 2019-03-19 17:29:26 +05:30
Sadhyama Vengilat
08feef216e Rename command line options for MTLS cert and Key #290 2019-03-19 17:19:00 +05:30
Nuno Martins
3bb48b48c0 Added Security Feature: Mutual Authentication (mTLS or two way TLS)
This change adds support for two new program parameters
-q "client_cert_path" and -k "client key path"
Where here client is the CPE, so It will be the CPE cert and
corresponding key.

Having those two parameters we are in position to pass them
on the nopoll_conn_opts_set_ssl_certs function. This function,
previously, was being set with NULL values.

As most parameters have a path with 64 characters, we also created
those (cert and key) paths with that length.

We also changed the README.md accordingly, to show how to enable
and use this feature.

Signed-off-by: Nuno Martins <nuno.mmartins@parceiros.nos.pt>
2018-10-08 16:16:08 +01:00
36 changed files with 1322 additions and 207 deletions

View File

@@ -6,6 +6,24 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [Unreleased]
- Security: Added support to use auth token during initial connect to cloud
- Fix re-registration fails that lose a socket
- Fix mutex error in service alive
- Security: Mutual Authentication (mTLS or two way TLS)
- Rename command line options for MTLS cert and Key
- Update to use nanomsg v. 1.1.4
- requestNewAuthToken will clear the token if it fails.
- request auth token on every retry, not just after 403
- update to use nopoll v 1.0.2
- Add pause/resume heartBeatTimer
- parodus event handler to listen to interface_down and interface_up event
- Pause connection retry during interface_down event
- Add callback handler for ping status change event
- Fixed nopoll_conn_unref crash
- Update retry timestamp in connection-health-file
- fix so that parodus can be killed, even if in a connection fail loop
- provide signal handlers so we shut down properly when INCLUDE_BREAKPAD active
- send status code and reason in websocket close message
- dont try to install handler for signal 9
## [1.0.2] - 2019-02-08
- Refactored connection.c and updated corresponding unit tests

View File

@@ -85,7 +85,7 @@ add_dependencies(libtrower-base64 trower-base64)
ExternalProject_Add(nopoll
PREFIX ${PREFIX_DIR}/nopoll
GIT_REPOSITORY https://github.com/Comcast/nopoll.git
GIT_TAG "1.0.1"
GIT_TAG "1.0.2"
CONFIGURE_COMMAND COMMAND <SOURCE_DIR>/autogen.sh --prefix=${PREFIX}
--includedir=${INCLUDE_DIR}
--libdir=${LIBRARY_DIR}
@@ -101,7 +101,7 @@ add_dependencies(libnopoll nopoll)
ExternalProject_Add(nanomsg
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/nanomsg
GIT_REPOSITORY https://github.com/nanomsg/nanomsg.git
GIT_TAG "1.1.2"
GIT_TAG "1.1.4"
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR}
)
add_library(libnanomsg STATIC SHARED IMPORTED)
@@ -152,7 +152,7 @@ add_dependencies(libcurl curl)
ExternalProject_Add(cimplog
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/cimplog
GIT_REPOSITORY https://github.com/Comcast/cimplog.git
GIT_TAG "1.0.1"
GIT_TAG "1.0.2"
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} -DBUILD_TESTING=OFF
)
add_library(libcimplog STATIC SHARED IMPORTED)

View File

@@ -1,6 +1,6 @@
# parodus
[![Build Status](https://travis-ci.org/Comcast/parodus.svg?branch=master)](https://travis-ci.org/Comcast/parodus)
[![Build Status](https://travis-ci.org/xmidt-org/parodus.svg?branch=master)](https://travis-ci.org/xmidt-org/parodus)
[![codecov.io](http://codecov.io/github/Comcast/parodus/coverage.svg?branch=master)](http://codecov.io/github/Comcast/parodus?branch=master)
[![Coverity](https://img.shields.io/coverity/scan/11192.svg)](https://scan.coverity.com/projects/comcast-parodus)
[![Apache V2 License](http://img.shields.io/badge/license-Apache%20V2-blue.svg)](https://github.com/Comcast/parodus/blob/master/LICENSE)
@@ -75,6 +75,12 @@ make test
- /jwt-public-key-file -JWT token validation key
# if ENABLE_MUTUAL_AUTH is enabled
- /mtls-client-cert-path - Provide the client cert for establishing a mutual auth secure websocket connection
- /mtls-client-key-path - Provide the client cert key for establishing a mutual auth secure websocket connection
```
# Sample parodus start commands:

View File

@@ -25,6 +25,11 @@
#include "config.h"
#include "connection.h"
bool interface_down_event = false;
pthread_mutex_t interface_down_mut=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t interface_down_con=PTHREAD_COND_INITIALIZER;
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
@@ -139,3 +144,47 @@ void timespec_diff(struct timespec *start, struct timespec *stop,
return;
}
/*------------------------------------------------------------------------------*/
/* For interface_down_event Flag */
/*------------------------------------------------------------------------------*/
// Get value of interface_down_event
bool get_interface_down_event()
{
bool tmp = false;
pthread_mutex_lock (&interface_down_mut);
tmp = interface_down_event;
pthread_mutex_unlock (&interface_down_mut);
return tmp;
}
// Reset value of interface_down_event to false
void reset_interface_down_event()
{
pthread_mutex_lock (&interface_down_mut);
interface_down_event = false;
pthread_cond_signal(&interface_down_con);
pthread_mutex_unlock (&interface_down_mut);
}
// set value of interface_down_event to true
void set_interface_down_event()
{
pthread_mutex_lock (&interface_down_mut);
interface_down_event = true;
pthread_mutex_unlock (&interface_down_mut);
}
pthread_cond_t *get_interface_down_con(void)
{
return &interface_down_con;
}
pthread_mutex_t *get_interface_down_mut(void)
{
return &interface_down_mut;
}

View File

@@ -49,6 +49,7 @@
/*----------------------------------------------------------------------------*/
/* Macros */
/*----------------------------------------------------------------------------*/
#define UNUSED(x) (void )(x)
#define NANO_SOCKET_SEND_TIMEOUT_MS 2000
#define NANO_SOCKET_RCV_TIMEOUT_MS 500
@@ -107,6 +108,7 @@ typedef struct {
//--- Used in connection.c for backoff delay timer
typedef struct {
struct timespec ts;
int count;
int max_count;
int delay;
@@ -157,6 +159,25 @@ void addCRUDmsgToQueue(wrp_msg_t *crudMsg);
void timespec_diff(struct timespec *start, struct timespec *stop,
struct timespec *result);
/*------------------------------------------------------------------------------*/
/* For interface_down_event Flag */
/*------------------------------------------------------------------------------*/
// Get value of interface_down_event
bool get_interface_down_event();
// Reset value of interface_down_event to false
void reset_interface_down_event();
// Set value of interface_down_event to true
void set_interface_down_event();
pthread_cond_t *get_interface_down_con();
pthread_mutex_t *get_interface_down_mut();
#ifdef __cplusplus
}
#endif

View File

@@ -66,17 +66,11 @@ int requestNewAuthToken(char *newToken, size_t len, int r_count)
struct token_data data;
data.size = 0;
data.data = newToken;
curl = curl_easy_init();
if(curl)
{
//this memory will be dynamically grown by write call back fn as required
data.data = (char *) malloc(sizeof(char) * 1);
if(NULL == data.data)
{
ParodusError("Failed to allocate memory.\n");
return -1;
}
data.data[0] = '\0';
createCurlheader(mac_header, serial_header, uuid_header, transaction_uuid, list, &headers_list);
@@ -137,11 +131,8 @@ int requestNewAuthToken(char *newToken, size_t len, int r_count)
{
ParodusError("curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
curl_easy_cleanup(curl);
if(data.data)
{
free(data.data);
data.data = NULL;
}
data.size = 0;
memset (data.data, 0, len);
return -1;
}
else
@@ -149,19 +140,15 @@ int requestNewAuthToken(char *newToken, size_t len, int r_count)
if(response_code == 200)
{
ParodusInfo("cURL success\n");
strncpy(newToken, data.data, len);
}
}
if(data.data)
{
free(data.data);
data.data = NULL;
}
curl_easy_cleanup(curl);
}
else
{
ParodusError("curl init failure\n");
data.size = 0;
memset (data.data, 0, len);
return -1;
}
@@ -179,6 +166,7 @@ void getAuthToken(ParodusCfg *cfg)
int status = -1;
int retry_count = 0;
memset (cfg->webpa_auth_token, 0, sizeof(cfg->webpa_auth_token));
if( cfg->hw_mac != NULL && strlen(cfg->hw_mac) !=0 )
{
if( cfg->client_cert_path !=NULL && strlen(cfg->client_cert_path) !=0 )
@@ -225,28 +213,23 @@ void getAuthToken(ParodusCfg *cfg)
*/
size_t write_callback_fn(void *buffer, size_t size, size_t nmemb, struct token_data *data)
{
ParodusCfg *cfg;
size_t max_data_size = sizeof (cfg->webpa_auth_token);
size_t index = data->size;
size_t n = (size * nmemb);
char* tmp;
data->size += (size * nmemb);
data->size += n;
tmp = realloc(data->data, data->size + 1); /* +1 for '\0' */
if(tmp) {
data->data = tmp;
} else {
if(data->data) {
free(data->data);
}
ParodusError("Failed to allocate memory for data\n");
if (data->size >= max_data_size) {
ParodusError("Auth token data overruns buffer\n");
data->size = 0;
return 0;
}
memcpy((data->data + index), buffer, n);
data->data[data->size] = '\0';
return size * nmemb;
return n;
}
/* @brief function to generate random uuid.

View File

@@ -76,7 +76,11 @@ int addToList( wrp_msg_t **msg)
if(rc < 0)
{
ParodusError ("Unable to connect socket (errno=%d, %s)\n",errno, strerror(errno));
nn_close (sock);
if (nn_close (sock) < 0)
{
ParodusError ("nn_close socket=%d (err=%d, %s)\n",
sock, errno, strerror(errno));
}
}
else
@@ -87,6 +91,7 @@ int addToList( wrp_msg_t **msg)
{
memset( new_node, 0, sizeof( reg_list_item_t ) );
new_node->sock = sock;
new_node->endpoint = rc;
ParodusPrint("new_node->sock is %d\n", new_node->sock);
@@ -219,6 +224,16 @@ int deleteFromList(char* service_name)
}
ParodusPrint("Deleting the node\n");
if(nn_shutdown(curr_node->sock, curr_node->endpoint) < 0)
{
ParodusError ("nn_shutdown socket=%d endpt=%d, err=%d\n",
curr_node->sock, curr_node->endpoint, errno);
}
if (nn_close (curr_node->sock) < 0)
{
ParodusError ("nn_close socket=%d err=%d\n",
curr_node->sock, errno);
}
free( curr_node );
curr_node = NULL;
ParodusInfo("Deleted successfully and returning..\n");

View File

@@ -30,6 +30,7 @@
typedef struct reg_list_item
{
int sock;
int endpoint;
char service_name[32];
char url[100];
struct reg_list_item *next;

View File

@@ -365,6 +365,9 @@ int parseCommandLine(int argc,char **argv,ParodusCfg * cfg)
{"client-cert-path", required_argument, 0, 'P'},
{"token-server-url", required_argument, 0, 'U'},
{"crud-config-file", required_argument, 0, 'C'},
{"connection-health-file", required_argument, 0, 'S'},
{"mtls-client-key-path", required_argument, 0, 'K'},
{"mtls-client-cert-path", required_argument, 0,'M'},
{0, 0, 0, 0}
};
int c;
@@ -380,6 +383,7 @@ 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->connection_health_file = NULL;
cfg->client_cert_path = NULL;
cfg->token_server_url = NULL;
cfg->cloud_status = NULL;
@@ -390,7 +394,7 @@ int parseCommandLine(int argc,char **argv,ParodusCfg * cfg)
/* 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:w: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:S:K:M",
long_options, &option_index);
/* Detect the end of the options. */
@@ -431,6 +435,7 @@ int parseCommandLine(int argc,char **argv,ParodusCfg * cfg)
case 'r':
parStrncpy(cfg->hw_last_reboot_reason, optarg,sizeof(cfg->hw_last_reboot_reason));
ParodusInfo("hw_last_reboot_reason is %s\n",cfg->hw_last_reboot_reason);
OnboardLog("Last reboot reason is %s\n",cfg->hw_last_reboot_reason);
break;
case 'n':
@@ -528,10 +533,15 @@ int parseCommandLine(int argc,char **argv,ParodusCfg * cfg)
ParodusInfo("boot_retry_wait is %d\n",cfg->boot_retry_wait);
break;
case 'C':
cfg->crud_config_file = strdup(optarg);
ParodusInfo("crud_config_file is %s\n", cfg->crud_config_file);
break;
case 'S':
cfg->connection_health_file = strdup(optarg);
ParodusInfo("connection_health_file is %s\n", cfg->connection_health_file);
break;
case 'C':
cfg->crud_config_file = strdup(optarg);
ParodusInfo("crud_config_file is %s\n", cfg->crud_config_file);
break;
case 'P':
cfg->client_cert_path = strdup(optarg);
@@ -543,6 +553,16 @@ int parseCommandLine(int argc,char **argv,ParodusCfg * cfg)
ParodusInfo("token_server_url is %s\n", cfg->token_server_url);
break;
case 'K':
cfg->mtls_client_key_path = strdup(optarg);
ParodusInfo("mtls_client_key_path is %s\n", cfg->mtls_client_key_path);
break;
case 'M':
cfg->mtls_client_cert_path = strdup(optarg);
ParodusInfo("mtls_client_cert_path is %s\n", cfg->mtls_client_cert_path);
break;
case '?':
/* getopt_long already printed an error message. */
break;
@@ -616,6 +636,7 @@ void setDefaultValuesToCfg(ParodusCfg *cfg)
parStrncpy(cfg->webpa_uuid, "1234567-345456546",sizeof(cfg->webpa_uuid));
ParodusPrint("cfg->webpa_uuid is :%s\n", cfg->webpa_uuid);
cfg->crud_config_file = NULL;
cfg->connection_health_file = NULL;
cfg->client_cert_path = NULL;
cfg->token_server_url = NULL;
@@ -767,6 +788,15 @@ void loadParodusCfg(ParodusCfg * config,ParodusCfg *cfg)
parStrncpy(cfg->webpa_uuid, "1234567-345456546",sizeof(cfg->webpa_uuid));
ParodusPrint("cfg->webpa_uuid is :%s\n", cfg->webpa_uuid);
if(config->connection_health_file != NULL)
{
cfg->connection_health_file = strdup(config->connection_health_file);
}
else
{
ParodusPrint("connection_health_file is NULL. set to empty\n");
}
if(config->crud_config_file != NULL)
{
cfg->crud_config_file = strdup(config->crud_config_file);

View File

@@ -101,6 +101,9 @@ typedef struct
char token_read_script[64];
char *client_cert_path;
char *token_server_url;
char *connection_health_file;
char *mtls_client_key_path;
char *mtls_client_cert_path;
char *crud_config_file;
char *cloud_status;
char *cloud_disconnect;

View File

@@ -74,6 +74,7 @@ void createSocketConnection(void (* initKeypress)())
//ParodusCfg *tmpCfg = (ParodusCfg*)config_in;
noPollCtx *ctx;
bool seshat_registered = false;
int create_conn_rtn = 0;
unsigned int webpa_ping_timeout_ms = 1000 * get_parodus_cfg()->webpa_ping_timeout;
unsigned int heartBeatTimer = 0;
struct timespec start_svc_alive_timer;
@@ -94,9 +95,13 @@ void createSocketConnection(void (* initKeypress)())
nopoll_log_set_handler (ctx, __report_log, NULL);
#endif
if(!createNopollConnection(ctx))
start_conn_in_progress ();
create_conn_rtn = createNopollConnection(ctx);
stop_conn_in_progress ();
if(!create_conn_rtn)
{
ParodusError("Unrecovered error, terminating the process\n");
OnboardLog("Unrecovered error, terminating the process\n");
abort();
}
packMetaData();
@@ -140,8 +145,14 @@ void createSocketConnection(void (* initKeypress)())
{
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");
OnboardLog("Reconnect detected, setting Ping_Miss reason for Reconnect\n");
set_global_reconnect_reason("Ping_Miss");
set_global_reconnect_status(true);
// Invoke the ping status change event callback as "missed" ping
if(NULL != on_ping_status_change)
{
on_ping_status_change("missed");
}
set_close_retry();
}
else
@@ -157,6 +168,10 @@ void createSocketConnection(void (* initKeypress)())
if( false == seshat_registered ) {
seshat_registered = __registerWithSeshat();
}
if (get_interface_down_event ())
if (0 != wait_while_interface_down ())
break;
if(get_close_retry())
{
@@ -164,8 +179,6 @@ void createSocketConnection(void (* initKeypress)())
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);
@@ -177,7 +190,9 @@ void createSocketConnection(void (* initKeypress)())
free(get_parodus_cfg()->cloud_disconnect);
reset_cloud_disconnect_reason(get_parodus_cfg());
}
start_conn_in_progress ();
createNopollConnection(ctx);
stop_conn_in_progress ();
}
} while(!get_close_retry() && !g_shutdown);
@@ -203,13 +218,18 @@ void createSocketConnection(void (* initKeypress)())
deleteAllClients ();
ParodusInfo ("reconnect reason at close %s\n", get_global_reconnect_reason());
ParodusInfo ("shutdown reason at close %s\n", get_global_shutdown_reason());
close_and_unref_connection(get_global_conn());
nopoll_ctx_unref(ctx);
nopoll_cleanup_library();
curl_global_cleanup();
}
void shutdownSocketConnection(void) {
void shutdownSocketConnection(char *reason) {
set_global_shutdown_reason (reason);
g_shutdown = true;
reset_interface_down_event ();
terminate_backoff_delay ();
}

View File

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

View File

@@ -38,11 +38,34 @@
#define HTTP_CUSTOM_HEADER_COUNT 5
#define INITIAL_CJWT_RETRY -2
#define UPDATE_HEALTH_FILE_INTERVAL_SECS 450
/* Close codes defined in RFC 6455, section 11.7. */
enum {
CloseNormalClosure = 1000,
CloseGoingAway = 1001,
CloseProtocolError = 1002,
CloseUnsupportedData = 1003,
CloseNoStatus = 1005,
CloseAbnormalClosure = 1006,
CloseInvalidFramePayloadData = 1007,
ClosePolicyViolation = 1008,
CloseMessageTooBig = 1009,
CloseMandatoryExtension = 1010,
CloseInternalServerErr = 1011,
CloseServiceRestart = 1012,
CloseTryAgainLater = 1013,
CloseTLSHandshake = 1015
};
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
pthread_mutex_t backoff_delay_mut=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t backoff_delay_con=PTHREAD_COND_INITIALIZER;
static char *shutdown_reason = SHUTDOWN_REASON_PARODUS_STOP; /* goes in the close message */
static char *reconnect_reason = "webpa_process_starts";
static int cloud_disconnect_max_time = 5;
static noPollConn *g_conn = NULL;
@@ -65,6 +88,16 @@ void set_global_conn(noPollConn *conn)
g_conn = conn;
}
char *get_global_shutdown_reason()
{
return shutdown_reason;
}
void set_global_shutdown_reason(char *reason)
{
shutdown_reason = reason;
}
char *get_global_reconnect_reason()
{
return reconnect_reason;
@@ -199,6 +232,14 @@ void init_backoff_timer (backoff_timer_t *timer, int max_count)
timer->count = 1;
timer->max_count = max_count;
timer->delay = 1;
clock_gettime (CLOCK_REALTIME, &timer->ts);
}
void terminate_backoff_delay (void)
{
pthread_mutex_lock (&backoff_delay_mut);
pthread_cond_signal(&backoff_delay_con);
pthread_mutex_unlock (&backoff_delay_mut);
}
int update_backoff_delay (backoff_timer_t *timer)
@@ -211,11 +252,50 @@ int update_backoff_delay (backoff_timer_t *timer)
return timer->delay;
}
static void backoff_delay (backoff_timer_t *timer)
#define BACKOFF_ERR -1
#define BACKOFF_SHUTDOWN 1
#define BACKOFF_DELAY_TAKEN 0
void start_conn_in_progress (void);
/* backoff_delay
*
* delays for the number of seconds specified in parameter timer
* g_shutdown can break out of the delay.
*
* returns -1 pthread_cond_timedwait error
* 1 shutdown
* 0 delay taken
*/
static int backoff_delay (backoff_timer_t *timer)
{
struct timespec ts;
int rtn;
// periodically update the health file.
clock_gettime (CLOCK_REALTIME, &ts);
if ((ts.tv_sec - timer->ts.tv_sec) >= UPDATE_HEALTH_FILE_INTERVAL_SECS) {
start_conn_in_progress ();
timer->ts.tv_sec += UPDATE_HEALTH_FILE_INTERVAL_SECS;
}
update_backoff_delay (timer);
ParodusInfo("Waiting with backoffRetryTime %d seconds\n", timer->delay);
sleep (timer->delay);
ts.tv_sec += timer->delay;
pthread_mutex_lock (&backoff_delay_mut);
// The condition variable will only be set if we shut down.
rtn = pthread_cond_timedwait (&backoff_delay_con, &backoff_delay_mut, &ts);
pthread_mutex_unlock (&backoff_delay_mut);
if (g_shutdown)
return BACKOFF_SHUTDOWN;
if ((rtn != 0) && (rtn != ETIMEDOUT)) {
ParodusError ("pthread_cond_timedwait error (%d) in backoff_delay.\n", rtn);
return BACKOFF_ERR;
}
return BACKOFF_DELAY_TAKEN;
}
//--------------------------------------------------------------------
@@ -296,21 +376,25 @@ 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 && (get_parodus_cfg()->client_cert_path !=NULL && strlen(get_parodus_cfg()->client_cert_path) >0))
{
getAuthToken(get_parodus_cfg());
}
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 set_extra_headers (create_connection_ctx_t *ctx)
{
ParodusCfg * cfg = get_parodus_cfg();
free_extra_headers (ctx);
if ((strlen(cfg->webpa_auth_token) == 0) &&
(cfg->client_cert_path != NULL) && (strlen(cfg->client_cert_path) > 0))
{
getAuthToken(cfg);
}
ctx->extra_headers = build_extra_hdrs (&ctx->header_info);
}
void free_connection_ctx (create_connection_ctx_t *ctx)
{
free_extra_headers (ctx);
@@ -387,8 +471,10 @@ int nopoll_connect (create_connection_ctx_t *ctx, int is_ipv6)
}
if ((NULL == connection) && (!is_ipv6)) {
if((checkHostIp(server->server_addr) == -2)) {
if (check_timer_expired (&ctx->connect_timer, 15*60*1000)) {
if (check_timer_expired (&ctx->connect_timer, 15*60*1000) && !get_interface_down_event()) {
ParodusError("WebPA unable to connect due to DNS resolving to 10.0.0.1 for over 15 minutes; crashing service.\n");
OnboardLog("WebPA unable to connect due to DNS resolving to 10.0.0.1 for over 15 minutes; crashing service.\n");
OnboardLog("Reconnect detected, setting Dns_Res_webpa_reconnect reason for Reconnect\n");
set_global_reconnect_reason("Dns_Res_webpa_reconnect");
set_global_reconnect_status(true);
@@ -404,14 +490,14 @@ int nopoll_connect (create_connection_ctx_t *ctx, int is_ipv6)
//--------------------------------------------------------------------
// 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_ACTION_RETRY 1 // if wait_status is 307, 302, 303, or 403
#define WAIT_FAIL 2
#define FREE_NON_NULL_PTR(ptr) if (NULL != ptr) free(ptr)
int wait_connection_ready (create_connection_ctx_t *ctx)
{
int wait_status;
int wait_status = 0;
char *redirectURL = NULL;
if(nopoll_conn_wait_for_status_until_connection_ready(get_global_conn(), 10,
@@ -423,7 +509,7 @@ int wait_connection_ready (create_connection_ctx_t *ctx)
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);
ParodusInfo("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;
@@ -440,10 +526,12 @@ int wait_connection_ready (create_connection_ctx_t *ctx)
FREE_NON_NULL_PTR (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;
ParodusCfg *cfg = get_parodus_cfg();
/* clear auth token in cfg so that we will refetch auth token */
memset (cfg->webpa_auth_token, 0, sizeof(cfg->webpa_auth_token));
ParodusError("Received Unauthorized response with status: %d\n", wait_status);
OnboardLog("Received Unauthorized response with status: %d\n", wait_status);
return WAIT_ACTION_RETRY;
}
ParodusError("Client connection timeout\n");
ParodusError("RDK-10037 - WebPA Connection Lost\n");
@@ -453,9 +541,9 @@ int wait_connection_ready (create_connection_ctx_t *ctx)
//--------------------------------------------------------------------
// Return codes for connect_and_wait
#define CONN_WAIT_SUCCESS 0
#define CONN_WAIT_ACTION_RETRY 1 // if wait_status is 307, 302, 303 or 403
#define CONN_WAIT_RETRY_DNS 2
#define CONN_WAIT_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)
{
@@ -512,20 +600,60 @@ int keep_trying_to_connect (create_connection_ctx_t *ctx,
{
int rtn;
while (true)
while (!g_shutdown)
{
set_extra_headers (ctx);
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 interface down event is set, stop retry
// and wait till interface is up again.
if(get_interface_down_event()) {
if (0 != wait_while_interface_down())
return false;
start_conn_in_progress();
ParodusInfo("Interface is back up, re-initializing the convey header\n");
// Reset the reconnect reason by initializing the convey header again
((header_info_t *)(&ctx->header_info))->conveyHeader = getWebpaConveyHeader();
ParodusInfo("Received reconnect_reason as:%s\n", reconnect_reason);
} else {
if (backoff_delay (backoff_timer) // 3,7,15,31 ..
!= BACKOFF_DELAY_TAKEN) // shutdown or cond wait error
return false;
}
if (rtn == CONN_WAIT_RETRY_DNS)
return false; //find_server again
// else retry
}
return false;
}
int wait_while_interface_down()
{
int rtn;
ParodusError("Interface is down, hence waiting until its up\n");
close_and_unref_connection (get_global_conn());
set_global_conn(NULL);
while (get_interface_down_event ()) {
pthread_mutex_lock(get_interface_down_mut());
rtn = pthread_cond_wait(get_interface_down_con(), get_interface_down_mut());
pthread_mutex_unlock (get_interface_down_mut());
if (rtn != 0)
ParodusError
("Error on pthread_cond_wait (%d) in wait_while_interface_down\n", rtn);
if ((rtn != 0) || g_shutdown) {
return -1;
}
}
return 0;
}
//--------------------------------------------------------------------
@@ -552,11 +680,11 @@ int createNopollConnection(noPollCtx *ctx)
max_retry_count = (int) get_parodus_cfg()->webpa_backoff_max;
ParodusPrint("max_retry_count is %d\n", max_retry_count );
memset (&conn_ctx, 0, sizeof(create_connection_ctx_t));
conn_ctx.nopoll_ctx = ctx;
init_expire_timer (&conn_ctx.connect_timer);
init_header_info (&conn_ctx.header_info);
set_extra_headers (&conn_ctx, false);
set_server_list_null (&conn_ctx.server_list);
init_backoff_timer (&backoff_timer, max_retry_count);
@@ -574,15 +702,23 @@ int createNopollConnection(noPollCtx *ctx)
if(conn_ctx.current_server->allow_insecure <= 0)
{
ParodusInfo("Connected to server over SSL\n");
OnboardLog("Connected to server over SSL\n");
}
else
{
ParodusInfo("Connected to server\n");
OnboardLog("Connected to server\n");
}
get_parodus_cfg()->cloud_status = CLOUD_STATUS_ONLINE;
ParodusInfo("cloud_status set as %s after successful connection\n", get_parodus_cfg()->cloud_status);
// Invoke the ping status change event callback as "received" ping
if(NULL != on_ping_status_change)
{
on_ping_status_change("received");
}
if((get_parodus_cfg()->boot_time != 0) && init) {
getCurrentTime(connectTimePtr);
ParodusInfo("connect_time-diff-boot_time=%d\n", connectTimePtr->tv_sec - get_parodus_cfg()->boot_time);
@@ -628,13 +764,20 @@ static char* build_extra_headers( const char *auth, const char *device_id,
static noPollConnOpts * createConnOpts (char * extra_headers, bool secure)
{
noPollConnOpts * opts;
char * mtls_client_cert_path = NULL;
char * mtls_client_key_path = NULL;
opts = nopoll_conn_opts_new ();
if(secure)
{
if(strlen(get_parodus_cfg()->cert_path) > 0)
{
nopoll_conn_opts_set_ssl_certs(opts, NULL, NULL, NULL, get_parodus_cfg()->cert_path);
if( ( get_parodus_cfg()->mtls_client_cert_path !=NULL && strlen(get_parodus_cfg()->mtls_client_cert_path) > 0) && (get_parodus_cfg()->mtls_client_key_path !=NULL && strlen(get_parodus_cfg()->mtls_client_key_path) > 0) )
{
mtls_client_cert_path = get_parodus_cfg()->mtls_client_cert_path;
mtls_client_key_path = get_parodus_cfg()->mtls_client_key_path;
}
nopoll_conn_opts_set_ssl_certs(opts, mtls_client_cert_path, mtls_client_key_path, NULL, get_parodus_cfg()->cert_path);
}
nopoll_conn_opts_ssl_peer_verify (opts, nopoll_true);
nopoll_conn_opts_set_ssl_protocol (opts, NOPOLL_METHOD_TLSV1_2);
@@ -648,10 +791,57 @@ static noPollConnOpts * createConnOpts (char * extra_headers, bool secure)
void close_and_unref_connection(noPollConn *conn)
{
if (conn) {
nopoll_conn_close(conn);
if (0 < nopoll_conn_ref_count (conn)) {
nopoll_conn_unref(conn);
}
const char *reason = get_global_shutdown_reason();
int reason_len = 0;
int status = CloseNoStatus;
if (NULL != reason) {
reason_len = (int) strlen (reason);
status = CloseNormalClosure;
}
nopoll_conn_close_ext(conn, status, reason, reason_len);
get_parodus_cfg()->cloud_status = CLOUD_STATUS_OFFLINE;
ParodusInfo("cloud_status set as %s after connection close\n", get_parodus_cfg()->cloud_status);
}
}
void write_conn_in_prog_file (const char *msg)
{
int fd;
FILE *fp;
unsigned long timestamp;
ParodusCfg *cfg = get_parodus_cfg();
if (NULL == cfg->connection_health_file)
return;
fd = open (cfg->connection_health_file, O_CREAT | O_WRONLY | O_SYNC, 0666);
if (fd < 0) {
ParodusError ("Error(1) %d opening file %s\n", errno, cfg->connection_health_file);
return;
}
ftruncate (fd, 0);
fp = fdopen (fd, "w");
if (fp == NULL) {
ParodusError ("Error(2) %d opening file %s\n", errno, cfg->connection_health_file);
return;
}
timestamp = (unsigned long) time(NULL);
fprintf (fp, "{%s=%lu}\n", msg, timestamp);
fclose (fp);
}
void start_conn_in_progress (void)
{
write_conn_in_prog_file ("START");
}
void stop_conn_in_progress (void)
{
write_conn_in_prog_file ("STOP");
}
void registerParodusOnPingStatusChangeHandler(parodusOnPingStatusChangeHandler callback_func)
{
on_ping_status_change = callback_func;
}

View File

@@ -33,7 +33,17 @@ extern "C" {
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
#define SHUTDOWN_REASON_PARODUS_STOP "parodus_stopping"
#define SHUTDOWN_REASON_SYSTEM_RESTART "system_restarting"
/**
* parodusOnPingStatusChangeHandler - Function pointer
* Used to define callback function to do additional processing
* when websocket Ping status change event
* i.e. ping_miss or ping receive after miss
*/
typedef void (*parodusOnPingStatusChangeHandler) (char * status);
parodusOnPingStatusChangeHandler on_ping_status_change;
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
@@ -49,6 +59,9 @@ void close_and_unref_connection(noPollConn *);
noPollConn *get_global_conn(void);
void set_global_conn(noPollConn *);
char *get_global_shutdown_reason();
void set_global_shutdown_reason(char *reason);
char *get_global_reconnect_reason();
void set_global_reconnect_reason(char *reason);
@@ -57,6 +70,21 @@ void set_global_reconnect_status(bool status);
int get_cloud_disconnect_time();
void set_cloud_disconnect_time(int disconnTime);
/**
* @brief Interface to self heal connection in progress getting stuck
*/
void start_conn_in_progress (void);
void stop_conn_in_progress (void);
// To Register parodusOnPingStatusChangeHandler Callback function
void registerParodusOnPingStatusChangeHandler(parodusOnPingStatusChangeHandler on_ping_status_change);
// To stop connection and wait duing interface down state
int wait_while_interface_down (void);
void terminate_backoff_delay (void);
#ifdef __cplusplus
}
#endif

View File

@@ -1346,6 +1346,7 @@ static int ConnDisconnectFromCloud(char *disconn_reason)
if(!close_retry)
{
ParodusInfo("Reconnect detected, setting reason %s for Reconnect\n", disconn_reason);
OnboardLog("Reconnect detected, setting reason %s for Reconnect\n", disconn_reason);
set_global_reconnect_reason(disconn_reason);
set_global_reconnect_status(true);
set_close_retry();

View File

@@ -121,6 +121,9 @@ void listenerOnMessage(void * msg, size_t msgSize)
ParodusInfo("Received downstream dest as :%s and transaction_uuid :%s\n", dest,
((WRP_MSG_TYPE__REQ == msgType) ? message->u.req.transaction_uuid :
((WRP_MSG_TYPE__EVENT == msgType) ? "NA" : message->u.crud.transaction_uuid)));
OnboardLog("%s\n",
((WRP_MSG_TYPE__REQ == msgType) ? message->u.req.transaction_uuid :
((WRP_MSG_TYPE__EVENT == msgType) ? "NA" : message->u.crud.transaction_uuid)));
free(destVal);

View File

@@ -22,8 +22,10 @@
*/
#include "heartBeat.h"
#include <stdbool.h>
volatile unsigned int heartBeatTimer = 0;
volatile bool paused = false;
pthread_mutex_t heartBeat_mut=PTHREAD_MUTEX_INITIALIZER;
@@ -49,8 +51,27 @@ void reset_heartBeatTimer()
void increment_heartBeatTimer(unsigned int inc_time_ms)
{
pthread_mutex_lock (&heartBeat_mut);
heartBeatTimer += inc_time_ms;
if (!paused)
heartBeatTimer += inc_time_ms;
pthread_mutex_unlock (&heartBeat_mut);
}
// Pause heartBeatTimer, i.e. stop incrementing
void pause_heartBeatTimer()
{
pthread_mutex_lock (&heartBeat_mut);
heartBeatTimer = 0;
paused = true;
pthread_mutex_unlock (&heartBeat_mut);
}
// Resume heartBeatTimer, i.e. resume incrementing
void resume_heartBeatTimer()
{
pthread_mutex_lock (&heartBeat_mut);
paused = false;
pthread_mutex_unlock (&heartBeat_mut);
}

View File

@@ -39,6 +39,12 @@ void reset_heartBeatTimer();
// Increment value of heartBeatTimer to desired value
void increment_heartBeatTimer(unsigned int inc_time_ms);
// Pause heartBeatTimer, i.e. stop incrementing
void pause_heartBeatTimer();
// Resume heartBeatTimer, i.e. resume incrementing
void resume_heartBeatTimer();
#ifdef __cplusplus
}
#endif

View File

@@ -19,14 +19,14 @@
#include "stdlib.h"
#include "config.h"
#include "auth_token.h"
#include "connection.h"
#include "conn_interface.h"
#include "parodus_log.h"
#include <curl/curl.h>
#ifdef INCLUDE_BREAKPAD
#include "breakpad_wrapper.h"
#else
#include "signal.h"
#endif
#include "signal.h"
/*----------------------------------------------------------------------------*/
/* Macros */
@@ -36,7 +36,7 @@
/*----------------------------------------------------------------------------*/
/* Data Structures */
/*----------------------------------------------------------------------------*/
/* none */
typedef void Sigfunc(int);
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
@@ -46,30 +46,53 @@
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
#ifndef INCLUDE_BREAKPAD
static void sig_handler(int sig);
Sigfunc *
signal (int signo, Sigfunc *func)
{
struct sigaction act, oact;
act.sa_handler = func;
sigemptyset (&act.sa_mask);
act.sa_flags = 0;
if (signo == SIGALRM) {
#ifdef SA_INTERRUPT
act.sa_flags |= SA_INTERRUPT; /* SunOS 4.x */
#endif
} else {
#ifdef SA_RESTART
act.sa_flags |= SA_RESTART; /* SVR4, 4.4BSD */
#endif
}
if (sigaction (signo, &act, &oact) < 0) {
ParodusError ("Signal Handler for signal %d not installed!\n", signo);
return (SIG_ERR);
}
return (oact.sa_handler);
}
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
int main( int argc, char **argv)
{
#ifdef INCLUDE_BREAKPAD
breakpad_ExceptionHandler();
#else
set_global_shutdown_reason (SHUTDOWN_REASON_PARODUS_STOP);
signal(SIGTERM, sig_handler);
signal(SIGINT, sig_handler);
signal(SIGINT, sig_handler);
signal(SIGUSR1, sig_handler);
signal(SIGUSR2, sig_handler);
signal(SIGQUIT, sig_handler);
signal(SIGHUP, sig_handler);
signal(SIGALRM, sig_handler);
#ifdef INCLUDE_BREAKPAD
/* breakpad handles the signals SIGSEGV, SIGBUS, SIGFPE, and SIGILL */
breakpad_ExceptionHandler();
#else
signal(SIGSEGV, sig_handler);
signal(SIGBUS, sig_handler);
signal(SIGKILL, sig_handler);
signal(SIGFPE, sig_handler);
signal(SIGILL, sig_handler);
signal(SIGQUIT, sig_handler);
signal(SIGHUP, sig_handler);
signal(SIGALRM, sig_handler);
#endif
ParodusCfg *cfg;
@@ -83,7 +106,6 @@ int main( int argc, char **argv)
abort();
}
curl_global_init(CURL_GLOBAL_DEFAULT);
getAuthToken(cfg);
createSocketConnection( NULL);
@@ -98,7 +120,6 @@ const char *rdk_logger_module_fetch(void)
/*----------------------------------------------------------------------------*/
/* Internal functions */
/*----------------------------------------------------------------------------*/
#ifndef INCLUDE_BREAKPAD
static void sig_handler(int sig)
{
@@ -106,12 +127,13 @@ static void sig_handler(int sig)
{
signal(SIGINT, sig_handler); /* reset it to this function */
ParodusInfo("SIGINT received!\n");
shutdownSocketConnection();
shutdownSocketConnection(SHUTDOWN_REASON_PARODUS_STOP);
}
else if ( sig == SIGUSR1 )
{
signal(SIGUSR1, sig_handler); /* reset it to this function */
ParodusInfo("SIGUSR1 received!\n");
shutdownSocketConnection(SHUTDOWN_REASON_SYSTEM_RESTART);
}
else if ( sig == SIGUSR2 )
{
@@ -135,8 +157,7 @@ static void sig_handler(int sig)
else
{
ParodusInfo("Signal %d received!\n", sig);
shutdownSocketConnection();
shutdownSocketConnection(SHUTDOWN_REASON_PARODUS_STOP);
}
}
#endif

View File

@@ -70,6 +70,7 @@ int checkHostIp(char * serverIP)
if (retVal != 0)
{
ParodusError("getaddrinfo: %s\n", gai_strerror(retVal));
OnboardLog("getaddrinfo: %s\n", gai_strerror(retVal));
}
else
{

View File

@@ -167,16 +167,25 @@ void listenerOnCloseMessage (noPollCtx * ctx, noPollConn * conn, noPollPtr user_
if( closeStatus == 1006 && !get_global_reconnect_status())
{
ParodusInfo("Reconnect detected, setting default Reconnect reason %s\n",defaultReason);
OnboardLog("Reconnect detected, setting default Reconnect reason %s\n",defaultReason);
set_global_reconnect_reason(defaultReason);
set_global_reconnect_status(true);
}
else if(!get_global_reconnect_status())
{
ParodusInfo("Reconnect detected, setting Reconnect reason as Unknown\n");
OnboardLog("Reconnect detected, setting Reconnect reason as Unknown\n");
set_global_reconnect_reason("Unknown");
}
if(!get_interface_down_event())
{
ParodusInfo("Setting the close and retry connection\n");
set_close_retry();
}
else
ParodusInfo("Not Setting the close and retry connection as interface is down\n");
set_close_retry();
ParodusPrint("listenerOnCloseMessage(): mutex unlock in producer thread\n");
}

View File

@@ -73,25 +73,35 @@ void sendMessage(noPollConn *conn, void *msg, size_t len)
else
{
ParodusError("Failed to send msg upstream as connection is not OK\n");
if (connErr == 0)
{
getCurrentTime(connStuck_startPtr);
ParodusInfo("Conn got stuck, initialized the first timer\n");
connErr = 1;
}
else
{
getCurrentTime(connStuck_endPtr);
timeDiff = timeValDiff(connStuck_startPtr, connStuck_endPtr);
ParodusPrint("checking timeout difference:%ld\n", timeDiff);
OnboardLog("Failed to send msg upstream as connection is not OK\n");
if( timeDiff >= (10*60*1000))
if(get_interface_down_event())
{
ParodusError("Unable to connect to server since interface is down\n");
}
else
{
if (connErr == 0)
{
ParodusError("conn got stuck for over 10 minutes; crashing service.\n");
kill(getpid(),SIGTERM);
getCurrentTime(connStuck_startPtr);
ParodusInfo("Conn got stuck, initialized the first timer\n");
connErr = 1;
}
else
{
getCurrentTime(connStuck_endPtr);
timeDiff = timeValDiff(connStuck_startPtr, connStuck_endPtr);
ParodusPrint("checking timeout difference:%ld\n", timeDiff);
}
if( timeDiff >= (10*60*1000))
{
ParodusError("conn got stuck for over 10 minutes; crashing service.\n");
OnboardLog("conn got stuck for over 10 minutes; crashing service.\n");
kill(getpid(),SIGTERM);
}
}
}
}
}
@@ -136,7 +146,7 @@ void __report_log (noPollCtx * ctx, noPollDebugLevel level, const char * log_msg
if (level == NOPOLL_LEVEL_DEBUG)
{
//ParodusPrint("%s\n", log_msg);
ParodusInfo("%s\n", log_msg);
}
if (level == NOPOLL_LEVEL_INFO)
{
@@ -144,11 +154,12 @@ void __report_log (noPollCtx * ctx, noPollDebugLevel level, const char * log_msg
}
if (level == NOPOLL_LEVEL_WARNING)
{
ParodusPrint("%s\n", log_msg);
ParodusInfo("%s\n", log_msg);
}
if (level == NOPOLL_LEVEL_CRITICAL)
{
ParodusError("%s\n", log_msg );
OnboardLog("%s\n", log_msg );
}
return;
}

View File

@@ -33,3 +33,9 @@
#define ParodusError(...) cimplog_error(LOGGING_MODULE, __VA_ARGS__)
#define ParodusInfo(...) cimplog_info(LOGGING_MODULE, __VA_ARGS__)
#define ParodusPrint(...) cimplog_debug(LOGGING_MODULE, __VA_ARGS__)
#ifdef FEATURE_SUPPORT_ONBOARD_LOGGING
#define OnboardLog(...) onboarding_log(LOGGING_MODULE, __VA_ARGS__)
#else
#define OnboardLog(...)
#endif

View File

@@ -178,6 +178,7 @@ int validate_partner_id(wrp_msg_t *msg, partners_t **partnerIds)
if(matchFlag != 1)
{
ParodusError("Invalid partner_id %s\n",temp);
OnboardLog("Invalid partner_id %s\n",temp);
if(partnersList != NULL)
{
for(j=0; j<partnersList->count; j++)

View File

@@ -139,6 +139,7 @@ int analyze_jwt (const cjwt_t *jwt, char **url_buf, unsigned int *port)
show_times (exp_time, cur_time);
if (exp_time < cur_time) {
ParodusError ("JWT has expired\n");
OnboardLog ("JWT has expired\n");
return TOKEN_ERR_JWT_EXPIRED;
}
}
@@ -146,6 +147,7 @@ int analyze_jwt (const cjwt_t *jwt, char **url_buf, unsigned int *port)
url_buf, port);
if (http_match < 0) {
ParodusError ("Invalid endpoint claim in JWT\n");
OnboardLog("Invalid endpoint claim in JWT\n");
return TOKEN_ERR_BAD_ENDPOINT;
}
ParodusInfo ("JWT is_http strncmp: %d\n", http_match);

View File

@@ -190,6 +190,16 @@ void *handle_upstream()
ParodusError("failure in allocation for message\n");
}
}
if(nn_shutdown(sock, bind) < 0)
{
ParodusError ("nn_shutdown bind socket=%d endpt=%d, err=%d\n",
sock, bind, errno);
}
if (nn_close (sock) < 0)
{
ParodusError ("nn_close bind socket=%d err=%d\n",
sock, errno);
}
}
}
else
@@ -234,7 +244,7 @@ void *processUpstreamMessage()
if(rv > 0)
{
msgType = msg->msg_type;
if(msgType == 9)
if(msgType == WRP_MSG_TYPE__SVC_REGISTRATION)
{
ParodusInfo("\n Nanomsg client Registration for Upstream\n");
//Extract serviceName and url & store it in a linked list for reg_clients
@@ -249,12 +259,16 @@ void *processUpstreamMessage()
{
ParodusInfo("match found, client is already registered\n");
parStrncpy(temp->url,msg->u.reg.url, sizeof(temp->url));
if(nn_shutdown(temp->sock, 0) < 0)
if(nn_shutdown(temp->sock, temp->endpoint) < 0)
{
ParodusError ("nn_shutdown socket=%d err=%d\n",
ParodusError ("nn_shutdown socket=%d endpt=%d, err=%d\n",
temp->sock, temp->endpoint, errno);
}
if (nn_close (temp->sock) < 0)
{
ParodusError ("nn_close socket=%d err=%d\n",
temp->sock, errno);
}
nn_close (temp->sock);
temp->sock = nn_socket(AF_SP,NN_PUSH );
if(temp->sock >= 0)
@@ -272,6 +286,7 @@ void *processUpstreamMessage()
}
else
{
temp->endpoint = rc;
ParodusInfo("Client registered before. Sending ack on socket %d\n", temp->sock);
status =sendAuthStatus(temp);
@@ -402,9 +417,8 @@ void *processUpstreamMessage()
{
ParodusError("Failed to get device_id\n");
}
}
else
{
} else if (WRP_MSG_TYPE__SVC_ALIVE != msgType) {
/* Don't reply to service alive message */
sendUpstreamMsgToServer(&message->msg, message->len);
}
}
@@ -575,6 +589,7 @@ void sendUpstreamMsgToServer(void **resp_bytes, size_t resp_size)
else
{
ParodusInfo("close_retry is %d, unable to send response as connection retry is in progress\n", close_retry);
OnboardLog("close_retry is %d, unable to send response as connection retry is in progress\n", close_retry);
}
free(appendData);
appendData =NULL;

View File

@@ -193,6 +193,17 @@ target_link_libraries (test_auth_token -lcmocka
-Wl,--no-as-needed -lcimplog
-lcjson -lcjwt -ltrower-base64 -lssl -lcrypto -lrt -lm -lcurl -luuid
)
#-------------------------------------------------------------------------------
# test_auth_token_more
#-------------------------------------------------------------------------------
add_test(NAME test_auth_token_more COMMAND ${MEMORY_CHECK} ./test_auth_token_more)
add_executable(test_auth_token_more test_auth_token_more.c ../src/config.c ../src/auth_token.c ../src/string_helpers.c)
target_link_libraries (test_auth_token_more -lcmocka
-Wl,--no-as-needed -lcimplog
-lcjson -lcjwt -ltrower-base64 -lssl -lcrypto -lrt -lm -lcurl -luuid
)
#-------------------------------------------------------------------------------
# test_crud_interface
#-------------------------------------------------------------------------------
@@ -224,6 +235,17 @@ target_link_libraries (test_upstream -lcmocka gcov -lcunit -lcimplog
-Wl,--no-as-needed -lcjson -lcjwt -ltrower-base64
-lssl -lcrypto -lrt -lm)
#-------------------------------------------------------------------------------
# test_upstream_sock
#-------------------------------------------------------------------------------
add_test(NAME test_upstream_sock COMMAND ${MEMORY_CHECK} ./test_upstream_sock)
add_executable(test_upstream_sock test_upstream_sock.c ../src/upstream.c
../src/client_list.c ../src/close_retry.c ../src/string_helpers.c)
target_link_libraries (test_upstream_sock -lcmocka gcov -lcunit -lcimplog
-lwrp-c -luuid -lpthread -lmsgpackc -lnopoll -lnanomsg
-Wl,--no-as-needed -lcjson -lcjwt -ltrower-base64
-lssl -lcrypto -lrt -lm)
#-------------------------------------------------------------------------------
# test_downstream
#-------------------------------------------------------------------------------

View File

@@ -40,11 +40,19 @@ typedef enum {
CURLINFO_TOTAL_TIME
} CURLINFO;
struct token_data test_data;
int curl_easy_perform(CURL *curl)
{
UNUSED(curl);
char *msg = "response";
int rtn;
function_called();
return (int) mock();
rtn = (int) mock();
if (0 == rtn)
write_callback_fn (msg, 1, strlen(msg), &test_data);
return rtn;
}
int curl_easy_getinfo(CURL *curl, CURLINFO CURLINFO_RESPONSE_CODE, long response_code)
@@ -67,6 +75,7 @@ void getAuthToken_Null()
getAuthToken(&cfg);
set_parodus_cfg(&cfg);
assert( cfg.client_cert_path == NULL);
assert_int_equal (0, (int) cfg.webpa_auth_token[0]);
}
void getAuthToken_MacNull()
@@ -77,8 +86,10 @@ void getAuthToken_MacNull()
getAuthToken(&cfg);
set_parodus_cfg(&cfg);
assert( cfg.client_cert_path == NULL);
assert_int_equal (0, (int) cfg.webpa_auth_token[0]);
}
#if 0
void test_requestNewAuthToken_init_fail ()
{
char token[32];
@@ -106,7 +117,7 @@ void test_requestNewAuthToken_init_fail ()
assert_int_equal (output, -1);
free(cfg.token_server_url);
}
#endif
void test_requestNewAuthToken_failure ()
{
@@ -121,6 +132,8 @@ void test_requestNewAuthToken_failure ()
parStrncpy(cfg.hw_mac , "123567892366", sizeof(cfg.hw_mac));
set_parodus_cfg(&cfg);
test_data.size = 0;
test_data.data = token;
will_return (curl_easy_perform, -1);
expect_function_calls (curl_easy_perform, 1);
@@ -132,6 +145,7 @@ void test_requestNewAuthToken_failure ()
requestNewAuthToken (token, sizeof(token), 2);
assert_int_equal (output, -1);
assert_int_equal (0, (int) token[0]);
free(cfg.token_server_url);
}
@@ -150,6 +164,8 @@ void test_requestNewAuthToken ()
parStrncpy(cfg.hw_mac , "123567892366", sizeof(cfg.hw_mac));
set_parodus_cfg(&cfg);
test_data.size = 0;
test_data.data = token;
will_return (curl_easy_perform, 0);
expect_function_calls (curl_easy_perform, 1);
will_return (curl_easy_getinfo, 0);
@@ -160,6 +176,7 @@ void test_requestNewAuthToken ()
output = requestNewAuthToken (token, sizeof(token), 1);
assert_int_equal (output, 0);
assert_string_equal (token, "response");
free(cfg.token_server_url);
}
@@ -197,6 +214,8 @@ void test_getAuthToken ()
expect_function_calls (curl_easy_getinfo, 1);
/* To test curl success case */
test_data.size = 0;
test_data.data = cfg.webpa_auth_token;
will_return (curl_easy_perform, 0);
expect_function_calls (curl_easy_perform, 1);
@@ -207,7 +226,7 @@ void test_getAuthToken ()
expect_function_calls (curl_easy_getinfo, 1);
getAuthToken(&cfg);
assert_string_equal (cfg.webpa_auth_token, "response");
free(cfg.client_cert_path);
free(cfg.token_server_url);
}
@@ -224,6 +243,7 @@ void test_getAuthTokenFailure ()
parStrncpy(cfg.hw_serial_number, "Fer23u948590", sizeof(cfg.hw_serial_number));
parStrncpy(cfg.hw_mac , "123567892366", sizeof(cfg.hw_mac));
set_parodus_cfg(&cfg);
will_return (curl_easy_perform, -1);
expect_function_calls (curl_easy_perform, 1);
@@ -261,20 +281,35 @@ void test_getAuthTokenFailure ()
void test_write_callback_fn ()
{
void *buffer;
size_t size = 1;
size_t nmemb =8;
ParodusCfg *cfg;
size_t max_data_size = sizeof (cfg->webpa_auth_token);
char *buffer1 = "response1";
size_t buf1len = strlen(buffer1);
char *buffer2 = "R2";
size_t buf2len = strlen(buffer2);
char buffer3[max_data_size];
int out_len=0;
struct token_data data;
data.size = 0;
buffer = strdup("response");
data.data = (char *) malloc(sizeof(char) * 5);
data.data = (char *) malloc(max_data_size);
data.data[0] = '\0';
out_len = write_callback_fn(buffer, size, nmemb, &data);
assert_string_equal(data.data, buffer);
assert_int_equal( out_len, strlen(buffer));
out_len = write_callback_fn(buffer1, 1, buf1len, &data);
assert_string_equal(data.data, buffer1);
assert_int_equal (out_len, buf1len);
assert_int_equal (data.size, buf1len);
out_len = write_callback_fn(buffer2, 1, buf2len, &data);
assert_string_equal(data.data, "response1R2");
assert_int_equal (out_len, buf2len);
assert_int_equal (data.size, buf1len+buf2len);
memset (buffer3, 'x', max_data_size);
out_len = write_callback_fn(buffer3, 1, max_data_size, &data);
assert_int_equal (out_len, 0);
assert_int_equal (data.size, 0);
free(data.data);
}
@@ -285,14 +320,14 @@ void test_write_callback_fn ()
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_write_callback_fn),
cmocka_unit_test(test_requestNewAuthToken),
cmocka_unit_test(test_requestNewAuthToken_init_fail),
// cmocka_unit_test(test_requestNewAuthToken_init_fail),
cmocka_unit_test(test_requestNewAuthToken_failure),
cmocka_unit_test(getAuthToken_Null),
cmocka_unit_test(getAuthToken_MacNull),
cmocka_unit_test(test_getAuthToken),
cmocka_unit_test(test_getAuthTokenFailure),
cmocka_unit_test(test_write_callback_fn),
};
return cmocka_run_group_tests(tests, NULL, NULL);

View File

@@ -0,0 +1,109 @@
/**
* Copyright 2010-2016 Comcast Cable Communications Management, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <assert.h>
#include <errno.h>
#include <pthread.h>
#include <malloc.h>
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <CUnit/Basic.h>
#include "../src/config.h"
#include "../src/auth_token.h"
#include "../src/ParodusInternal.h"
extern int requestNewAuthToken(char *newToken, size_t len, int r_count);
/*----------------------------------------------------------------------------*/
/* Mocks */
/*----------------------------------------------------------------------------*/
typedef void CURL;
typedef enum {
CURLINFO_RESPONSE_CODE = 2,
CURLINFO_TOTAL_TIME
} CURLINFO;
struct token_data test_data;
CURL *curl_easy_init ()
{
function_called();
return (CURL *) mock();
}
int curl_easy_perform(CURL *curl)
{
UNUSED(curl);
char *msg = "response";
int rtn;
function_called();
rtn = (int) mock();
if (0 == rtn)
write_callback_fn (msg, 1, strlen(msg), &test_data);
return rtn;
}
int curl_easy_getinfo(CURL *curl, CURLINFO CURLINFO_RESPONSE_CODE, long response_code)
{
UNUSED(curl);
UNUSED(CURLINFO_RESPONSE_CODE);
UNUSED(response_code);
function_called();
return (int) mock();
}
/*----------------------------------------------------------------------------*/
/* Tests */
/*----------------------------------------------------------------------------*/
void test_requestNewAuthToken_init_fail ()
{
char token[32];
ParodusCfg cfg;
int output = -1;
memset(&cfg,0,sizeof(cfg));
cfg.token_server_url = strdup("https://dev.comcast.net/token");
parStrncpy(cfg.cert_path , "/etc/ssl/certs/ca-certificates.crt", sizeof(cfg.cert_path));
parStrncpy(cfg.hw_serial_number, "Fer23u948590", sizeof(cfg.hw_serial_number));
parStrncpy(cfg.hw_mac , "123567892366", sizeof(cfg.hw_mac));
set_parodus_cfg(&cfg);
will_return (curl_easy_init, NULL);
expect_function_calls (curl_easy_init, 1);
requestNewAuthToken (token, sizeof(token), 2);
assert_int_equal (output, -1);
assert_int_equal (0, (int) token[0]);
free(cfg.token_server_url);
}
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_requestNewAuthToken_init_fail)
};
return cmocka_run_group_tests(tests, NULL, NULL);
}

View File

@@ -33,6 +33,7 @@
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
static char *reconnect_reason = "webpa_process_starts";
UpStreamMsg *UpStreamMsgQ;
ParodusMsg *ParodusMsgQ;
pthread_mutex_t g_mutex=PTHREAD_MUTEX_INITIALIZER;
@@ -74,6 +75,48 @@ noPollMutexUnlock mutex_unlock
UNUSED(mutex_create); UNUSED(mutex_destroy); UNUSED(mutex_lock); UNUSED(mutex_unlock);
function_called();
}
char *get_global_reconnect_reason()
{
return reconnect_reason;
}
char *get_global_shutdown_reason()
{
return SHUTDOWN_REASON_PARODUS_STOP;
}
void set_global_shutdown_reason(char *reason)
{
UNUSED(reason);
}
void start_conn_in_progress (void)
{
}
void stop_conn_in_progress (void)
{
}
void reset_interface_down_event (void)
{
}
bool get_interface_down_event (void)
{
return false;
}
int wait_while_interface_down (void)
{
return 0;
}
void terminate_backoff_delay (void)
{
}
void packMetaData()
{
function_called();
@@ -300,7 +343,6 @@ 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);
}

View File

@@ -24,6 +24,7 @@
#include <assert.h>
#include <CUnit/Basic.h>
#include <nopoll.h>
#include <pthread.h>
#include "../src/ParodusInternal.h"
#include "../src/connection.h"
@@ -60,7 +61,10 @@ extern int keep_trying_to_connect (create_connection_ctx_t *ctx,
bool close_retry;
bool LastReasonStatus;
pthread_mutex_t close_mut;
bool interface_down_event = false;
pthread_mutex_t close_mut;
pthread_mutex_t interface_down_mut=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t interface_down_con=PTHREAD_COND_INITIALIZER;
// Mock values
bool g_shutdown = false;
@@ -80,6 +84,35 @@ char* getWebpaConveyHeader()
return (char*) "WebPA-1.6 (TG1682)";
}
void set_interface_down_event()
{
interface_down_event = true;
}
void reset_interface_down_event()
{
pthread_mutex_lock (&interface_down_mut);
interface_down_event = false;
pthread_cond_signal(&interface_down_con);
pthread_mutex_unlock (&interface_down_mut);
}
bool get_interface_down_event()
{
return interface_down_event;
}
pthread_cond_t *get_interface_down_con(void)
{
return &interface_down_con;
}
pthread_mutex_t *get_interface_down_mut(void)
{
return &interface_down_mut;
}
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);
@@ -117,6 +150,8 @@ nopoll_bool nopoll_conn_wait_for_status_until_connection_ready (noPollConn * co
int timeout, int *status, char ** message)
{
UNUSED(conn); UNUSED(timeout);
*message = NULL;
if (mock_wait_status >= 1000) {
*status = mock_wait_status / 1000;
mock_wait_status = mock_wait_status % 1000;
@@ -146,11 +181,9 @@ void nopoll_conn_close (noPollConn *conn)
UNUSED(conn);
}
int nopoll_conn_ref_count (noPollConn *conn)
void nopoll_conn_close_ext (noPollConn *conn, int status, const char *reason, int reason_size)
{
UNUSED(conn);
function_called ();
return (nopoll_bool) mock();
UNUSED(conn); UNUSED(status); UNUSED(reason); UNUSED(reason_size);
}
int checkHostIp(char * serverIP)
@@ -198,6 +231,7 @@ int allow_insecure_conn (char **server_addr, unsigned int *port)
/* Tests */
/*----------------------------------------------------------------------------*/
void test_get_global_conn()
{
assert_null(get_global_conn());
@@ -375,6 +409,15 @@ void test_set_current_server()
assert_ptr_equal (&ctx.server_list.defaults, ctx.current_server);
}
void init_cfg_header_info (ParodusCfg *cfg)
{
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));
}
void test_set_extra_headers ()
{
int rtn;
@@ -391,12 +434,8 @@ void test_set_extra_headers ()
cfg.client_cert_path = strdup("testcert");
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));
init_cfg_header_info (&cfg);
parStrncpy(cfg.cert_path , "/etc/ssl/certs/ca-certificates.crt", sizeof(cfg.cert_path));
parStrncpy(cfg.webpa_protocol , "WebPA-1.6", sizeof(cfg.webpa_protocol));
set_parodus_cfg(&cfg);
rtn = init_header_info (&ctx.header_info);
@@ -578,19 +617,12 @@ void test_nopoll_connect ()
// 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_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);
@@ -605,7 +637,7 @@ void test_wait_connection_ready ()
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_false);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
assert_int_equal (wait_connection_ready (&ctx), WAIT_FAIL);
mock_wait_status = 503;
will_return (nopoll_conn_wait_for_status_until_connection_ready, nopoll_false);
expect_function_call (nopoll_conn_wait_for_status_until_connection_ready);
@@ -640,30 +672,18 @@ void test_wait_connection_ready ()
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
#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 ()
{
@@ -707,8 +727,6 @@ void test_connect_and_wait ()
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);
assert_int_equal (connect_and_wait (&ctx), CONN_WAIT_RETRY_DNS);
Cfg.flags = 0;
@@ -718,8 +736,6 @@ void test_connect_and_wait ()
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);
@@ -757,8 +773,6 @@ void test_connect_and_wait ()
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);
@@ -769,8 +783,6 @@ void test_connect_and_wait ()
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);
@@ -790,8 +802,6 @@ void test_connect_and_wait ()
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);
@@ -802,8 +812,6 @@ void test_connect_and_wait ()
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);
}
@@ -815,22 +823,16 @@ void test_keep_trying ()
server_t test_server;
backoff_timer_t backoff_timer;
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));
init_cfg_header_info (&Cfg);
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";
@@ -861,8 +863,6 @@ void test_keep_trying ()
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);
@@ -881,16 +881,12 @@ void test_keep_trying ()
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);
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);
init_backoff_timer (&backoff_timer, 5);
rtn = keep_trying_to_connect (&ctx, &backoff_timer);
assert_int_equal (rtn, false);
@@ -913,8 +909,6 @@ void test_keep_trying ()
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);
init_backoff_timer (&backoff_timer, 5);
rtn = keep_trying_to_connect (&ctx, &backoff_timer);
assert_int_equal (rtn, false);
@@ -964,8 +958,6 @@ void test_create_nopoll_connection()
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);
@@ -979,8 +971,6 @@ void test_create_nopoll_connection()
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);
@@ -989,15 +979,11 @@ void test_create_nopoll_connection()
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);
@@ -1041,8 +1027,6 @@ void test_create_nopoll_connection()
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);
@@ -1056,6 +1040,149 @@ void test_create_nopoll_connection()
}
void test_get_interface_down_event()
{
assert_false(get_interface_down_event());
set_interface_down_event();
}
void *a()
{
sleep(15);
reset_interface_down_event();
pthread_exit(0);
return NULL;
}
void test_interface_down_retry()
{
int rtn;
ParodusCfg cfg;
noPollCtx test_nopoll_ctx;
pthread_t thread_a;
pthread_create(&thread_a, NULL, a, NULL);
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_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_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_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_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);
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
pthread_join(thread_a, NULL);
}
/*----------------------------------------------------------------------------*/
/* External Functions */
@@ -1083,7 +1210,9 @@ int main(void)
cmocka_unit_test(test_wait_connection_ready),
cmocka_unit_test(test_connect_and_wait),
cmocka_unit_test(test_keep_trying),
cmocka_unit_test(test_create_nopoll_connection)
cmocka_unit_test(test_create_nopoll_connection),
cmocka_unit_test(test_get_interface_down_event),
cmocka_unit_test(test_interface_down_retry)
};
return cmocka_run_group_tests(tests, NULL, NULL);

View File

@@ -21,6 +21,7 @@
#include <nopoll_private.h>
#include <pthread.h>
#include "../src/ParodusInternal.h"
#include "../src/nopoll_handlers.h"
#include "../src/parodus_log.h"
@@ -29,8 +30,11 @@
/*----------------------------------------------------------------------------*/
volatile unsigned int heartBeatTimer;
bool LastReasonStatus;
bool interface_down_event = false;
int closeReason = 0;
pthread_mutex_t close_mut;
pthread_mutex_t close_mut;
pthread_mutex_t interface_down_mut=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t interface_down_con=PTHREAD_COND_INITIALIZER;
bool close_retry;
/*----------------------------------------------------------------------------*/
/* Mocks */
@@ -46,6 +50,24 @@ bool get_global_reconnect_status()
return LastReasonStatus;
}
void set_interface_down_event()
{
interface_down_event = true;
}
void reset_interface_down_event()
{
pthread_mutex_lock (&interface_down_mut);
interface_down_event = false;
pthread_cond_signal(&interface_down_con);
pthread_mutex_unlock (&interface_down_mut);
}
bool get_interface_down_event()
{
return interface_down_event;
}
void set_global_reconnect_status(bool status)
{
(void) status ;
@@ -179,6 +201,30 @@ void test_listenerOnPingMessage()
listenerOnPingMessage(NULL, NULL, NULL, NULL);
}
void test_getInterfaceDownEvent()
{
set_interface_down_event();
CU_ASSERT_TRUE(get_interface_down_event());
}
void test_interfaceDownEvent()
{
char str[] = "SSL_Socket_Close";
set_global_reconnect_status(true);
set_interface_down_event();
listenerOnCloseMessage(NULL, NULL, (noPollPtr) str);
}
void test_noInterfaceDownEvent()
{
char str[] = "SSL_Socket_Close";
set_global_reconnect_status(true);
reset_interface_down_event();
listenerOnCloseMessage(NULL, NULL, (noPollPtr) str);
}
void add_suites( CU_pSuite *suite )
{
ParodusInfo("--------Start of Test Cases Execution ---------\n");
@@ -186,6 +232,9 @@ void add_suites( CU_pSuite *suite )
CU_add_test( *suite, "Test 1", test_listenerOnMessage_queue );
CU_add_test( *suite, "Test 2", test_listenerOnCloseMessage );
CU_add_test( *suite, "Test 3", test_listenerOnPingMessage );
CU_add_test( *suite, "Test 4", test_getInterfaceDownEvent );
CU_add_test( *suite, "Test 5", test_interfaceDownEvent );
CU_add_test( *suite, "Test 6", test_noInterfaceDownEvent );
}
/*----------------------------------------------------------------------------*/

View File

@@ -48,6 +48,11 @@ bool get_global_reconnect_status()
return LastReasonStatus;
}
bool get_interface_down_event()
{
return false;
}
void set_global_reconnect_status(bool status)
{
(void) status ;

View File

@@ -16,6 +16,7 @@
#include <stdarg.h>
#include <stddef.h>
#include <stdbool.h>
#include <setjmp.h>
#include <cmocka.h>
#include <nopoll.h>
@@ -116,6 +117,11 @@ int kill(pid_t pid, int sig)
return (int) mock();
}
bool get_interface_down_event()
{
return false;
}
/*----------------------------------------------------------------------------*/
/* Tests */
/*----------------------------------------------------------------------------*/

View File

@@ -273,6 +273,10 @@ void test_handleUpstreamNull()
expect_function_call(nn_bind);
will_return(nn_recv, 12);
expect_function_call(nn_recv);
will_return(nn_shutdown, 0);
expect_function_call(nn_shutdown);
will_return(nn_close, 0);
expect_function_call(nn_close);
handle_upstream();
}
@@ -294,6 +298,10 @@ void test_handle_upstream()
expect_function_call(nn_bind);
will_return(nn_recv, 12);
expect_function_call(nn_recv);
will_return(nn_shutdown, 0);
expect_function_call(nn_shutdown);
will_return(nn_close, 0);
expect_function_call(nn_close);
handle_upstream();
free(UpStreamMsgQ->next);
free(UpStreamMsgQ);

249
tests/test_upstream_sock.c Normal file
View File

@@ -0,0 +1,249 @@
/**
* Copyright 2010-2016 Comcast Cable Communications Management, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <assert.h>
#include <errno.h>
#include <pthread.h>
#include <malloc.h>
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <nopoll.h>
#include <wrp-c.h>
#include <nanomsg/nn.h>
#include "../src/upstream.h"
#include "../src/config.h"
#include "../src/client_list.h"
#include "../src/ParodusInternal.h"
#include "../src/partners_check.h"
#include "../src/close_retry.h"
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
#define GOOD_CLIENT_URL "tcp://127.0.0.1:6667"
static noPollConn *conn;
static char *reconnect_reason = "webpa_process_starts";
bool g_shutdown = false;
static ParodusCfg parodusCfg;
extern size_t metaPackSize;
extern UpStreamMsg *UpStreamMsgQ;
int numLoops = 1;
int deviceIDNull =0;
wrp_msg_t *reg_msg = NULL;
extern pthread_mutex_t nano_mut;
extern pthread_cond_t nano_con;
/*----------------------------------------------------------------------------*/
/* Mocks */
/*----------------------------------------------------------------------------*/
reg_list_item_t *get_reg_list()
{
reg_list_item_t *item = get_global_node();
release_global_node();
return item;
}
noPollConn *get_global_conn()
{
return conn;
}
char *get_global_reconnect_reason()
{
return reconnect_reason;
}
void addCRUDmsgToQueue(wrp_msg_t *crudMsg)
{
(void)crudMsg;
function_called();
return;
}
void sendMessage(noPollConn *conn, void *msg, size_t len)
{
(void) conn; (void) msg; (void) len;
function_called();
}
void set_parodus_cfg(ParodusCfg *cfg)
{
memcpy(&parodusCfg, cfg, sizeof(ParodusCfg));
}
ParodusCfg *get_parodus_cfg(void)
{
ParodusCfg cfg;
memset(&cfg,0,sizeof(cfg));
parStrncpy(cfg.hw_mac , "14cfe2142xxx", sizeof(cfg.hw_mac));
if(deviceIDNull)
{
parStrncpy(cfg.hw_mac , "", sizeof(cfg.hw_mac));
}
set_parodus_cfg(&cfg);
return &parodusCfg;
}
/*-------------------------------------------
int nn_connect (int s, const char *addr)
{
(void) s; (void) addr;
printf ("nn_connect, socket %d\n", s);
return 1;
}
---------------------------------------------*/
ssize_t wrp_pack_metadata( const data_t *packData, void **data )
{
(void) packData; (void) data;
function_called();
return (ssize_t)mock();
}
size_t appendEncodedData( void **appendData, void *encodedBuffer, size_t encodedSize, void *metadataPack, size_t metadataSize )
{
(void) encodedBuffer; (void) encodedSize; (void) metadataPack; (void) metadataSize;
function_called();
char *data = (char *) malloc (sizeof(char) * 100);
parStrncpy(data, "AAAAAAAAYYYYIGkYTUYFJH", 100);
*appendData = data;
return (size_t)mock();
}
int nn_send (int s, const void *buf, size_t len, int flags)
{
UNUSED(s); UNUSED(buf); UNUSED(len); UNUSED(flags);
function_called();
return (int)mock();
}
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex)
{
UNUSED(cond); UNUSED(mutex);
function_called();
return (int)mock();
}
ssize_t wrp_to_struct( const void *bytes, const size_t length, const enum wrp_format fmt, wrp_msg_t **msg )
{
UNUSED(bytes); UNUSED(length); UNUSED(fmt);
function_called();
*msg = reg_msg;
return (ssize_t)mock();
}
void wrp_free_struct( wrp_msg_t *msg )
{
UNUSED(msg);
function_called();
}
int nn_freemsg (void *msg)
{
UNUSED(msg);
function_called();
return (int)mock();
}
int validate_partner_id(wrp_msg_t *msg, partners_t **partnerIds)
{
UNUSED(msg); UNUSED(partnerIds);
function_called();
return (int) mock();
}
/*----------------------------------------------------------------------------*/
/* Tests */
/*----------------------------------------------------------------------------*/
void test_message()
{
metaPackSize = 20;
UpStreamMsgQ = (UpStreamMsg *) malloc(sizeof(UpStreamMsg));
UpStreamMsgQ->msg = "First Message";
UpStreamMsgQ->len = 13;
UpStreamMsgQ->next = NULL;
numLoops = 1;
reg_msg = (wrp_msg_t *) malloc(sizeof(wrp_msg_t));
memset(reg_msg,0,sizeof(wrp_msg_t));
reg_msg->msg_type = WRP_MSG_TYPE__SVC_REGISTRATION;
reg_msg->u.reg.service_name = "config";
reg_msg->u.reg.url = GOOD_CLIENT_URL;
will_return(wrp_to_struct, 12);
expect_function_call(wrp_to_struct);
will_return(nn_send, 1);
expect_function_call(nn_send);
will_return(nn_freemsg, 0);
expect_function_call(nn_freemsg);
expect_function_call(wrp_free_struct);
processUpstreamMessage();
free(reg_msg);
free(UpStreamMsgQ);
}
void test_processUpstreamMessage()
{
int last_sock = -1;
reg_list_item_t * reg_item = get_reg_list ();
assert_null (reg_item);
test_message();
reg_item = get_reg_list ();
assert_non_null (reg_item);
if (NULL == reg_item)
return;
last_sock = reg_item->sock;
test_message ();
assert_int_equal (get_numOfClients(), 1);
if (get_numOfClients() != 1)
return;
reg_item = get_reg_list ();
assert_int_equal (last_sock, reg_item->sock);
if (last_sock != reg_item->sock)
return;
test_message ();
assert_int_equal (get_numOfClients(), 1);
if (get_numOfClients() != 1)
return;
reg_item = get_reg_list ();
assert_int_equal (last_sock, reg_item->sock);
}
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_processUpstreamMessage)
};
return cmocka_run_group_tests(tests, NULL, NULL);
}