Compare commits

..

158 Commits

Author SHA1 Message Date
Shilpa Seshadri
bf342a6983 Clear auth token if fetch fails 2019-05-21 18:31:03 -07:00
Weston Schmidt
0910dfa11e Merge pull request #239 from gbuddappagari/boot_time_fix
Handle unknown and * partner_id in parodus
2018-09-10 09:55:06 -07:00
Gayathri
1b007fe3bb Handle unknown and * partner_id in parodus 2018-09-10 16:23:28 +05:30
Shilpa Seshadri
a252447494 Modify nopoll git tag as appropriate 2018-08-27 23:30:04 -07:00
Gayathri
7f4b6e3f9e Modified validation logic for boot-time
(cherry picked from commit 844a1d925a)

Conflicts:
	src/config.c
	src/config.h
2018-08-27 23:18:53 -07:00
Weston Schmidt
136da0621e Merge pull request #165 from bill1600/master
remove references to comcast in readme. change dns-id param to dns-txt-url
2018-02-22 10:30:25 -08:00
Bill Williams
2aa134c9d4 remove references to comcast in readme. change dns-id param to dns-txt-url 2018-02-16 08:00:55 -08:00
Weston Schmidt
0a7d2f3a1a Merge pull request #163 from bill1600/master
cmd line parameter changes
2018-02-15 10:10:46 -08:00
Bill Williams
968727eece use parse_num_arg for nueric arguments 2018-02-07 16:38:48 -08:00
Bill Williams
bac0a6983d add test_standard_strncmp to test_createConnection 2018-02-07 14:03:55 -08:00
Bill Williams
f877b9c22f add config tests 2018-02-07 13:38:31 -08:00
Bill Williams
9b988c6878 add test_parse_mac_address to test_config 2018-02-07 09:38:07 -08:00
Bill Williams
91d7f4a02b add check of key file in test_config 2018-02-06 15:22:56 -08:00
Bill Williams
b74f73ee73 update test_config error tests 2018-02-06 12:47:22 -08:00
Bill Williams
df53862dec Merge branch 'master' of https://github.com/Comcast/parodus 2018-02-06 10:27:18 -08:00
Bill Williams
b85e78fb7b changes to disallow none, dns-id rule change and update readme 2018-02-06 10:21:51 -08:00
Weston Schmidt
38b8cbf4ac Merge pull request #162 from bill1600/master
fix test_errParseCommandLine
2018-01-30 17:31:55 -08:00
Bill Williams
4671e40b32 fix test_errParseCommandLine 2018-01-30 14:48:09 -08:00
Bill Williams
22278846e1 enable messages in tests in travis 2018-01-29 17:06:44 -08:00
Bill Williams
ed3ec23a47 fix test_errParseCommandLine 2018-01-29 16:21:21 -08:00
Weston Schmidt
b1b6883799 Merge pull request #160 from sadhyama/master
To update upstream token in configuration
2018-01-26 17:53:06 -08:00
Shilpa Seshadri
79b6861af6 Fixing compiler errors 2018-01-26 17:28:47 -08:00
shilpa24balaji
e298549510 Merge branch 'master' into master 2018-01-26 16:54:09 -08:00
Bill Williams
3a181d2ffe fix coverity issue CID 1464190. possible array overrun in connection.c 2018-01-25 11:50:22 -08:00
Bill Williams
be71810dea update README file to correspond with cmd line changes 2018-01-25 11:12:04 -08:00
Bill Williams
2bf902242f fix merge conflicts and verify they aren't really anything 2018-01-24 15:01:34 -08:00
Bill Williams
2b15321a77 use tag nopoll_yocto in CMakeLists.txt 2018-01-23 14:14:12 -08:00
Bill Williams
f21a00616a apply default ports 443 and 80 2018-01-22 13:37:26 -08:00
Sadhyama Vengilat
8df4ad3cbc To update upstream token in configuration 2018-01-22 17:12:31 +05:30
Bill Williams
7f2aa3f826 merge with latest parodus 2018-01-19 14:39:17 -08:00
shilpa24balaji
7946f585ee Merge pull request #159 from Comcast/remove-a-few-buffers
Clean up the header processing code a bit.
2018-01-18 11:35:51 -08:00
Weston Schmidt
5f10aae6c2 Make the whitespace consistent. 2018-01-17 16:09:39 -08:00
Weston Schmidt
e11927f8de Clean up the header processing code a bit. 2018-01-17 16:05:18 -08:00
Weston Schmidt
c478da9f7c Fix a buffer being too small and causing compiler warnings. 2018-01-17 15:36:14 -08:00
Weston Schmidt
0bdb8f96b8 Merge pull request #158 from sadhyama/master
Add cmd line args support for acquisition and read header
2018-01-17 13:30:09 -08:00
Sadhyama Vengilat
b1c9cdfa16 Add cmd line args support for acquisition and read header 2018-01-17 19:20:01 +05:30
Shilpa Seshadri
04cefb9037 Added sudo to run parodus with root permission to avoid port bind error 2018-01-16 12:29:22 -08:00
Weston Schmidt
21fe137755 Merge pull request #155 from gbuddappagari/master
Updating msgpack dependency version with 2.1.5.
2018-01-12 02:23:19 -08:00
Gayathri
807839f8c5 Updating msgpack dependency version with 2.1.5. 2018-01-12 12:26:03 +05:30
Bill Williams
bbf8813303 extract port from JWT endpoint 2018-01-11 13:50:47 -08:00
Weston Schmidt
e9ae72c79b Merge pull request #154 from gbuddappagari/master
Added tests for configurable secure flag
2018-01-10 22:16:13 -08:00
Gayathri
268b1a2e82 Added tests for configurable secure flag 2018-01-10 17:47:39 +05:30
Weston Schmidt
ca4132b9e3 Merge pull request #152 from sadhyama/master
Configurable secure flag and port
2018-01-09 13:07:14 -08:00
Bill Williams
7d8c0bcff2 update .travis.yml cmake cmd to specify FEATURE_DNS_QUERY 2018-01-09 11:46:36 -08:00
Bill Williams
0ba7f5b95a support fabric.xmidt.comcast.net 2018-01-09 09:44:30 -08:00
Sadhyama Vengilat
36735f588d Added method to set default values and removed loadParodusCfg 2018-01-08 19:32:06 +05:30
Sadhyama Vengilat
5f4d640467 Changes for Configurable secure flag and port 2018-01-08 14:20:36 +05:30
Weston Schmidt
7bc99bb48c Merge pull request #148 from sadhyama/master
Modified strcpy to strncpy
2017-12-15 15:58:11 -08:00
Sadhyama Vengilat
cf1e9c51d2 Modified strcpy to strncpy 2017-12-15 18:19:54 +05:30
Weston Schmidt
14241251d8 Merge pull request #147 from sadhyama/master
Handle 403 error from talaria in parodus
2017-12-14 20:24:55 -08:00
Sadhyama Vengilat
eb67134b10 Handle 403 error from talaria in parodus 2017-12-14 17:03:23 +05:30
Weston Schmidt
93f30417de Merge pull request #145 from armcc/master
spin_thread.c: don't assume pthread_t can be cast to int
2017-12-01 11:46:47 -08:00
Andre McCurdy
d282afca4f spin_thread.c: don't assume pthread_t can be cast to int
Fix build issues for 64bit targets.

Signed-off-by: Andre McCurdy <armccurdy@gmail.com>
2017-11-30 15:30:27 -08:00
Weston Schmidt
81dff2cef0 Merge pull request #144 from cableramki/master
Reduced duplicate code and fixed debug info to display based on messa…
2017-11-30 12:20:34 -08:00
Ramki Ananthakrishnan
a3991b3ed9 Reduced duplicate code and fixed debug info to display based on message type. 2017-11-29 15:43:30 -08:00
Weston Schmidt
afbb5c5fa0 Merge pull request #142 from cableramki/master
Added downstream support to pass through other types of WRP messages.
2017-11-17 07:06:43 -08:00
Ramki Ananthakrishnan
0003bc4a25 Fixed some discrepancies handling different message types and added tests. 2017-11-17 01:01:31 -08:00
shilpa24balaji
b83392f519 Merge pull request #143 from Comcast/revert-140-master
Revert "Configurable secure flag and port"
2017-11-16 22:41:40 -08:00
shilpa24balaji
50a8cd7911 Revert "Configurable secure flag and port" 2017-11-16 22:22:25 -08:00
Ramki Ananthakrishnan
5c388d1db7 Added changes from review. 2017-11-16 19:48:21 -08:00
Ramki Ananthakrishnan
aa596dd3c2 Added downstream support to pass through CRUD messages. 2017-11-16 18:55:12 -08:00
Weston Schmidt
7829ec3de6 Merge pull request #140 from gbuddappagari/master
Configurable secure flag and port
2017-11-15 09:15:02 -08:00
Gayathri
f214d119a3 Configurable secure flag and port 2017-11-15 17:25:40 +05:30
Weston Schmidt
99393a233d Merge pull request #139 from Comcast/decode_free
To fix the parodus crash during invalid message type decode and free
2017-11-07 21:11:05 -08:00
Shilpa Seshadri
8b8c3f0950 To fix the parodus crash during invalid message type decode and free 2017-11-07 19:23:04 -08:00
Weston Schmidt
a461a7da10 Update license details an support materials. 2017-11-03 19:01:13 -07:00
Weston Schmidt
61ee6aca96 Merge pull request #138 from gbuddappagari/master
Use correct deallocator
2017-10-30 00:05:33 -07:00
Gayathri
774ec17e4e Use correct deallocator 2017-10-30 11:58:41 +05:30
Weston Schmidt
1fdf4a46ef Merge pull request #137 from gbuddappagari/master
Change logic to retrieve token
2017-10-27 08:46:00 -07:00
Gayathri
b8a48a400d Added webpa-token command-line argument to tests 2017-10-27 18:14:13 +05:30
Gayathri
acdb5c9937 Change logic to retrieve token 2017-10-27 11:57:32 +05:30
Weston Schmidt
76505cd414 Merge pull request #136 from gbuddappagari/master
Add command-line argument to acquire JWT and add it to HTTP HEADERS
2017-10-25 07:47:37 -07:00
Gayathri
d270f480e9 Add JWT to HTTP HEADERS 2017-10-25 18:11:29 +05:30
Gayathri
7fb0ed583c Add new command-line argument to acquire JWT 2017-10-25 18:08:35 +05:30
shilpa24balaji
73a64224cd Merge pull request #135 from Comcast/feature-ipv6-options
Add --force-ipv4 and --force-ipv6 flags and fix some surprises along the way.
2017-10-23 14:05:35 -07:00
Weston Schmidt
fe70242243 Remove a resource leak. 2017-10-20 21:55:57 -07:00
Weston Schmidt
d111826d92 Update the tests. 2017-10-20 21:28:07 -07:00
Weston Schmidt
818b84257c Fix ssl-cert-path option decorator. 2017-10-20 20:35:32 -07:00
Weston Schmidt
b1078b53d6 Add --force-ipv4 and --force-ipv6 flags. 2017-10-20 20:35:03 -07:00
Weston Schmidt
54849bba00 Fix error: webpa-interface-used option. 2017-10-20 20:00:37 -07:00
Weston Schmidt
f9b6ae840d Move the secureFlag into a group of flags. 2017-10-20 19:58:27 -07:00
Weston Schmidt
831df10422 Fix a variable aliasing problem. 2017-10-20 19:52:14 -07:00
Weston Schmidt
c63867a936 Normalize the code format a bit. 2017-10-20 19:48:03 -07:00
Weston Schmidt
0b90f0fe3b Merge pull request #134 from sadhyama/master
To remove logging of sensitive data from request/response payload
2017-10-11 15:17:58 -07:00
Sadhyama Vengilat
429abeb6a5 To remove logging of sensitive data from request/response payload 2017-10-10 19:31:13 +05:30
Weston Schmidt
0acefa0c37 Merge pull request #132 from gbuddappagari/master
Set ssl cert path using command-line argument
2017-08-30 09:43:39 -07:00
Gayathri
36fc6a7e51 Set ssl cert path using command-line argument 2017-08-30 14:50:26 +05:30
shilpa24balaji
66c6ec779d Merge pull request #131 from gbuddappagari/master
Enabled peer verify and added cert path
2017-08-29 22:38:16 -07:00
Gayathri
e888235850 Enabled peer verify and added cert path 2017-08-30 11:04:28 +05:30
Weston Schmidt
678d6c5f2d Merge pull request #130 from selvamKrish/master
Intregate breakpad only in yocto
2017-08-12 22:47:19 -07:00
skrishnamoorthy01
80f82521bd Intregate breakpad only in yocto 2017-08-11 12:01:13 +05:30
shilpa24balaji
a73373e055 Merge pull request #129 from selvamKrish/master
Disable peer verify and fix fedora build issue for nopoll
2017-08-02 23:57:21 -07:00
Selvam Krishnamoorthy
a9f11e85c6 Fix fedora build issue for nopoll 2017-08-03 12:05:40 +05:30
Selvam Krishnamoorthy
72ec4daf74 Disable peer verify 2017-08-03 12:03:14 +05:30
Weston Schmidt
278c1199cd Merge pull request #127 from selvamKrish/master
Incorporate review comments for createConnOpts function
2017-08-01 09:40:56 -07:00
shilpa24balaji
75c446b220 Merge pull request #128 from gbuddappagari/master
nopoll opts set ssl certs
2017-08-01 00:10:56 -07:00
Gayathri
e78174f314 nopoll opts set ssl certs for yocto 2017-08-01 11:59:54 +05:30
skrishnamoorthy01
3ee3ec356d Incorporate review comments for createConnOpts function 2017-07-31 18:46:21 +05:30
shilpa24balaji
e09ae35682 Merge pull request #126 from sadhyama/master
Fixed travis build failure due to test_createConnection
2017-07-28 10:58:06 -07:00
Sadhyama Vengilat
9fbe242ec7 Fixed travis build failure due to test_createConnection 2017-07-28 15:50:51 +05:30
Weston Schmidt
275f5595ce Merge pull request #125 from selvamKrish/master
Modify parodus to use latest nopoll 0.4.4
2017-07-26 14:54:41 -07:00
Selvam Krishnamoorthy
a9b4b44504 Enable peer verify and use opts for http connection 2017-07-26 20:36:02 +05:30
skrishnamoorthy01
dbc7b99b31 Modify parodus to use latest nopoll 0.4.4 2017-07-25 20:18:37 +05:30
Weston Schmidt
b68ba089cd Merge pull request #124 from sadhyama/master
Fixed few more coverity defects
2017-07-20 08:00:33 -07:00
Sadhyama Vengilat
6a921bd396 Fixed few more coverity defects 2017-07-20 19:23:31 +05:30
Weston Schmidt
b02c30256c Merge pull request #123 from sadhyama/master
Fix for defects reported by coverity
2017-07-19 08:06:06 -07:00
Sadhyama Vengilat
9a09357fc3 Fix for defects reported by coverity 2017-07-19 15:20:16 +05:30
Weston Schmidt
19208e2d0f Merge pull request #122 from gbuddappagari/master
Configurable command-line arguments
2017-07-18 21:29:20 -07:00
Gayathri
aacbcf5360 Configurable command-line arguments 2017-07-17 19:23:46 +05:30
Weston Schmidt
63b9b50534 Merge pull request #120 from sadhyama/master
Modified all strcpy to use parStrncpy wrapper and added unit test for parodus git commit hash
2017-07-17 05:57:43 -07:00
Sadhyama Vengilat
7e5aefd10a Added unit test to validate parodus git version 2017-07-17 16:37:35 +05:30
Sadhyama Vengilat
912638d59b Modified all strcpy to use parStrncpy wrapper 2017-07-17 16:17:03 +05:30
Weston Schmidt
883814ba42 Merge pull request #118 from gbuddappagari/master
seshat and cjwt conditional compilation
2017-07-13 10:23:11 -07:00
Gayathri
718beac0bd Enable seshat and cjwt compiler flags 2017-07-13 17:00:23 +05:30
Gayathri
88c4315a68 Allow JWT token validation to be configurable at compile time 2017-07-13 15:41:00 +05:30
Gayathri
d4bf5dc099 Allow seshat registration to be configurable at compile time 2017-07-13 15:35:44 +05:30
Weston Schmidt
3e91b55197 Merge pull request #116 from sadhyama/master
Added parodus version along with git commit hash
2017-07-11 13:05:32 -07:00
Sadhyama Vengilat
48d94661a3 Added parodus version along with git commit hash 2017-07-10 16:25:04 +05:30
Weston Schmidt
0da33e5ec3 Merge pull request #114 from gbuddappagari/master
Correcting compiler macro for UCLIBC
2017-06-22 07:39:16 -07:00
Gayathri
f67f385584 Correcting compiler macro for UCLIBC 2017-06-22 18:39:52 +05:30
Weston Schmidt
c55a480830 Merge pull request #113 from gbuddappagari/master
To fix Yocto build issue
2017-06-20 09:44:45 -07:00
Gayathri
976810432e To fix Yocto build issue 2017-06-20 18:08:05 +05:30
Ramki A
451517ca2b Merge pull request #111 from bill1600/ctests
add unit tests for config.c relating to jwt tokens
2017-06-19 14:59:21 -07:00
Bill Williams
c96fd044de add unit tests for config.c relating to jwt tokens 2017-06-16 10:05:50 -07:00
Weston Schmidt
0e2bc12736 Merge pull request #109 from selvamKrish/master
Update patch for hostname validation
2017-06-14 10:16:50 -07:00
Weston Schmidt
6dbf2d479b Merge pull request #106 from bill1600/vtests
fix coverity errors and add unit tests
2017-06-14 10:16:07 -07:00
Bill Williams
f8a0179753 add parentheses and another test 2017-06-14 10:06:58 -07:00
Weston Schmidt
05fad15ac5 Merge pull request #108 from cableramki/master
Increased test coverage for conn_interface.
2017-06-14 09:57:14 -07:00
skrishnamoorthy01
6f96cf6529 Update patch for hostname validation 2017-06-14 19:07:15 +05:30
skrishnamoorthy01
5ab7f7a697 Revert "Update patch for hostname validation"
This reverts commit 0807c5623f.
2017-06-14 18:56:51 +05:30
skrishnamoorthy01
0807c5623f Update patch for hostname validation 2017-06-14 18:54:01 +05:30
Ramki Ananthakrishnan
5eebbb8f49 Fixed param transposition build error. 2017-06-12 20:45:14 -07:00
Ramki Ananthakrishnan
d19a6f0022 Increased test coverage for conn_interface. 2017-06-12 20:43:28 -07:00
Bill Williams
6aeb6a42b1 fix coverity errors and add unit tests 2017-06-12 13:24:29 -07:00
Weston Schmidt
7e5ec0d670 Merge pull request #102 from bill1600/utests
forgot to activate dns server call in connection.c, also added more u…
2017-06-12 09:36:46 -07:00
Bill Williams
58c3fe35db forgot to activate dns server call in connection.c, also added more unit tests 2017-06-10 17:12:21 -07:00
Weston Schmidt
056659c19e Merge pull request #101 from bill1600/cjwt
cjwt integration into parodus
2017-06-09 11:56:49 -07:00
Bill Williams
ee0d1dd6c0 remove commented code from token.c 2017-06-09 11:22:58 -07:00
Bill Williams
e2296b497c fix test_config by reordering 2017-06-09 09:18:57 -07:00
Bill Williams
3b2b14056c fix test_config by reordering 2017-06-09 08:48:45 -07:00
Bill Williams
5c17a9fc73 fix test_config by reordering libs 2017-06-09 08:29:01 -07:00
Bill Williams
d8e78ff982 reorder link libs in tests to resolve all syms in travis env 2017-06-09 08:02:58 -07:00
Bill Williams
1ecc3ad516 explicit reference to trower-base64 library 2017-06-08 16:56:46 -07:00
Bill Williams
dd6fc7551a BUILD_TESTING OFF in trower-base64 2017-06-08 16:07:57 -07:00
Bill Williams
40e7963d29 BUILD_TESTING OFF off for cjwt 2017-06-08 15:48:34 -07:00
Bill Williams
866eb6b128 dont need libssl-dev, need shared cjwt 2017-06-08 11:23:57 -07:00
Bill Williams
f927aba40c need libssl-dev 2017-06-08 10:20:27 -07:00
Bill Williams
a55d28d85d back up 2017-06-08 09:42:37 -07:00
Bill Williams
b222bf7a7b travis to install ssl and crypto, try 2 2017-06-08 09:36:43 -07:00
Bill Williams
699fabc6df travis to install ssl and crypto 2017-06-08 09:30:25 -07:00
Bill Williams
8007039712 change travis.yml to install check 2017-06-07 16:05:36 -07:00
Bill Williams
e11a52fb57 cjwt integration into parodus 2017-06-07 09:23:57 -07:00
cableramki
4944f0a527 Merge pull request #99 from cableramki/master
Added null check before string comparison to fix crash being seen by …
2017-06-06 12:37:17 -07:00
Ramki Ananthakrishnan
7732aa02f2 Added null check before string comparison to fix crash being seen by offshore team. 2017-06-06 12:27:21 -07:00
Weston Schmidt
52e048b5ab Merge pull request #98 from gbuddappagari/master
Remove simple.c integration test cases
2017-06-06 05:43:44 -07:00
Gayathri
434c84773a Remove simple.c integration test cases 2017-06-06 16:32:32 +05:30
Weston Schmidt
03d420f8f7 Merge pull request #97 from sadhyama/master
Fixed parodus client reconnect issue due to delay in sending keep alive
2017-06-05 19:14:40 -07:00
Sadhyama Vengilat
5f2d73e0af Fixed parodus client reconnect issue due to delay in sending keep alive 2017-06-05 18:08:26 +05:30
72 changed files with 6631 additions and 2337 deletions

View File

@@ -8,12 +8,12 @@ compiler:
addons:
coverity_scan:
project:
name: "selvamKrish-parodus"
name: "Comcast/parodus"
description: "C implementation of the WebPA client coordinator"
notification_email: kselvam019@gmail.com
notification_email: weston_schmidt@alumni.purdue.edu
build_command_prepend: "mkdir coverity_build && cd coverity_build && cmake .."
build_command: "make"
branch_pattern: parodus_lws
branch_pattern: master
before_install:
- sudo pip install codecov
@@ -21,13 +21,14 @@ before_install:
install:
- sudo apt-get update -qq
- sudo apt-get install -y -qq libcunit1 libcunit1-dev uuid-dev valgrind
- sudo apt-get install -y -qq check libcunit1 libcunit1-dev uuid-dev valgrind
script:
- mkdir build
- cd build
- cmake .. -DINTEGRATION_TESTING:BOOL=false -DDISABLE_VALGRIND:BOOL=true
- cmake .. -DINTEGRATION_TESTING:BOOL=false -DDISABLE_VALGRIND:BOOL=true -DENABLE_SESHAT:BOOL=true -DFEATURE_DNS_QUERY:BOOL=true
- make
- export ARGS="-V"
- make test
after_success:

BIN
CLA.pdf

Binary file not shown.

View File

@@ -22,6 +22,7 @@ include(CTest)
set(INSTALL_DIR ${CMAKE_CURRENT_BINARY_DIR}/_install)
set(PREFIX_DIR ${CMAKE_CURRENT_BINARY_DIR}/_prefix)
set(INCLUDE_DIR ${INSTALL_DIR}/include)
set(INCLUDE_UCRESOLV ${PREFIX_DIR}/ucresolv/src/ucresolv/include)
set(LIBRARY_DIR ${INSTALL_DIR}/lib)
set(LIBRARY_DIR64 ${INSTALL_DIR}/lib64)
set(COMMON_LIBRARY_DIR ${INSTALL_DIR}/lib/${CMAKE_LIBRARY_ARCHITECTURE})
@@ -36,8 +37,19 @@ include_directories(${INCLUDE_DIR}
${INCLUDE_DIR}/wrp-c
${INCLUDE_DIR}/libparodus
${INCLUDE_DIR}/cimplog
${INCLUDE_DIR}/libseshat
)
${INCLUDE_DIR}/cjwt
)
# Get git commit hash
#-------------------------------------------------------------------------------
execute_process(
COMMAND git describe --tags --always
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE GIT_COMMIT_TAG
OUTPUT_STRIP_TRAILING_WHITESPACE
)
add_definitions("-DGIT_COMMIT_TAG=\"${GIT_COMMIT_TAG}\"")
# Compile options/flags
#-------------------------------------------------------------------------------
@@ -60,24 +72,27 @@ ExternalProject_Add(trower-base64
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/trower-base64
GIT_REPOSITORY https://github.com/Comcast/trower-base64.git
GIT_TAG "master"
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR}
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} -DBUILD_TESTING=OFF
)
add_library(libtrower-base64 STATIC SHARED IMPORTED)
add_dependencies(libtrower-base64 trower-base64)
# libwebsocket external dependency
# nopoll external dependency
#-------------------------------------------------------------------------------
set(PATCHES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/patches)
ExternalProject_Add(lws
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/lws
GIT_REPOSITORY https://github.com/warmcat/libwebsockets.git
GIT_TAG "ed92b6dfe75ad65a78dadfa4dc96da4568d95d69"
PATCH_COMMAND patch -p1 < ${PATCHES_DIR}/lws.patch
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR}
-DCMAKE_BUILD_TYPE=DEBUG
ExternalProject_Add(nopoll
PREFIX ${PREFIX_DIR}/nopoll
GIT_REPOSITORY https://github.com/Comcast/nopoll.git
GIT_TAG "18e83e32bfccd1f308b4df0fe0aa3565302903a4"
CONFIGURE_COMMAND COMMAND <SOURCE_DIR>/autogen.sh --prefix=${PREFIX}
--includedir=${INCLUDE_DIR}
--libdir=${LIBRARY_DIR}
${CUSTOM_HOST}
BUILD_IN_SOURCE 1
)
add_library(libwebsockets STATIC SHARED IMPORTED)
add_dependencies(libwebsockets lws)
add_library(libnopoll STATIC SHARED IMPORTED)
add_dependencies(libnopoll nopoll)
# nanoMsg external dependency
#-------------------------------------------------------------------------------
@@ -98,7 +113,7 @@ ExternalProject_Add(cJSON
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/cJSON
GIT_REPOSITORY https://github.com/DaveGamble/cJSON.git
GIT_TAG "aafb64a1c549b7b927e339df6d35b1d5059dc235"
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR}
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} -DBUILD_TESTING=OFF
)
add_library(libcJSON STATIC SHARED IMPORTED)
add_dependencies(libcJSON cJSON)
@@ -109,7 +124,7 @@ add_dependencies(libcJSON cJSON)
ExternalProject_Add(msgpack
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/msgpack
GIT_REPOSITORY https://github.com/msgpack/msgpack-c.git
GIT_TAG "c6e6dbc608366090c12b142b3832604e6aa12f54"
GIT_TAG "7a98138f27f27290e680bf8fbf1f8d1b089bf138"
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR}
-DMSGPACK_ENABLE_CXX=OFF
-DMSGPACK_BUILD_EXAMPLES=OFF
@@ -124,7 +139,7 @@ ExternalProject_Add(cimplog
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/cimplog
GIT_REPOSITORY https://github.com/Comcast/cimplog.git
GIT_TAG "master"
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR}
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} -DBUILD_TESTING=OFF
)
add_library(libcimplog STATIC SHARED IMPORTED)
add_dependencies(libcimplog cimplog)
@@ -155,7 +170,7 @@ ExternalProject_Add(libparodus
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/libparodus
GIT_REPOSITORY https://github.com/Comcast/libparodus.git
GIT_TAG "master"
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR}
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} -DBUILD_TESTING=OFF
-DMAIN_PROJ_BUILD=ON
-DMAIN_PROJ_LIB_PATH=${LIBRARY_DIR}
-DMAIN_PROJ_LIB64_PATH=${LIBRARY_DIR64}
@@ -165,13 +180,14 @@ ExternalProject_Add(libparodus
add_library(liblibparodus STATIC SHARED IMPORTED)
add_dependencies(liblibparodus libparodus)
if (ENABLE_SESHAT)
# libseshat external dependency
#-------------------------------------------------------------------------------
ExternalProject_Add(libseshat
DEPENDS cJSON trower-base64 msgpack wrp-c
DEPENDS cJSON trower-base64 msgpack nanomsg wrp-c
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/libseshat
GIT_REPOSITORY https://github.com/comcast/seshat.git
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR}
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} -DBUILD_TESTING=OFF
-DMAIN_PROJ_BUILD=ON
-DMAIN_PROJ_LIB_PATH=${LIBRARY_DIR}
-DMAIN_PROJ_LIB64_PATH=${LIBRARY_DIR64}
@@ -180,13 +196,45 @@ ExternalProject_Add(libseshat
)
add_library(liblibseshat STATIC SHARED IMPORTED)
add_dependencies(liblibseshat libseshat)
include_directories(${INCLUDE_DIR}/libseshat)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DENABLE_SESHAT ")
endif (ENABLE_SESHAT)
# libcjwt external dependency
#-------------------------------------------------------------------------------
ExternalProject_Add(cjwt
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/cjwt
GIT_REPOSITORY https://github.com/Comcast/cjwt.git
GIT_TAG "master"
#GIT_TAG "abd4376ff56212d16f69e850a64f6e095857ca39"
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} -DBUILD_TESTING=OFF
)
add_library(libcjwt STATIC SHARED IMPORTED)
add_dependencies(libcjwt cjwt)
if (FEATURE_DNS_QUERY)
# libucresolv external dependency
#-------------------------------------------------------------------------------
ExternalProject_Add(ucresolv
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/ucresolv
GIT_REPOSITORY https://github.com/Comcast/libucresolv.git
GIT_TAG "master"
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR}
)
add_library(libucresolv STATIC SHARED IMPORTED)
add_dependencies(libucresolv ucresolv)
include_directories(${INCLUDE_DIR}
${INCLUDE_DIR}/ucresolv
)
endif (FEATURE_DNS_QUERY)
if (BUILD_TESTING)
# cmocka external dependency
#-------------------------------------------------------------------------------
ExternalProject_Add(cmocka
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/cmocka
GIT_REPOSITORY https://git.cryptomilk.org/projects/cmocka.git
GIT_REPOSITORY https://github.com/elventear/cmocka.git
GIT_TAG "master"
CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR}
)
@@ -195,7 +243,15 @@ add_dependencies(libcmocka cmocka)
endif (BUILD_TESTING)
endif ()
endif () # NOT BUILD_YOCTO
if (BUILD_YOCTO)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DBUILD_YOCTO ")
endif (BUILD_YOCTO)
if (FEATURE_DNS_QUERY)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFEATURE_DNS_QUERY ")
endif (FEATURE_DNS_QUERY)
link_directories ( ${LIBRARY_DIR} ${COMMON_LIBRARY_DIR} ${LIBRARY_DIR64} )
add_subdirectory(src)

View File

@@ -1,5 +1,31 @@
If you would like to contribute code to this project you can do so
through GitHub by forking the repository and sending a pull request.
Contribution Guidelines
=======================
Before Comcast accepts your code into the project you must sign the
Comcast Contributor License Agreement ('CLA.pdf').
We love to see contributions to the project and have tried to make it easy to do so. If you would like to contribute code to this project you can do so through GitHub by forking the repository and sending a pull request.
Before Comcast merges your code into the project you must sign the [Comcast Contributor License Agreement (CLA)](https://gist.github.com/ComcastOSS/a7b8933dd8e368535378cda25c92d19a).
If you haven't previously signed a Comcast CLA, you'll automatically be asked to when you open a pull request. Alternatively, we can e-mail you a PDF that you can sign and scan back to us. Please send us an e-mail or create a new GitHub issue to request a PDF version of the CLA.
For more details about contributing to GitHub projects see
http://gun.io/blog/how-to-github-fork-branch-and-pull-request/
Documentation
-------------
If you contribute anything that changes the behavior of the
application, document it in the [README](https://github.com/Comcast/parodus/blob/master/README.md) or [wiki](https://github.com/Comcast/parodus/wiki)! This includes new features, additional variants of behavior and breaking changes.
Testing
-------
Tests are written using golang's standard testing tools, and are run prior to the PR being accepted.
Pull Requests
-------------
* should be narrowly focused with no more than 3 or 4 logical commits
* when possible, address no more than one issue
* should be reviewable in the GitHub code review tool
* should be linked to any issues it relates to (i.e. issue number after (#) in commit messages or pull request message)
* should conform to idiomatic golang code formatting

16
NOTICE Normal file
View File

@@ -0,0 +1,16 @@
parodus
Copyright 2017 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.
This product includes software developed at Comcast (http://www.comcast.com/).

View File

@@ -15,3 +15,77 @@ cmake ..
make
make test
```
# Command line Arguments needed to start parodus
```
- /hw-model -The hardware model name.
- /hw-serial-number -The serial number.
- /hw-manufacturer -The device manufacturer.
- /hw-mac -The MAC address used to manage the device.
- /hw-last-reboot-reason -The last known reboot reason.
- /fw-name -The firmware name.
- /boot-time -The boot time in unix time.
- /webpa-url -The URL that the WRP client should reach out to. (required). Must begin with 'https://' or 'http://'. May end with a port number. If no port specified, then 443 is assumed for https, 80 for http.
- /webpa-backoff-max -The maximum value of c in the binary backoff algorithm
- /webpa-ping-timeout -The maximum time to wait between pings before assuming the connection is broken.
- /webpa-interface-used -The device interface being used to connect to the cloud.
- /parodus-local-url -Parodus local server url (optional argument)
- /partner-id - Partner ID of broadband gateway (optional argument)
- /ssl-cert-path -Provide the certs for establishing secure connection (optional argument)
- /force-ipv4 -Forcefully connect parodus to ipv4 address (optional argument)
- /force-ipv6 -Forcefully connect parodus to ipv6 address (optional argument)
- /token-read-script -Script to get webpa auth token for establishing secure connection (absolute path where that script is present) -optional argument
- /token-acquisition-script -Script to create new auth token for establishing secure connection (absolute path where that script is present) -optional argument
# if ENABLE_SESHAT is enabled
- /seshat-url - The seshat server url
# if FEATURE_DNS_QUERY is enabled then below mentioned arguments are needed
- /acquire-jwt - this parameter (0 or 1) specifies whether there will be a dns lookup. If not, or if any problem occurs with the dns lookup, then webpa-url will be the target.
- /dns-txt-url - this parameter is used along with the hw_mac parameter to create the dns txt record id
- /jwt-algo -Allowed algorithm used for communication
- /jwt-public-key-file -JWT token validation key
```
# Sample parodus start commands:
```
# Seshat & FEATURE_DNS_QUERY Enabled
./parodus --hw-model=TGXXX --hw-serial-number=E8GBUEXXXXXXXXX --hw-manufacturer=ARRIS --hw-mac=14cfexxxxxxx --hw-last-reboot-reason=unknown --fw-name=TG1682_DEV_master_20170512115046sdy --boot-time=1494590301 --webpa-ping-timeout=180 --webpa-interface-used=eth0 --webpa-url=somebody.net:8080 --webpa-backoff-max=9 --parodus-local-url=tcp://127.0.0.1:6666 --partner-id=comcast --ssl-cert-path=/etc/ssl/certs/ca-certificates.crt --acquire-jwt=1 --dns-txt-url=somebody.net --jwt-public-key-file=webpa-rs256.pem --jwt-algo=RS256 --seshat-url=tcp://127.0.0.1:7777 --token-read-script=/usr/ccsp/parodus/parodus_token1.sh --token-acquisition-script=/usr/ccsp/parodus/parodus_token2.sh --force-ipv4
# Seshat is not enabled
./parodus --hw-model=TGXXX --hw-serial-number=E8GBUEXXXXXXXXX --hw-manufacturer=ARRIS --hw-mac=14cfexxxxxxx --hw-last-reboot-reason=unknown --fw-name=TG1682_DEV_master_20170512115046sdy --boot-time=1494590301 --webpa-ping-timeout=180 --webpa-interface-used=eth0 --webpa-url=somebody.net:8080 --webpa-backoff-max=9 --parodus-local-url=tcp://127.0.0.1:6666 --partner-id=comcast --ssl-cert-path=/etc/ssl/certs/ca-certificates.crt --acquire-jwt=1 --dns-txt-url=somebody.net --jwt-public-key-file=webpa-rs256.pem --jwt-algo=RS256 --token-read-script=/usr/ccsp/parodus/parodus_token1.sh --token-acquisition-script=/usr/ccsp/parodus/parodus_token2.sh --force-ipv4
# When both Seshat & FEATURE_DNS_QUERY not Enabled
./parodus --hw-model=TGXXX --hw-serial-number=E8GBUEXXXXXXXXX --hw-manufacturer=ARRIS --hw-mac=14cfexxxxxxx --hw-last-reboot-reason=unknown --fw-name=TG1682_DEV_master_20170512115046sdy --boot-time=1494590301 --webpa-ping-timeout=180 --webpa-interface-used=eth0 --webpa-url=somebody.net:8080 --webpa-backoff-max=9 --parodus-local-url=tcp://127.0.0.1:6666 --partner-id=comcast --ssl-cert-path=/etc/ssl/certs/ca-certificates.crt --token-read-script=/usr/ccsp/parodus/parodus_token1.sh --token-acquisition-script=/usr/ccsp/parodus/parodus_token2.sh --force-ipv4
```

View File

@@ -1,57 +0,0 @@
diff --git a/lib/client-parser.c b/lib/client-parser.c
index b979c62..79b25be 100644
--- a/lib/client-parser.c
+++ b/lib/client-parser.c
@@ -439,6 +439,7 @@ spill:
/* get it sent as soon as possible */
lws_callback_on_writable(wsi);
+ callback_action = LWS_CALLBACK_CLIENT_RECEIVE_PING;
ping_drop:
wsi->u.ws.rx_ubuf_head = 0;
handled = 1;
@@ -494,7 +495,7 @@ ping_drop:
* It's nicely buffered with the pre-padding taken care of
* so it can be sent straight out again using lws_write
*/
- if (handled)
+ if (handled && callback_action != LWS_CALLBACK_CLIENT_RECEIVE_PING)
goto already_done;
eff_buf.token = &wsi->u.ws.rx_ubuf[LWS_PRE];
@@ -533,7 +534,7 @@ utf8_fail: lwsl_info("utf8 error\n");
}
if (eff_buf.token_len < 0 &&
- callback_action != LWS_CALLBACK_CLIENT_RECEIVE_PONG)
+ callback_action != LWS_CALLBACK_CLIENT_RECEIVE_PONG && callback_action != LWS_CALLBACK_CLIENT_RECEIVE_PING)
goto already_done;
if (!eff_buf.token)
diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h
index 23d6588..2081b0a 100644
--- a/lib/libwebsockets.h
+++ b/lib/libwebsockets.h
@@ -1235,6 +1235,8 @@ enum lws_callback_reasons {
/**< RAW mode file is writeable */
LWS_CALLBACK_RAW_CLOSE_FILE = 66,
/**< RAW mode wsi that adopted a file is closing */
+ LWS_CALLBACK_CLIENT_RECEIVE_PING = 67,
+ /**< clients receive PING packets with this callback reason */
/****** add new things just above ---^ ******/
diff --git a/lib/ssl.c b/lib/ssl.c
index 651757f..d928afc 100644
--- a/lib/ssl.c
+++ b/lib/ssl.c
@@ -378,6 +378,9 @@ lws_ssl_capable_read(struct lws *wsi, unsigned char *buf, int len)
lwsl_debug("%p: SSL_read says %d\n", wsi, n);
/* manpage: returning 0 means connection shut down */
if (!n) {
+ /* Setting close reason for SSL socket close from server */
+ wsi->vhost->protocols->callback(wsi, LWS_CALLBACK_WS_PEER_INITIATED_CLOSE,
+ wsi->user_space, "SSL_Socket_Close", 16 );
n = lws_ssl_get_error(wsi, n);
lwsl_debug("%p: ssl err %d errno %d\n", wsi, n, errno);
if (n == SSL_ERROR_ZERO_RETURN)

View File

@@ -11,8 +11,17 @@
# 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.
set(SOURCES main.c lws_handlers.c ParodusInternal.c
string_helpers.c time.c config.c conn_interface.c connection.c spin_thread.c client_list.c service_alive.c upstream.c downstream.c thread_tasks.c partners_check.c)
set(SOURCES main.c mutex.c networking.c nopoll_helpers.c nopoll_handlers.c
ParodusInternal.c string_helpers.c time.c config.c conn_interface.c
connection.c spin_thread.c client_list.c service_alive.c
upstream.c downstream.c thread_tasks.c partners_check.c token.c)
if (ENABLE_SESHAT)
set(SOURCES ${SOURCES} seshat_interface.c)
else()
set(SOURCES ${SOURCES} seshat_interface_stub.c)
endif (ENABLE_SESHAT)
add_executable(parodus ${SOURCES})
@@ -21,7 +30,7 @@ target_link_libraries (parodus
-lwrp-c
-lmsgpackc
-ltrower-base64
-llibseshat
-lnopoll
-luuid
-lm
-lcimplog
@@ -29,8 +38,18 @@ target_link_libraries (parodus
-lcrypto
-lnanomsg
-lcjson
-lcjwt
-lpthread
-lrt
-lwebsockets
)
if (FEATURE_DNS_QUERY)
target_link_libraries (parodus -lucresolv -lresolv)
endif (FEATURE_DNS_QUERY)
if (ENABLE_SESHAT)
target_link_libraries (parodus -llibseshat)
endif (ENABLE_SESHAT)
install (TARGETS parodus DESTINATION bin)

View File

@@ -1,9 +1,24 @@
/**
* Copyright 2015 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 ParodusInternal.c
*
* @description This file is used to manage internal functions of parodus
*
* Copyright (c) 2015 Comcast
*/
#include "ParodusInternal.h"
@@ -72,9 +87,14 @@ 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);
if(lws_b64_encode_string (buffer, strlen(buffer), encodedData, encodedDataSize) < 0)
if(nopoll_base64_encode (buffer, strlen(buffer), encodedData, &encodedDataSize) != nopoll_true)
{
ParodusError("Base64 Encoding failed for Connection Header\n");
}
@@ -98,5 +118,10 @@ char* getWebpaConveyHeader()
}
free(buffer);
cJSON_Delete(response);
return encodedData;
if( 0 < strlen(encodedData) ) {
return encodedData;
}
return NULL;
}

View File

@@ -1,9 +1,24 @@
/**
* Copyright 2015 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 ParodusInternal.h
*
* @description This file is used to manage internal functions of parodus
*
* Copyright (c) 2015 Comcast
*/
#ifndef _PARODUSINTERNAL_H_
#define _PARODUSINTERNAL_H_
@@ -25,10 +40,10 @@
#include <sys/wait.h>
#include <cJSON.h>
#include <nopoll.h>
#include <nanomsg/nn.h>
#include <nanomsg/pipeline.h>
#include <wrp-c.h>
#include <libwebsockets.h>
#include "parodus_log.h"
/*----------------------------------------------------------------------------*/
@@ -50,11 +65,18 @@ extern int numLoops;
typedef struct ParodusMsg__
{
noPollMsg * msg;
void * payload;
size_t len;
struct ParodusMsg__ *next;
} ParodusMsg;
// Used in token.c to get jwt from dns server
typedef struct {
const char *rr_ptr;
int rr_len;
} rr_rec_t;
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
@@ -69,6 +91,8 @@ int numLoops;
extern "C" {
#endif
int checkHostIp(char * serverIP);
void parStrncpy(char *destStr, const char *srcStr, size_t destSize);
char* getWebpaConveyHeader();

View File

@@ -1,9 +1,24 @@
/**
* Copyright 2015 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 client_list.h
*
* @description This file is used to manage registered clients
*
* Copyright (c) 2015 Comcast
*/
#include "ParodusInternal.h"
@@ -69,9 +84,8 @@ int addToList( wrp_msg_t **msg)
ParodusPrint("(*msg)->u.reg.service_name is %s\n", (*msg)->u.reg.service_name);
ParodusPrint("(*msg)->u.reg.url is %s\n", (*msg)->u.reg.url);
strncpy(new_node->service_name, (*msg)->u.reg.service_name, strlen((*msg)->u.reg.service_name)+1);
strncpy(new_node->url, (*msg)->u.reg.url, strlen((*msg)->u.reg.url)+1);
parStrncpy(new_node->service_name, (*msg)->u.reg.service_name, sizeof(new_node->service_name));
parStrncpy(new_node->url, (*msg)->u.reg.url, sizeof(new_node->url));
new_node->next=NULL;
if (g_head == NULL) //adding first client

View File

@@ -1,9 +1,24 @@
/**
* Copyright 2015 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 client_list.h
*
* @description This file is used to manage registered clients
*
* Copyright (c) 2015 Comcast
*/
#ifndef _CLIENTLIST_H_
#define _CLIENTLIST_H_

View File

@@ -1,19 +1,41 @@
/**
* @file config.h
* Copyright 2015 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 config.c
*
* @description This file contains configuration details of parodus
*
* Copyright (c) 2015 Comcast
*/
#include <stdio.h>
#include <fcntl.h>
#include "config.h"
#include "ParodusInternal.h"
#include <cjwt/cjwt.h>
#define MAX_BUF_SIZE 128
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
static ParodusCfg parodusCfg;
static unsigned int rsa_algorithms =
(1<<alg_rs256) | (1<<alg_rs384) | (1<<alg_rs512);
/*----------------------------------------------------------------------------*/
/* External Functions */
@@ -26,35 +48,274 @@ ParodusCfg *get_parodus_cfg(void)
void set_parodus_cfg(ParodusCfg *cfg)
{
parodusCfg = *cfg;
memcpy(&parodusCfg, cfg, sizeof(ParodusCfg));
}
void parseCommandLine(int argc,char **argv,ParodusCfg * cfg)
{
int c;
static void execute_token_script(char *token, char *name, size_t len, char *mac, char *serNum);
const char *get_tok (const char *src, int delim, char *result, int resultsize)
{
int i;
char c;
int endx = resultsize-1;
memset (result, 0, resultsize);
for (i=0; (c=src[i]) != 0; i++) {
if (c == delim)
break;
if (i < endx)
result[i] = c;
}
if (c == 0)
return NULL;
return src + i + 1;
}
// the algorithm mask indicates which algorithms are allowed
unsigned int get_algo_mask (const char *algo_str)
{
unsigned int mask = 0;
unsigned int mask_val;
#define BUFLEN 16
char tok[BUFLEN];
int alg_val;
while(NULL != algo_str)
{
algo_str = get_tok (algo_str, ':', tok, BUFLEN);
alg_val = cjwt_alg_str_to_enum (tok);
if ((alg_val < 0) || (alg_val >= num_algorithms)) {
ParodusError("Invalid jwt algorithm %s\n", tok);
return (unsigned int) (-1);
}
if (alg_val == alg_none) {
ParodusError("Disallowed jwt algorithm none\n");
return (unsigned int) (-1);
}
mask_val = (1<<alg_val);
#if !ALLOW_NON_RSA_ALG
if (0 == (mask_val & rsa_algorithms)) {
ParodusError("Disallowed non-rsa jwt algorithm %s\n", tok);
return (unsigned int) (-1);
}
#endif
mask |= mask_val;
}
return mask;
#undef BUFLEN
}
static int open_input_file (const char *fname)
{
int fd = open(fname, O_RDONLY);
if (fd<0)
{
ParodusError ("File %s open error\n", fname);
abort ();
}
return fd;
}
void read_key_from_file (const char *fname, char *buf, size_t buflen)
{
ssize_t nbytes;
int fd = open_input_file(fname);
nbytes = read(fd, buf, buflen);
if (nbytes < 0)
{
ParodusError ("Read file %s error\n", fname);
close(fd);
abort ();
}
close(fd);
ParodusInfo ("%d bytes read\n", nbytes);
}
static 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'};
if(strlen(name)>0)
{
file = fopen(name, "r");
if(file)
{
snprintf(command,sizeof(command),"%s %s %s",name,serNum,mac);
out = popen(command, "r");
if(out)
{
fgets(token, len, out);
pclose(out);
}
fclose(file);
}
else
{
ParodusError ("File %s open error\n", name);
}
}
}
// strips ':' characters
// verifies that there exactly 12 characters
int parse_mac_address (char *target, const char *arg)
{
int count = 0;
int i;
char c;
for (i=0; (c=arg[i]) != 0; i++) {
if (c !=':')
count++;
}
if (count != 12)
return -1; // bad mac address
for (i=0; (c=arg[i]) != 0; i++) {
if (c != ':')
*(target++) = c;
}
*target = 0; // terminating null
return 0;
}
int server_is_http (const char *full_url,
const char **server_ptr)
{
int http_match;
const char *ptr;
if (strncmp(full_url, "https://", 8) == 0) {
http_match = 0;
ptr = full_url + 8;
} else if (strncmp(full_url, "http://", 7) == 0) {
http_match = 1;
ptr = full_url + 7;
} else {
ParodusError ("Invalid url %s\n", full_url);
return -1;
}
if (NULL != server_ptr)
*server_ptr = ptr;
return http_match;
}
int parse_webpa_url(const char *full_url,
char *server_addr, int server_addr_buflen,
char *port_buf, int port_buflen)
{
const char *server_ptr;
char *port_val;
char *end_port;
size_t server_len;
int http_match;
ParodusInfo ("full url: %s\n", full_url);
http_match = server_is_http (full_url, &server_ptr);
if (http_match < 0)
return http_match;
ParodusInfo ("server address copied from url\n");
parStrncpy (server_addr, server_ptr, server_addr_buflen);
server_len = strlen(server_addr);
// If there's a '/' on end, null it out
if ((server_len>0) && (server_addr[server_len-1] == '/'))
server_addr[server_len-1] = '\0';
// Look for ':'
port_val = strchr (server_addr, ':');
if (NULL == port_val) {
if (http_match)
parStrncpy (port_buf, "80", port_buflen);
else
parStrncpy (port_buf, "443", port_buflen);
} else {
*port_val = '\0'; // terminate server address with null
port_val++;
end_port = strchr (port_val, '/');
if (NULL != end_port)
*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;
}
unsigned int parse_num_arg (const char *arg, const char *arg_name)
{
unsigned int result = 0;
int i;
char c;
if (arg[0] == '\0') {
ParodusError ("Empty %s argument\n", arg_name);
return (unsigned int) -1;
}
for (i=0; '\0' != (c=arg[i]); i++)
{
if ((c<'0') || (c>'9')) {
ParodusError ("Non-numeric %s argument\n", arg_name);
return (unsigned int) -1;
}
result = (result*10) + c - '0';
}
return result;
}
int parseCommandLine(int argc,char **argv,ParodusCfg * cfg)
{
static const struct option long_options[] = {
{"hw-model", required_argument, 0, 'm'},
{"hw-serial-number", required_argument, 0, 's'},
{"hw-manufacturer", required_argument, 0, 'f'},
{"hw-mac", required_argument, 0, 'd'},
{"hw-last-reboot-reason", required_argument, 0, 'r'},
{"fw-name", required_argument, 0, 'n'},
{"boot-time", required_argument, 0, 'b'},
{"webpa-url", required_argument, 0, 'u'},
{"webpa-ping-timeout", required_argument, 0, 't'},
{"webpa-backoff-max", required_argument, 0, 'o'},
{"webpa-interface-used", required_argument, 0, 'i'},
{"parodus-local-url", required_argument, 0, 'l'},
{"partner-id", required_argument, 0, 'p'},
#ifdef ENABLE_SESHAT
{"seshat-url", required_argument, 0, 'e'},
#endif
{"dns-txt-url", required_argument, 0, 'D'},
{"acquire-jwt", required_argument, 0, 'j'},
{"jwt-algo", required_argument, 0, 'a'},
{"jwt-public-key-file", required_argument, 0, 'k'},
{"ssl-cert-path", required_argument, 0, 'c'},
{"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'},
{0, 0, 0, 0}
};
int c;
ParodusInfo("Parsing parodus command line arguments..\n");
if (NULL == cfg) {
ParodusError ("NULL cfg structure\n");
return -1;
}
cfg->flags = 0;
parStrncpy (cfg->webpa_url, "", sizeof(cfg->webpa_url));
cfg->acquire_jwt = 0;
cfg->jwt_algo = 0;
parStrncpy (cfg->jwt_key, "", sizeof(cfg->jwt_key));
optind = 1; /* We need this if parseCommandLine is called again */
while (1)
{
static struct option long_options[] = {
{"hw-model", required_argument, 0, 'm'},
{"hw-serial-number", required_argument, 0, 's'},
{"hw-manufacturer", required_argument, 0, 'f'},
{"hw-mac", required_argument, 0, 'd'},
{"hw-last-reboot-reason", required_argument, 0, 'r'},
{"fw-name", required_argument, 0, 'n'},
{"boot-time", required_argument, 0, 'b'},
{"webpa-url", required_argument, 0, 'u'},
{"webpa-ping-timeout", required_argument, 0, 't'},
{"webpa-backoff-max", required_argument, 0, 'o'},
{"webpa-inteface-used", required_argument, 0, 'i'},
{"parodus-local-url", required_argument, 0, 'l'},
{"partner-id", required_argument, 0, 'p'},
{"seshat-url", required_argument, 0, 'e'},
{0, 0, 0, 0}
};
/* 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:",long_options, &option_index);
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",
long_options, &option_index);
/* Detect the end of the options. */
if (c == -1)
@@ -78,15 +339,19 @@ void parseCommandLine(int argc,char **argv,ParodusCfg * cfg)
break;
case 'd':
parStrncpy(cfg->hw_mac, optarg,sizeof(cfg->hw_mac));
ParodusInfo("hw_mac is %s\n",cfg->hw_mac);
if (parse_mac_address (cfg->hw_mac, optarg) == 0) {
ParodusInfo ("hw_mac is %s\n",cfg->hw_mac);
} else {
ParodusError ("Bad mac address %s\n", optarg);
return -1;
}
break;
#ifdef ENABLE_SESHAT
case 'e':
parStrncpy(cfg->seshat_url, optarg,sizeof(cfg->seshat_url));
ParodusInfo("seshat_url is %s\n",cfg->seshat_url);
break;
#endif
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);
@@ -98,50 +363,131 @@ void parseCommandLine(int argc,char **argv,ParodusCfg * cfg)
break;
case 'b':
cfg->boot_time = atoi(optarg);
cfg->boot_time = parse_num_arg (optarg, "boot-time");
ParodusInfo("boot_time is %d\n",cfg->boot_time);
break;
case 'u':
parStrncpy(cfg->webpa_url, optarg,sizeof(cfg->webpa_url));
parStrncpy(cfg->webpa_url, optarg,sizeof(cfg->webpa_url));
if (server_is_http (cfg->webpa_url, NULL) < 0) {
ParodusError ("Bad webpa url %s\n", optarg);
return -1;
}
ParodusInfo("webpa_url is %s\n",cfg->webpa_url);
break;
case 't':
cfg->webpa_ping_timeout = atoi(optarg);
cfg->webpa_ping_timeout = parse_num_arg (optarg, "webpa-ping-timeout");
if (cfg->webpa_ping_timeout == (unsigned int) -1)
return -1;
ParodusInfo("webpa_ping_timeout is %d\n",cfg->webpa_ping_timeout);
break;
case 'o':
cfg->webpa_backoff_max = atoi(optarg);
cfg->webpa_backoff_max = parse_num_arg (optarg, "webpa-backoff-max");
if (cfg->webpa_backoff_max == (unsigned int) -1)
return -1;
ParodusInfo("webpa_backoff_max is %d\n",cfg->webpa_backoff_max);
break;
case 'i':
parStrncpy(cfg->webpa_interface_used, optarg,sizeof(cfg->webpa_interface_used));
ParodusInfo("webpa_inteface_used is %s\n",cfg->webpa_interface_used);
ParodusInfo("webpa_interface_used is %s\n",cfg->webpa_interface_used);
break;
case 'l':
parStrncpy(cfg->local_url, optarg,sizeof(cfg->local_url));
ParodusInfo("parodus local_url is %s\n",cfg->local_url);
break;
case 'D':
// like 'fabric' or 'test'
// this parameter is used, along with the hw_mac parameter
// to create the dns txt record id
parStrncpy(cfg->dns_txt_url, optarg,sizeof(cfg->dns_txt_url));
ParodusInfo("parodus dns-txt-url is %s\n",cfg->dns_txt_url);
break;
case 'j':
cfg->acquire_jwt = parse_num_arg (optarg, "acquire-jwt");
if (cfg->acquire_jwt == (unsigned int) -1)
return -1;
ParodusInfo("acquire jwt option is %d\n",cfg->acquire_jwt);
break;
case 'a':
// the command line argument is a list of allowed algoritms,
// separated by colons, like "RS256:RS512:none"
cfg->jwt_algo = get_algo_mask (optarg);
if (cfg->jwt_algo == (unsigned int) -1) {
return -1;
}
ParodusInfo("jwt_algo is %u\n",cfg->jwt_algo);
break;
case 'k':
read_key_from_file (optarg, cfg->jwt_key, sizeof(cfg->jwt_key));
ParodusInfo("jwt_key is %s\n",cfg->jwt_key);
break;
case 'p':
parStrncpy(cfg->partner_id, optarg,sizeof(cfg->partner_id));
ParodusInfo("partner_id is %s\n",cfg->partner_id);
break;
case 'c':
parStrncpy(cfg->cert_path, optarg,sizeof(cfg->cert_path));
ParodusInfo("cert_path is %s\n",cfg->cert_path);
break;
case '4':
ParodusInfo("Force IPv4\n");
cfg->flags |= FLAGS_IPV4_ONLY;
break;
case '6':
ParodusInfo("Force IPv6\n");
cfg->flags |= FLAGS_IPV6_ONLY;
break;
case 'J':
parStrncpy(cfg->token_acquisition_script, optarg,sizeof(cfg->token_acquisition_script));
break;
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 '?':
/* getopt_long already printed an error message. */
break;
default:
ParodusError("Enter Valid commands..\n");
abort ();
return -1;
}
}
if (0 == strlen (cfg->webpa_url)) {
ParodusError ("Missing webpa url argument\n");
return -1;
}
if (cfg->acquire_jwt) {
if (0 == cfg->jwt_algo) {
ParodusError ("Missing jwt algorithm argument\n");
return -1;
}
if ((0 != (cfg->jwt_algo & rsa_algorithms)) &&
(0 == strlen (cfg->jwt_key)) ) {
ParodusError ("Missing jwt public key file argument\n");
return -1;
}
}
ParodusPrint("argc is :%d\n", argc);
ParodusPrint("optind is :%d\n", optind);
@@ -153,6 +499,98 @@ void parseCommandLine(int argc,char **argv,ParodusCfg * cfg)
ParodusPrint ("%s ", argv[optind++]);
putchar ('\n');
}
return 0;
}
/*
* call parodus create/acquisition script to create new auth token, if success then calls
* execute_token_script func with args as parodus read script.
*/
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)
{
//Call read script
execute_token_script(newToken,get_parodus_cfg()->token_read_script,len,get_parodus_cfg()->hw_mac,get_parodus_cfg()->hw_serial_number);
}
else
{
ParodusError("Failed to create new token\n");
}
}
/*
* Fetches authorization token from the output of read script. If read script returns "ERROR"
* it will call createNewAuthToken to create and read new token
*/
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);
if ((strlen(output) == 0))
{
ParodusError("Unable to get auth token\n");
}
else if(strcmp(output,"ERROR")==0)
{
ParodusInfo("Failed to read token from %s. Proceeding to create new token.\n",cfg->token_read_script);
//Call create/acquisition script
createNewAuthToken(cfg->webpa_auth_token, sizeof(cfg->webpa_auth_token));
}
else
{
ParodusInfo("update cfg->webpa_auth_token in success case\n");
parStrncpy(cfg->webpa_auth_token, output, sizeof(cfg->webpa_auth_token));
}
}
else
{
ParodusInfo("Both read and write file are NULL \n");
}
}
void setDefaultValuesToCfg(ParodusCfg *cfg)
{
if(cfg == NULL)
{
ParodusError("cfg is NULL\n");
return;
}
ParodusInfo("Setting default values to parodusCfg\n");
parStrncpy(cfg->local_url, PARODUS_UPSTREAM, sizeof(cfg->local_url));
cfg->acquire_jwt = 0;
parStrncpy(cfg->dns_txt_url, DNS_TXT_URL, sizeof(cfg->dns_txt_url));
parStrncpy(cfg->jwt_key, "\0", sizeof(cfg->jwt_key));
cfg->jwt_algo = 0;
parStrncpy(cfg->cert_path, "\0", sizeof(cfg->cert_path));
cfg->flags = 0;
parStrncpy(cfg->webpa_path_url, WEBPA_PATH_URL,sizeof(cfg->webpa_path_url));
snprintf(cfg->webpa_protocol, sizeof(cfg->webpa_protocol), "%s-%s", PROTOCOL_VALUE, GIT_COMMIT_TAG);
ParodusInfo(" cfg->webpa_protocol is %s\n", cfg->webpa_protocol);
parStrncpy(cfg->webpa_uuid, "1234567-345456546",sizeof(cfg->webpa_uuid));
ParodusPrint("cfg->webpa_uuid is :%s\n", cfg->webpa_uuid);
}
void loadParodusCfg(ParodusCfg * config,ParodusCfg *cfg)
@@ -163,109 +601,160 @@ void loadParodusCfg(ParodusCfg * config,ParodusCfg *cfg)
return;
}
ParodusCfg *pConfig =config;
if(strlen (pConfig->hw_model) !=0)
if(strlen (config->hw_model) !=0)
{
strncpy(cfg->hw_model, pConfig->hw_model,strlen(pConfig->hw_model)+1);
parStrncpy(cfg->hw_model, config->hw_model, sizeof(cfg->hw_model));
}
else
{
ParodusPrint("hw_model is NULL. read from tmp file\n");
}
if( strlen(pConfig->hw_serial_number) !=0)
if( strlen(config->hw_serial_number) !=0)
{
strncpy(cfg->hw_serial_number, pConfig->hw_serial_number,strlen(pConfig->hw_serial_number)+1);
parStrncpy(cfg->hw_serial_number, config->hw_serial_number, sizeof(cfg->hw_serial_number));
}
else
{
ParodusPrint("hw_serial_number is NULL. read from tmp file\n");
}
if(strlen(pConfig->hw_manufacturer) !=0)
if(strlen(config->hw_manufacturer) !=0)
{
strncpy(cfg->hw_manufacturer, pConfig->hw_manufacturer,strlen(pConfig->hw_manufacturer)+1);
parStrncpy(cfg->hw_manufacturer, config->hw_manufacturer,sizeof(cfg->hw_manufacturer));
}
else
{
ParodusPrint("hw_manufacturer is NULL. read from tmp file\n");
}
if(strlen(pConfig->hw_mac) !=0)
if(strlen(config->hw_mac) !=0)
{
strncpy(cfg->hw_mac, pConfig->hw_mac,strlen(pConfig->hw_mac)+1);
parStrncpy(cfg->hw_mac, config->hw_mac,sizeof(cfg->hw_mac));
}
else
{
ParodusPrint("hw_mac is NULL. read from tmp file\n");
}
if(strlen (pConfig->hw_last_reboot_reason) !=0)
if(strlen (config->hw_last_reboot_reason) !=0)
{
strncpy(cfg->hw_last_reboot_reason, pConfig->hw_last_reboot_reason,strlen(pConfig->hw_last_reboot_reason)+1);
parStrncpy(cfg->hw_last_reboot_reason, config->hw_last_reboot_reason,sizeof(cfg->hw_last_reboot_reason));
}
else
{
ParodusPrint("hw_last_reboot_reason is NULL. read from tmp file\n");
}
if(strlen(pConfig->fw_name) !=0)
if(strlen(config->fw_name) !=0)
{
strncpy(cfg->fw_name, pConfig->fw_name,strlen(pConfig->fw_name)+1);
parStrncpy(cfg->fw_name, config->fw_name,sizeof(cfg->fw_name));
}
else
{
ParodusPrint("fw_name is NULL. read from tmp file\n");
}
if( strlen(pConfig->webpa_url) !=0)
if( strlen(config->webpa_url) !=0)
{
strncpy(cfg->webpa_url, pConfig->webpa_url,strlen(pConfig->webpa_url)+1);
parStrncpy(cfg->webpa_url, config->webpa_url,sizeof(cfg->webpa_url));
}
else
{
ParodusPrint("webpa_url is NULL. read from tmp file\n");
}
if(strlen(pConfig->webpa_interface_used )!=0)
if(strlen(config->webpa_interface_used )!=0)
{
strncpy(cfg->webpa_interface_used, pConfig->webpa_interface_used,strlen(pConfig->webpa_interface_used)+1);
parStrncpy(cfg->webpa_interface_used, config->webpa_interface_used,sizeof(cfg->webpa_interface_used));
}
else
{
ParodusPrint("webpa_interface_used is NULL. read from tmp file\n");
}
if( strlen(pConfig->local_url) !=0)
if( strlen(config->local_url) !=0)
{
strncpy(cfg->local_url, pConfig->local_url,strlen(pConfig->local_url)+1);
parStrncpy(cfg->local_url, config->local_url,sizeof(cfg->local_url));
}
else
{
ParodusInfo("parodus local_url is NULL. adding default url\n");
strncpy(cfg->local_url, PARODUS_UPSTREAM, strlen(PARODUS_UPSTREAM)+1);
parStrncpy(cfg->local_url, PARODUS_UPSTREAM, sizeof(cfg->local_url));
}
if( strlen(pConfig->partner_id) !=0)
if( strlen(config->partner_id) !=0)
{
strncpy(cfg->partner_id, pConfig->partner_id,strlen(pConfig->partner_id)+1);
parStrncpy(cfg->partner_id, config->partner_id,sizeof(cfg->partner_id));
}
else
{
ParodusPrint("partner_id is NULL. read from tmp file\n");
}
if( strlen(pConfig->seshat_url) !=0)
#ifdef ENABLE_SESHAT
if( strlen(config->seshat_url) !=0)
{
strncpy(cfg->seshat_url, pConfig->seshat_url,strlen(pConfig->seshat_url)+1);
parStrncpy(cfg->seshat_url, config->seshat_url,sizeof(cfg->seshat_url));
}
else
{
ParodusInfo("seshat_url is NULL. Read from tmp file\n");
}
#endif
cfg->acquire_jwt = config->acquire_jwt;
if( strlen(config->dns_txt_url) !=0)
{
parStrncpy(cfg->dns_txt_url, config->dns_txt_url, sizeof(cfg->dns_txt_url));
}
else
{
ParodusInfo("parodus dns-txt-url is NULL. adding default\n");
parStrncpy(cfg->dns_txt_url, DNS_TXT_URL, sizeof(cfg->dns_txt_url));
}
cfg->boot_time = pConfig->boot_time;
cfg->secureFlag = 1;
cfg->webpa_ping_timeout = pConfig->webpa_ping_timeout;
cfg->webpa_backoff_max = pConfig->webpa_backoff_max;
strncpy(cfg->webpa_path_url, WEBPA_PATH_URL, strlen(WEBPA_PATH_URL)+1);
strncpy(cfg->webpa_protocol, WEBPA_PROTOCOL_VALUE, strlen(WEBPA_PROTOCOL_VALUE)+1);
strncpy(cfg->webpa_uuid, "1234567-345456546", strlen("1234567-345456546")+1);
if(strlen(config->jwt_key )!=0)
{
parStrncpy(cfg->jwt_key, config->jwt_key,sizeof(cfg->jwt_key));
}
else
{
parStrncpy(cfg->jwt_key, "\0", sizeof(cfg->jwt_key));
ParodusPrint("jwt_key is NULL. set to empty\n");
}
cfg->jwt_algo = config->jwt_algo;
if(strlen(config->cert_path )!=0)
{
parStrncpy(cfg->cert_path, config->cert_path,sizeof(cfg->cert_path));
}
else
{
parStrncpy(cfg->cert_path, "\0", sizeof(cfg->cert_path));
ParodusPrint("cert_path is NULL. set to empty\n");
}
if(strlen(config->token_acquisition_script )!=0)
{
parStrncpy(cfg->token_acquisition_script, config->token_acquisition_script,sizeof(cfg->token_acquisition_script));
}
else
{
ParodusPrint("token_acquisition_script is NULL. read from tmp file\n");
}
if(strlen(config->token_read_script )!=0)
{
parStrncpy(cfg->token_read_script, config->token_read_script,sizeof(cfg->token_read_script));
}
else
{
ParodusPrint("token_read_script is NULL. read from tmp file\n");
}
cfg->boot_time = config->boot_time;
cfg->webpa_ping_timeout = config->webpa_ping_timeout;
cfg->webpa_backoff_max = config->webpa_backoff_max;
parStrncpy(cfg->webpa_path_url, WEBPA_PATH_URL,sizeof(cfg->webpa_path_url));
snprintf(cfg->webpa_protocol, sizeof(cfg->webpa_protocol), "%s-%s", PROTOCOL_VALUE, GIT_COMMIT_TAG);
ParodusInfo("cfg->webpa_protocol is %s\n", cfg->webpa_protocol);
parStrncpy(cfg->webpa_uuid, "1234567-345456546",sizeof(cfg->webpa_uuid));
ParodusPrint("cfg->webpa_uuid is :%s\n", cfg->webpa_uuid);
}

View File

@@ -1,9 +1,24 @@
/**
* Copyright 2015 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 config.h
*
* @description This file contains configuration details of parodus
*
* Copyright (c) 2015 Comcast
*/
#ifndef _CONFIG_H_
@@ -18,25 +33,32 @@ extern "C" {
/*----------------------------------------------------------------------------*/
/* WRP CRUD Model Macros */
#define HW_MODELNAME "hw-model"
#define HW_SERIALNUMBER "hw-serial-number"
#define HW_MANUFACTURER "hw-manufacturer"
#define HW_DEVICEMAC "hw-mac"
#define HW_LAST_REBOOT_REASON "hw-last-reboot-reason"
#define FIRMWARE_NAME "fw-name"
#define BOOT_TIME "boot-time"
#define LAST_RECONNECT_REASON "webpa-last-reconnect-reason"
#define WEBPA_PROTOCOL "webpa-protocol"
#define WEBPA_INTERFACE "webpa-inteface-used"
#define WEBPA_UUID "webpa-uuid"
#define WEBPA_URL "webpa-url"
#define WEBPA_PING_TIMEOUT "webpa-ping-timeout"
#define WEBPA_BACKOFF_MAX "webpa-backoff-max"
#define PARTNER_ID "partner-id"
#define HW_MODELNAME "hw-model"
#define HW_SERIALNUMBER "hw-serial-number"
#define HW_MANUFACTURER "hw-manufacturer"
#define HW_DEVICEMAC "hw-mac"
#define HW_LAST_REBOOT_REASON "hw-last-reboot-reason"
#define FIRMWARE_NAME "fw-name"
#define BOOT_TIME "boot-time"
#define LAST_RECONNECT_REASON "webpa-last-reconnect-reason"
#define WEBPA_PROTOCOL "webpa-protocol"
#define WEBPA_INTERFACE "webpa-inteface-used"
#define WEBPA_UUID "webpa-uuid"
#define WEBPA_URL "webpa-url"
#define WEBPA_PING_TIMEOUT "webpa-ping-timeout"
#define WEBPA_BACKOFF_MAX "webpa-backoff-max"
#define PARTNER_ID "partner-id"
#define CERT_PATH "ssl-cert-path"
#define BOOT_RETRY_WAIT "boot-time-retry-wait"
#define WEBPA_PROTOCOL_VALUE "WebPA-1.6"
#define WEBPA_PATH_URL "/api/v2/device"
#define PARODUS_UPSTREAM "tcp://127.0.0.1:6666"
#define PROTOCOL_VALUE "PARODUS-2.0"
#define WEBPA_PATH_URL "/api/v2/device"
#define JWT_ALGORITHM "jwt-algo"
#define JWT_KEY "jwt-key"
#define DNS_TXT_URL "fabric"
#define PARODUS_UPSTREAM "tcp://127.0.0.1:6666"
#define ALLOW_NON_RSA_ALG false
/*----------------------------------------------------------------------------*/
/* Data Structures */
@@ -56,25 +78,68 @@ typedef struct
char webpa_path_url[124];
unsigned int webpa_backoff_max;
char webpa_interface_used[16];
char webpa_protocol[16];
char webpa_protocol[32];
char webpa_uuid[64];
unsigned int secureFlag;
unsigned int flags;
char local_url[124];
char partner_id[64];
#ifdef ENABLE_SESHAT
char seshat_url[128];
#endif
char dns_txt_url[64];
unsigned int acquire_jwt;
unsigned int jwt_algo; // bit mask set for each allowed algorithm
char jwt_key[4096]; // may be read in from a pem file
char cert_path[64];
char webpa_auth_token[4096];
char token_acquisition_script[64];
char token_read_script[64];
unsigned int boot_retry_wait;
} ParodusCfg;
#define FLAGS_IPV6_ONLY (1 << 0)
#define FLAGS_IPV4_ONLY (1 << 1)
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
void loadParodusCfg(ParodusCfg * config,ParodusCfg *cfg);
void createNewAuthToken(char *newToken, size_t len);
void parseCommandLine(int argc,char **argv,ParodusCfg * cfg);
/**
* parse command line arguments and create config structure
* and return whether args are valid or not
*
* @param argc number of command line arguments
* @param argv command line argument lis
* @return 0 if OK
* or -1 if error
*/
int parseCommandLine(int argc,char **argv,ParodusCfg * cfg);
void setDefaultValuesToCfg(ParodusCfg *cfg);
void getAuthToken(ParodusCfg *cfg);
// Accessor for the global config structure.
ParodusCfg *get_parodus_cfg(void);
void set_parodus_cfg(ParodusCfg *);
char *get_token_application(void) ;
/**
* 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
* @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);
#ifdef __cplusplus
}

View File

@@ -1,9 +1,24 @@
/**
* Copyright 2015 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 conn_interface.c
*
* @description This decribes interface to create WebSocket client connections.
*
* Copyright (c) 2015 Comcast
*/
#include "connection.h"
@@ -13,40 +28,62 @@
#include "upstream.h"
#include "downstream.h"
#include "thread_tasks.h"
#include "nopoll_helpers.h"
#include "mutex.h"
#include "spin_thread.h"
#include "service_alive.h"
#include <libseshat.h>
#include <libwebsockets.h>
#include "seshat_interface.h"
#ifdef FEATURE_DNS_QUERY
#include <ucresolv_log.h>
#endif
/*----------------------------------------------------------------------------*/
/* Macros */
/*----------------------------------------------------------------------------*/
#define HEARTBEAT_RETRY_SEC 30 /* Heartbeat (ping/pong) timeout in seconds */
#define SESHAT_SERVICE_NAME "Parodus"
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
bool close_retry = false;
bool LastReasonStatus = false;
volatile unsigned int heartBeatTimer = 0;
pthread_mutex_t close_mut=PTHREAD_MUTEX_INITIALIZER;
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
static bool __registerWithSeshat(void);
static void *heartBeatHandlerTask();
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
void createLWSsocket(void *config_in, void (* initKeypress)())
void createSocketConnection(void (* initKeypress)())
{
int intTimer=0;
//ParodusCfg *tmpCfg = (ParodusCfg*)config_in;
noPollCtx *ctx;
bool seshat_registered = false;
ParodusCfg *tmpCfg = (ParodusCfg*)config_in;
loadParodusCfg(tmpCfg,get_parodus_cfg());
createLWSconnection();
//loadParodusCfg(tmpCfg,get_parodus_cfg());
#ifdef FEATURE_DNS_QUERY
register_ucresolv_logger (__cimplog);
#endif
ParodusPrint("Configure nopoll thread handlers in Parodus\n");
nopoll_thread_handlers(&createMutex, &destroyMutex, &lockMutex, &unlockMutex);
ctx = nopoll_ctx_new();
if (!ctx)
{
ParodusError("\nError creating nopoll context\n");
}
#ifdef NOPOLL_LOGGER
nopoll_log_set_handler (ctx, __report_log, NULL);
#endif
createNopollConnection(ctx);
packMetaData();
UpStreamMsgQ = NULL;
@@ -54,7 +91,6 @@ void createLWSsocket(void *config_in, void (* initKeypress)())
StartThread(processUpstreamMessage);
ParodusMsgQ = NULL;
StartThread(messageHandlerTask);
StartThread(heartBeatHandlerTask);
StartThread(serviceAliveTask);
if (NULL != initKeypress)
@@ -63,97 +99,52 @@ void createLWSsocket(void *config_in, void (* initKeypress)())
}
seshat_registered = __registerWithSeshat();
UNUSED(seshat_registered);
do
{
lws_service(get_global_context(), 50);
if(conn_retry)
nopoll_loop_wait(ctx, 5000000);
intTimer = intTimer + 5;
if(heartBeatTimer >= get_parodus_cfg()->webpa_ping_timeout)
{
wsi_dumb = NULL;
lws_context_destroy(get_global_context());
ParodusInfo("conn_retry is %d, hence closing the connection and retrying\n", conn_retry);
createLWSconnection();
}
}while(!conn_retry);
lws_context_destroy(get_global_context());
}
/*----------------------------------------------------------------------------*/
/* Internal functions */
/*----------------------------------------------------------------------------*/
/**
* @brief Helper function to register with seshat.
*
* @note return whether successfully registered.
*
* @return true when registered, false otherwise.
*/
static bool __registerWithSeshat()
{
char *seshat_url = get_parodus_cfg()->seshat_url;
char *parodus_url = get_parodus_cfg()->local_url;
char *discover_url = NULL;
bool rv = false;
if( 0 == init_lib_seshat(seshat_url) ) {
ParodusInfo("seshatlib initialized! (url %s)\n", seshat_url);
if( 0 == seshat_register(SESHAT_SERVICE_NAME, parodus_url) ) {
ParodusInfo("seshatlib registered! (url %s)\n", parodus_url);
discover_url = seshat_discover(SESHAT_SERVICE_NAME);
if( (NULL != discover_url) && (0 == strcmp(parodus_url, discover_url)) ) {
ParodusInfo("seshatlib discovered url = %s\n", discover_url);
rv = true;
} else {
ParodusError("seshatlib registration error (url %s)!", discover_url);
}
free(discover_url);
} else {
ParodusError("seshatlib not registered! (url %s)\n", parodus_url);
}
} else {
ParodusPrint("seshatlib not initialized! (url %s)\n", seshat_url);
}
shutdown_seshat_lib();
return rv;
}
/*
* @brief To handle heartbeat mechanism
*/
static void *heartBeatHandlerTask()
{
while (FOREVER())
{
sleep(HEARTBEAT_RETRY_SEC);
if(heartBeatTimer >= get_parodus_cfg()->webpa_ping_timeout)
{
if(!conn_retry)
if(!close_retry)
{
ParodusError("ping wait time > %d. Terminating the connection with WebPA server and retrying\n", get_parodus_cfg()->webpa_ping_timeout);
ParodusInfo("Reconnect detected, setting Ping_Miss reason for Reconnect\n");
set_global_reconnect_reason("Ping_Miss");
LastReasonStatus = true;
conn_retry = true;
pthread_mutex_lock (&close_mut);
close_retry = true;
pthread_mutex_unlock (&close_mut);
}
else
{
ParodusPrint("heartBeatHandler - conn_retry set to %d, hence resetting the heartBeatTimer\n",conn_retry);
{
ParodusPrint("heartBeatHandler - close_retry set to %d, hence resetting the heartBeatTimer\n",close_retry);
}
heartBeatTimer = 0;
}
else
else if(intTimer >= 30)
{
ParodusPrint("heartBeatTimer %d\n",heartBeatTimer);
heartBeatTimer += HEARTBEAT_RETRY_SEC;
heartBeatTimer += HEARTBEAT_RETRY_SEC;
intTimer = 0;
}
}
heartBeatTimer = 0;
return NULL;
if( false == seshat_registered ) {
seshat_registered = __registerWithSeshat();
}
if(close_retry)
{
ParodusInfo("close_retry is %d, hence closing the connection and retrying\n", close_retry);
close_and_unref_connection(get_global_conn());
set_global_conn(NULL);
createNopollConnection(ctx);
}
} while(!close_retry);
close_and_unref_connection(get_global_conn());
nopoll_ctx_unref(ctx);
nopoll_cleanup_library();
}

View File

@@ -1,11 +1,25 @@
/**
* Copyright 2015 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 conn_interface.h
*
* @description This header defines interface to create WebSocket client connections.
*
* Copyright (c) 2015 Comcast
*/
#ifndef _CONN_INTERFACE_H_
#define _CONN_INTERFACE_H_
@@ -30,7 +44,7 @@ extern UpStreamMsg *UpStreamMsgQ;
* Loads the WebPA config file, if not provided by the caller,
* and creates the intial connection and manages the connection wait, close mechanisms.
*/
void createLWSsocket(void *config_in, void (* initKeypress)());
void createSocketConnection(void (* initKeypress)());
#ifdef __cplusplus
}

View File

@@ -1,51 +1,62 @@
/**
* Copyright 2015 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 connection.c
*
* @description This decribes functions required to manage WebSocket client connections.
*
* Copyright (c) 2015 Comcast
*/
#include "connection.h"
#include "time.h"
#include "token.h"
#include "config.h"
#include "upstream.h"
#include "nopoll_helpers.h"
#include "mutex.h"
#include "spin_thread.h"
#include "lws_handlers.h"
/*----------------------------------------------------------------------------*/
/* Macros */
/*----------------------------------------------------------------------------*/
#define MAX_PAYLOAD 102400
#define HTTP_CUSTOM_HEADER_COUNT 5
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
char deviceMAC[32]={'\0'};
static char *reconnect_reason = "webpa_process_starts";
static struct lws_context *g_context;
struct lws *wsi_dumb;
pthread_mutex_t res_mutex ;
bool conn_retry = true;
char * fragmentMsg = NULL;
int fragmentSize = 0;
int payloadSize = 0;
static noPollConn *g_conn = NULL;
static noPollConnOpts * createConnOpts (char * extra_headers, bool secure);
static noPollConn * nopoll_tls_common_conn (noPollCtx * ctx,char * serverAddr,char *serverPort,char * extra_headers);
static char* build_extra_headers( const char *auth, const char *device_id,
const char *user_agent, const char *convey );
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
struct lws_context *get_global_context(void)
noPollConn *get_global_conn(void)
{
return g_context;
return g_conn;
}
void set_global_context(struct lws_context *contextRef)
void set_global_conn(noPollConn *conn)
{
g_context = contextRef;
g_conn = conn;
}
char *get_global_reconnect_reason()
@@ -58,255 +69,329 @@ void set_global_reconnect_reason(char *reason)
reconnect_reason = reason;
}
char * join_fragment_msg (char *firstMsg,int firstSize,char *secondMsg,int secondSize,int * result)
/**
* @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)
{
*result = firstSize + secondSize;
fragmentSize = *result;
char *tmpMsg = (char *)malloc(sizeof(char)* (*result));
memcpy(tmpMsg,firstMsg,firstSize);
memcpy (tmpMsg + (firstSize), secondMsg, secondSize);
free(firstMsg);
free(secondMsg);
return tmpMsg;
}
int parodus_callback(struct lws *wsi, enum lws_callback_reasons reason,void *user, void *in, size_t len)
{
int n;
char * payload = NULL;
unsigned char * out = NULL;
switch (reason) {
case LWS_CALLBACK_CLIENT_ESTABLISHED:
ParodusInfo("Connected to server successfully\n");
conn_retry = false;
break;
case LWS_CALLBACK_CLOSED:
ParodusInfo("Callback closed, websocket session ends \n");
if(!LastReasonStatus)
{
ParodusInfo("Setting reconnect reason as Unknown\n");
set_global_reconnect_reason("Unknown");
}
wsi_dumb = NULL;
conn_retry = true;
break;
bool initial_retry = false;
int backoffRetryTime = 0;
int max_retry_sleep;
char port[8];
char server_Address[256];
char redirectURL[128]={'\0'};
int status=0;
int allow_insecure;
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[32]={'\0'};
char user_agent[512]={'\0'};
char * extra_headers = NULL;
case LWS_CALLBACK_CLIENT_RECEIVE:
((char *)in)[len] = '\0';
//ParodusInfo("length %d payload : %s\n", (int)len, (char *)in);
if(ctx == NULL) {
return nopoll_false;
}
ParodusInfo("**** Recieved %d bytes from server\n",(int)len);
char * tmpMsg = NULL;
payload = (char *)malloc(sizeof(char)*len);
strcpy(payload,(char *)in);
ParodusPrint("BootTime In sec: %d\n", get_parodus_cfg()->boot_time);
ParodusInfo("Received reboot_reason as:%s\n", get_parodus_cfg()->hw_last_reboot_reason);
ParodusInfo("Received reconnect_reason as:%s\n", reconnect_reason);
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
int jwt_insecure = allow_insecure_conn(
server_Address, (int) sizeof(server_Address),
port, (int) sizeof(port));
if (jwt_insecure >= 0)
allow_insecure = jwt_insecure;
}
#endif
ParodusInfo("server_Address %s\n",server_Address);
ParodusInfo("port %s\n", port);
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"));
if (lws_is_final_fragment(wsi))
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
{
//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;
if(allow_insecure <= 0)
{
ParodusPrint("secure true\n");
connection = nopoll_tls_common_conn(ctx,server_Address, port, extra_headers);
}
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(fragmentMsg == NULL)
if(get_global_conn() != NULL)
{
if(!nopoll_conn_is_ok(get_global_conn()))
{
listenerOnrequest_queue(payload,len);
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
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;
ParodusInfo("Waiting with backoffRetryTime %d seconds\n", backoffRetryTime);
sleep(backoffRetryTime);
continue;
}
else
else
{
tmpMsg = join_fragment_msg(fragmentMsg,fragmentSize,payload,len,&payloadSize);
len = payloadSize;
listenerOnrequest_queue(tmpMsg,len);
fragmentMsg = NULL;
fragmentSize = 0;
payloadSize = 0;
}
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_until_connection_ready(get_global_conn(), 10, &status, redirectURL))
{
if(status == 307 || status == 302 || 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;
allow_insecure = parse_webpa_url (redirect_ptr,
server_Address, (int) sizeof(server_Address),
port, (int) sizeof(port));
if (allow_insecure < 0) {
ParodusError ("Invalid redirectURL\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
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);
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(fragmentMsg == NULL)
/* 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))
{
fragmentMsg = payload;
fragmentSize = len;
}
else
{
fragmentMsg = join_fragment_msg(fragmentMsg,fragmentSize,payload,len,&payloadSize);
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");
reconnect_reason = "Dns_Res_webpa_reconnect";
LastReasonStatus = true;
kill(getpid(),SIGTERM);
}
}
}
initial_retry = true;
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
allow_insecure = parse_webpa_url (get_parodus_cfg()->webpa_url,
server_Address, (int) sizeof(server_Address),
port, (int) sizeof(port));
}
lws_callback_on_writable(wsi);
break;
}while(initial_retry);
if(allow_insecure <= 0)
{
ParodusInfo("Connected to server over SSL\n");
}
else
{
ParodusInfo("Connected to server\n");
}
// 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");
heartBeatTimer = 0;
// Reset connErr flag on successful connection
connErr = 0;
reconnect_reason = "webpa_process_starts";
LastReasonStatus =false;
ParodusPrint("LastReasonStatus reset after successful connection\n");
setMessageHandlers();
case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
ParodusError("***** Failed to Connected to server *******\n");
wsi_dumb = NULL;
conn_retry = true;
break;
case LWS_CALLBACK_WS_PEER_INITIATED_CLOSE:
ParodusInfo("Received server socket close\n");
if( (NULL != (char *)in) && (0 == strcmp((char *)in, "SSL_Socket_Close")) )
{
ParodusInfo("Last close reason received is %s\n", (char *)in);
set_global_reconnect_reason("Server_closed_connection");
LastReasonStatus = true;
}
break;
return nopoll_true;
}
case LWS_CALLBACK_CLIENT_WRITEABLE:
// Call back to send response to server
if(ResponseMsgQ != NULL)
{
//Read response data from queue
while(ResponseMsgQ)
/* 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,
const char *user_agent, const char *convey )
{
return nopoll_strdup_printf(
"%s%s"
"\r\nX-WebPA-Device-Name: %s"
"\r\nX-WebPA-Device-Protocols: wrp-0.11,getset-0.1"
"\r\nUser-Agent: %s"
"%s%s",
(NULL != auth) ? "\r\nAuthorization: Bearer " : "",
(NULL != auth) ? auth: "",
device_id,
user_agent,
(NULL != convey) ? "\r\nX-WebPA-Convey: " : "",
(NULL != convey) ? convey : "" );
}
static noPollConn * nopoll_tls_common_conn (noPollCtx * ctx,char * serverAddr,char *serverPort,char * extra_headers)
{
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 {
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(connection == NULL)
{
pthread_mutex_lock (&res_mutex);
UpStreamMsg *message = ResponseMsgQ;
ResponseMsgQ = ResponseMsgQ->next;
pthread_mutex_unlock (&res_mutex);
out = (unsigned char *)malloc(sizeof(unsigned char) * (LWS_PRE + message->len));
memcpy (LWS_PRE + out, message->msg, message->len);
n = lws_write(wsi, LWS_PRE + out, message->len, LWS_WRITE_BINARY);
if (n < 0)
{
ParodusError("Failed to send to server\n");
free(message->msg);
message->msg = NULL;
return 1;
}
if (n < (int)message->len) {
ParodusError("Partial write\n");
return -1;
}
ParodusInfo("Sent %d bytes of data to server successfully \n",n);
free(out);
free(message->msg);
message->msg = NULL;
ParodusInfo("Ipv6 connection failed. Try connecting with Ipv4 mode \n");
opts = createConnOpts(extra_headers, true);
connection = nopoll_conn_tls_new (ctx, opts,serverAddr,serverPort,NULL,get_parodus_cfg()->webpa_path_url,NULL,NULL);
}
}
lws_callback_on_writable(wsi);
break;
case LWS_CALLBACK_CLIENT_RECEIVE_PING:
ParodusInfo("Resetting HeartBeat Timer\n");
heartBeatTimer = 0;
break;
case LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER:
//Call back to send custom header to server
ParodusPrint("Send custom header to server\n");
char device_id[32]={'\0'};
char user_agent[512]={'\0'};
char *conveyHeader;
unsigned char **p = (unsigned char **)in, *end = (*p) + len;
strncpy(deviceMAC, get_parodus_cfg()->hw_mac,sizeof(deviceMAC));
snprintf(device_id, sizeof(device_id), "mac:%s", deviceMAC);
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();
if (lws_add_http_header_by_name(wsi,
(unsigned char *)"X-WebPA-Device-Name:",
(unsigned char *)device_id,strlen(device_id),p,end))
return -1;
if (lws_add_http_header_by_name(wsi,
(unsigned char *)"X-WebPA-Device-Protocols:",
(unsigned char *)"wrp-0.11,getset-0.1",strlen("wrp-0.11,getset-0.1"),p,end))
return -1;
if (lws_add_http_header_by_name(wsi,
(unsigned char *)"User-Agent:",
(unsigned char *)user_agent,strlen(user_agent),p,end))
return -1;
if(strlen(conveyHeader) > 0)
{
if (lws_add_http_header_by_name(wsi,
(unsigned char *)"X-WebPA-Convey:",
(unsigned char *)conveyHeader,strlen(conveyHeader),p,end))
return -1;
}
break;
case LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION:
/* Disable self signed verification */
X509_STORE_CTX_set_error((X509_STORE_CTX*)user, X509_V_OK);
return 0;
break;
default:
break;
}
return 0;
return connection;
}
static const struct lws_protocols protocols[] = {
{
NULL,
parodus_callback,
0,
MAX_PAYLOAD,
},
{ NULL, NULL, 0, 0 } /* end */
};
LWS_VISIBLE void lwsl_emit_syslog(int level, const char *line)
static noPollConnOpts * createConnOpts (char * extra_headers, bool secure)
{
UNUSED(level);
ParodusInfo(" %s",line);
}
void createLWSconnection()
{
struct lws_context_creation_info info;
struct lws_client_connect_info i;
struct lws_context *context;
int port = 8080,use_ssl =0;
noPollConnOpts * opts;
memset(&info, 0, sizeof info);
memset(&i, 0, sizeof(i));
use_ssl = LCCSCF_USE_SSL;
info.port = CONTEXT_PORT_NO_LISTEN;
info.protocols = protocols;
info.gid = -1;
info.uid = -1;
info.iface = get_parodus_cfg()->webpa_interface_used;
lws_set_log_level(LLL_INFO | LLL_NOTICE | LLL_WARN | LLL_LATENCY | LLL_CLIENT | LLL_COUNT,lwsl_emit_syslog);
info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
context = lws_create_context(&info);
if (context == NULL) {
ParodusError("Creating libwebsocket context failed\n");
exit(1);
}
set_global_context(context);
i.port = port;
i.address = get_parodus_cfg()->webpa_url;
i.context = context;
i.ssl_connection = use_ssl;
i.host = i.address;
i.path = "/api/v2/device";
while(1)
opts = nopoll_conn_opts_new ();
if(secure)
{
if (!wsi_dumb)
{
ParodusInfo("Connecting to server..\n");
i.pwsi = &wsi_dumb;
lws_client_connect_via_info(&i);
}
/*We need lws service here till client connects to server, without lws_service callback will not work*/
lws_service(context, 500);
if(!conn_retry)
/*Connected to server, break the loop and try lws service from main thread*/
break;
if(strlen(get_parodus_cfg()->cert_path) > 0)
{
nopoll_conn_opts_set_ssl_certs(opts, NULL, NULL, 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);
}
nopoll_conn_opts_set_interface (opts,get_parodus_cfg()->webpa_interface_used);
nopoll_conn_opts_set_extra_headers (opts,extra_headers);
return opts;
}
void close_and_unref_connection(noPollConn *conn)
{
if (conn) {
nopoll_conn_close(conn);
if (0 < nopoll_conn_ref_count (conn)) {
nopoll_conn_unref(conn);
}
}
}

View File

@@ -1,9 +1,24 @@
/**
* Copyright 2015 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 connection.h
*
* @description This header defines functions required to manage WebSocket client connections.
*
* Copyright (c) 2015 Comcast
*/
#ifndef _CONNECTION_H_
@@ -19,23 +34,26 @@ extern "C" {
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
extern bool conn_retry;
extern bool close_retry;
extern volatile unsigned int heartBeatTimer;
extern struct lws *wsi_dumb;
extern pthread_mutex_t close_mut;
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
int createNopollConnection(noPollCtx *);
/**
* @brief Interface to terminate WebSocket client connections and clean up resources.
*/
int parodus_callback(struct lws *wsi, enum lws_callback_reasons reason,void *user, void *in, size_t len);
void close_and_unref_connection(noPollConn *);
noPollConn *get_global_conn(void);
void set_global_conn(noPollConn *);
char *get_global_reconnect_reason();
void set_global_reconnect_reason(char *reason);
void createLWSconnection();
struct lws_context *get_global_context(void);
void set_global_context(struct lws_context *contextRef);
#ifdef __cplusplus
}

View File

@@ -1,9 +1,24 @@
/**
* Copyright 2015 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 downstream.c
*
* @description This describes functions required to manage downstream messages.
*
* Copyright (c) 2015 Comcast
*/
#include "downstream.h"
@@ -42,7 +57,7 @@ void listenerOnMessage(void * msg, size_t msgSize)
recivedMsg = (const char *) msg;
ParodusInfo("Received msg from server:%s\n", recivedMsg);
ParodusInfo("Received msg from server\n");
if(recivedMsg!=NULL)
{
/*** Decoding downstream recivedMsg to check destination ***/
@@ -54,98 +69,135 @@ void listenerOnMessage(void * msg, size_t msgSize)
msgType = message->msg_type;
ParodusInfo("msgType received:%d\n", msgType);
if(message->msg_type == WRP_MSG_TYPE__AUTH)
switch( message->msg_type )
{
ParodusInfo("Authorization Status received with Status code :%d\n", message->u.auth.status);
}
if(message->msg_type == WRP_MSG_TYPE__REQ)
{
ParodusPrint("numOfClients registered is %d\n", get_numOfClients());
int ret = validate_partner_id(message, NULL);
if(ret < 0)
case WRP_MSG_TYPE__AUTH:
{
response = cJSON_CreateObject();
cJSON_AddNumberToObject(response, "statusCode", 430);
cJSON_AddStringToObject(response, "message", "Invalid partner_id");
ParodusInfo("Authorization Status received with Status code :%d\n", message->u.auth.status);
break;
}
if((message->u.req.dest !=NULL) && (ret >= 0))
case WRP_MSG_TYPE__EVENT:
case WRP_MSG_TYPE__REQ:
case WRP_MSG_TYPE__CREATE:
case WRP_MSG_TYPE__UPDATE:
case WRP_MSG_TYPE__RETREIVE:
case WRP_MSG_TYPE__DELETE:
{
destVal = message->u.req.dest;
strtok(destVal , "/");
parStrncpy(dest,strtok(NULL , "/"), sizeof(dest));
ParodusInfo("Received downstream dest as :%s\n", dest);
temp = get_global_node();
//Checking for individual clients & Sending to each client
while (NULL != temp)
ParodusPrint("numOfClients registered is %d\n", get_numOfClients());
int ret = validate_partner_id(message, NULL);
if(ret < 0)
{
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)
{
ParodusPrint("sending to nanomsg client %s\n", dest);
bytes = nn_send(temp->sock, recivedMsg, msgSize, 0);
ParodusInfo("sent downstream message '%s' to reg_client '%s'\n",recivedMsg,temp->url);
ParodusPrint("downstream bytes sent:%d\n", bytes);
destFlag =1;
break;
}
ParodusPrint("checking the next item in the list\n");
temp= temp->next;
}
//if any unknown dest received sending error response to server
if(destFlag ==0)
{
ParodusError("Unknown dest:%s\n", dest);
response = cJSON_CreateObject();
cJSON_AddNumberToObject(response, "statusCode", 531);
cJSON_AddStringToObject(response, "message", "Service Unavailable");
}
}
cJSON_AddNumberToObject(response, "statusCode", 403);
cJSON_AddStringToObject(response, "message", "Invalid partner_id");
}
if(destFlag == 0 || ret < 0)
{
resp_msg = (wrp_msg_t *)malloc(sizeof(wrp_msg_t));
memset(resp_msg, 0, sizeof(wrp_msg_t));
resp_msg ->msg_type = msgType;
resp_msg ->u.req.source = message->u.req.dest;
resp_msg ->u.req.dest = message->u.req.source;
resp_msg ->u.req.transaction_uuid=message->u.req.transaction_uuid;
if(response != NULL)
destVal = ((WRP_MSG_TYPE__EVENT == msgType) ? message->u.event.dest :
((WRP_MSG_TYPE__REQ == msgType) ? message->u.req.dest : message->u.crud.dest));
if( (destVal != NULL) && (ret >= 0) )
{
str = cJSON_PrintUnformatted(response);
ParodusInfo("Payload Response: %s\n", str);
strtok(destVal , "/");
parStrncpy(dest,strtok(NULL , "/"), sizeof(dest));
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)));
temp = get_global_node();
//Checking for individual clients & Sending to each client
resp_msg ->u.req.payload = (void *)str;
resp_msg ->u.req.payload_size = strlen(str);
ParodusPrint("msgpack encode\n");
resp_size = wrp_struct_to( resp_msg, WRP_BYTES, &resp_bytes );
if(resp_size > 0)
while (NULL != temp)
{
size = (size_t) resp_size;
sendUpstreamMsgToServer(&resp_bytes, size);
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)
{
ParodusPrint("sending to nanomsg client %s\n", dest);
bytes = nn_send(temp->sock, recivedMsg, msgSize, 0);
ParodusInfo("sent downstream message to reg_client '%s'\n",temp->url);
ParodusPrint("downstream bytes sent:%d\n", bytes);
destFlag =1;
break;
}
ParodusPrint("checking the next item in the list\n");
temp= temp->next;
}
//if any unknown dest received sending error response to server
if(destFlag ==0)
{
ParodusError("Unknown dest:%s\n", dest);
response = cJSON_CreateObject();
cJSON_AddNumberToObject(response, "statusCode", 531);
cJSON_AddStringToObject(response, "message", "Service Unavailable");
}
free(str);
cJSON_Delete(response);
free(resp_bytes);
resp_bytes = NULL;
}
free(resp_msg);
if( (WRP_MSG_TYPE__EVENT != msgType) &&
((destFlag == 0) || (ret < 0)) )
{
resp_msg = (wrp_msg_t *)malloc(sizeof(wrp_msg_t));
memset(resp_msg, 0, sizeof(wrp_msg_t));
resp_msg ->msg_type = msgType;
if( WRP_MSG_TYPE__REQ == msgType )
{
resp_msg ->u.req.source = message->u.req.dest;
resp_msg ->u.req.dest = message->u.req.source;
resp_msg ->u.req.transaction_uuid=message->u.req.transaction_uuid;
}
else
{
resp_msg ->u.crud.source = message->u.crud.dest;
resp_msg ->u.crud.dest = message->u.crud.source;
resp_msg ->u.crud.transaction_uuid = message->u.crud.transaction_uuid;
resp_msg ->u.crud.path = message->u.crud.path;
}
if(response != NULL)
{
str = cJSON_PrintUnformatted(response);
ParodusInfo("Payload Response: %s\n", str);
if( WRP_MSG_TYPE__REQ == msgType )
{
resp_msg ->u.req.payload = (void *)str;
resp_msg ->u.req.payload_size = strlen(str);
}
else
{
resp_msg ->u.crud.payload = (void *)str;
resp_msg ->u.crud.payload_size = strlen(str);
}
ParodusPrint("msgpack encode\n");
resp_size = wrp_struct_to( resp_msg, WRP_BYTES, &resp_bytes );
if(resp_size > 0)
{
size = (size_t) resp_size;
sendUpstreamMsgToServer(&resp_bytes, size);
}
free(str);
cJSON_Delete(response);
free(resp_bytes);
resp_bytes = NULL;
}
free(resp_msg);
ParodusPrint("free for downstream decoded msg\n");
wrp_free_struct(message);
}
break;
}
case WRP_MSG_TYPE__SVC_REGISTRATION:
case WRP_MSG_TYPE__SVC_ALIVE:
case WRP_MSG_TYPE__UNKNOWN:
default:
break;
}
}
else
{
ParodusError( "Failure in msgpack decoding for receivdMsg: rv is %d\n", rv );
}
ParodusPrint("free for downstream decoded msg\n");
free(msg);
wrp_free_struct(message);
}
}

View File

@@ -1,9 +1,24 @@
/**
* Copyright 2015 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 downstream.h
*
* @description This header defines functions required to manage downstream messages.
*
* Copyright (c) 2015 Comcast
*/
#ifndef _DOWNSTREAM_H_

View File

@@ -1,75 +0,0 @@
/**
* @file lws_handlers.c
*
* @description This describes lws handler functions.
*
* Copyright (c) 2015 Comcast
*/
#include "ParodusInternal.h"
#include "lws_handlers.h"
#include "connection.h"
/*----------------------------------------------------------------------------*/
/* Macros */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
pthread_mutex_t g_mutex=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t g_cond=PTHREAD_COND_INITIALIZER;
ParodusMsg *ParodusMsgQ = NULL;
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
/**
* @brief listenerOnrequest_queue function to add messages to the queue
*
* @param[in] reqSize size of the incoming message
* @param[in] requestMsg The message received from server for various process requests
*/
void listenerOnrequest_queue(void *requestMsg,int reqSize)
{
ParodusMsg *message;
message = (ParodusMsg *)malloc(sizeof(ParodusMsg));
if(message)
{
message->payload = requestMsg;
message->len = reqSize;
message->next = NULL;
pthread_mutex_lock (&g_mutex);
ParodusPrint("mutex lock in producer thread\n");
if(ParodusMsgQ == NULL)
{
ParodusMsgQ = message;
ParodusPrint("Producer added message\n");
pthread_cond_signal(&g_cond);
pthread_mutex_unlock (&g_mutex);
ParodusPrint("mutex unlock in producer thread\n");
}
else
{
ParodusMsg *temp = ParodusMsgQ;
while(temp->next)
{
temp = temp->next;
}
temp->next = message;
pthread_mutex_unlock (&g_mutex);
}
}
else
{
//Memory allocation failed
ParodusError("Memory allocation is failed\n");
}
ParodusPrint("*****listenerOnrequest_queue*****\n");
}

View File

@@ -1,40 +0,0 @@
/**
* @file lws_handlers.h
*
* @description This header defines lws handler functions.
*
* Copyright (c) 2015 Comcast
*/
#ifndef _LWS_HANDLERS_H_
#define _LWS_HANDLERS_H_
#ifdef __cplusplus
extern "C" {
#endif
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
extern pthread_mutex_t g_mutex;
extern pthread_cond_t g_cond;
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
/**
* @brief listenerOnrequest_queue function to add messages to the queue
*
* @param[in] reqSize size of the incoming message
* @param[in] requestMsg The message received from server for various process requests
*/
void listenerOnrequest_queue(void *requestMsg,int reqSize);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -20,7 +20,11 @@
#include "config.h"
#include "conn_interface.h"
#include "parodus_log.h"
#ifdef INCLUDE_BREAKPAD
#include "breakpad_wrapper.h"
#else
#include "signal.h"
#endif
/*----------------------------------------------------------------------------*/
/* Macros */
@@ -40,13 +44,18 @@
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
#ifndef INCLUDE_BREAKPAD
static void sig_handler(int sig);
#endif
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
int main( int argc, char **argv)
{
#ifdef INCLUDE_BREAKPAD
breakpad_ExceptionHandler();
#else
signal(SIGTERM, sig_handler);
signal(SIGINT, sig_handler);
signal(SIGUSR1, sig_handler);
@@ -59,14 +68,21 @@ int main( int argc, char **argv)
signal(SIGQUIT, sig_handler);
signal(SIGHUP, sig_handler);
signal(SIGALRM, sig_handler);
ParodusCfg parodusCfg;
memset(&parodusCfg,0,sizeof(parodusCfg));
#endif
ParodusCfg *cfg;
/* TODO not ideal, but it fixes a more major problem for now. */
cfg = get_parodus_cfg();
memset(cfg,0,sizeof(ParodusCfg));
ParodusInfo("********** Starting component: Parodus **********\n ");
parseCommandLine(argc,argv,&parodusCfg);
setDefaultValuesToCfg(cfg);
if (0 != parseCommandLine(argc,argv,cfg)) {
abort();
}
getAuthToken(cfg);
createLWSsocket(&parodusCfg,NULL);
createSocketConnection( NULL);
return 0;
}
@@ -79,6 +95,7 @@ const char *rdk_logger_module_fetch(void)
/*----------------------------------------------------------------------------*/
/* Internal functions */
/*----------------------------------------------------------------------------*/
#ifndef INCLUDE_BREAKPAD
static void sig_handler(int sig)
{
@@ -119,3 +136,4 @@ static void sig_handler(int sig)
}
}
#endif

159
src/mutex.c Normal file
View File

@@ -0,0 +1,159 @@
/**
* Copyright 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 "mutex.h"
#include "parodus_log.h"
/*----------------------------------------------------------------------------*/
/* Macros */
/*----------------------------------------------------------------------------*/
/* none */
/*----------------------------------------------------------------------------*/
/* Data Structures */
/*----------------------------------------------------------------------------*/
/* none */
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
/* none */
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
/* none */
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
/**
* @brief createMutex Nopoll create mutex handler
*/
noPollPtr createMutex()
{
pthread_mutexattr_t attr;
pthread_mutex_t * mutex;
int rtn;
mutex = (pthread_mutex_t*) malloc(sizeof(pthread_mutex_t));
if (mutex == NULL) {
ParodusError("Failed to create mutex\n");
return NULL;
}
pthread_mutexattr_init( &attr);
/*pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_ERRORCHECK);*/
pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE);
/* init the mutex using default values */
rtn = pthread_mutex_init (mutex, &attr);
pthread_mutexattr_destroy (&attr);
if (rtn != 0) {
ParodusError("Error in init Mutex\n");
free(mutex);
return NULL;
} else {
ParodusPrint("mutex init successfully\n");
}
return mutex;
}
/**
* @brief lockMutex Nopoll lock mutex handler
*/
void lockMutex(noPollPtr _mutex)
{
int rtn;
char errbuf[100];
if (_mutex == NULL) {
ParodusError("Received null mutex\n");
return;
}
pthread_mutex_t * mutex = _mutex;
/* lock the mutex */
rtn = pthread_mutex_lock (mutex);
if (rtn != 0) {
strerror_r (rtn, errbuf, 100);
ParodusError("Error in Lock mutex: %s\n", errbuf);
/* do some reporting */
return;
}
return;
}
/**
* @brief unlockMutex Nopoll unlock mutex handler
*/
void unlockMutex(noPollPtr _mutex)
{
int rtn;
char errbuf[100];
if (_mutex == NULL) {
ParodusError("Received null mutex\n");
return;
}
pthread_mutex_t * mutex = _mutex;
/* unlock mutex */
rtn = pthread_mutex_unlock (mutex);
if (rtn != 0) {
/* do some reporting */
strerror_r (rtn, errbuf, 100);
ParodusError("Error in unlock mutex: %s\n", errbuf);
return;
}
return;
}
/**
* @brief destroyMutex Nopoll destroy mutex handler
*/
void destroyMutex(noPollPtr _mutex)
{
if (_mutex == NULL) {
ParodusError("Received null mutex\n");
return;
}
pthread_mutex_t * mutex = _mutex;
if (pthread_mutex_destroy (mutex) != 0) {
/* do some reporting */
ParodusError("problem in destroy\n");
return;
} else {
ParodusPrint("Mutex destroyed \n");
}
free(mutex);
return;
}
/*----------------------------------------------------------------------------*/
/* Internal functions */
/*----------------------------------------------------------------------------*/
/* none */

58
src/mutex.h Normal file
View File

@@ -0,0 +1,58 @@
/**
* Copyright 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 <nopoll.h>
#include <pthread.h>
#ifndef _MUTEX_H_
#define _MUTEX_H_
#ifdef __cplusplus
extern "C" {
#endif
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
/**
* @brief createMutex Nopoll create mutex handler
*/
noPollPtr createMutex();
/**
* @brief lockMutex Nopoll lock mutex handler
*/
void lockMutex(noPollPtr _mutex);
/**
* @brief unlockMutex Nopoll unlock mutex handler
*/
void unlockMutex(noPollPtr _mutex);
/**
* @brief destroyMutex Nopoll destroy mutex handler
*/
void destroyMutex(noPollPtr _mutex);
#ifdef __cplusplus
}
#endif
#endif

104
src/networking.c Normal file
View File

@@ -0,0 +1,104 @@
/**
* Copyright 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 "ParodusInternal.h"
/*----------------------------------------------------------------------------*/
/* Macros */
/*----------------------------------------------------------------------------*/
/* none */
/*----------------------------------------------------------------------------*/
/* Data Structures */
/*----------------------------------------------------------------------------*/
/* none */
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
/* none */
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
/* none */
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
/**
* Interface to check if the Host server DNS is resolved to an IP address that
* is not 10.0.0.1.
*
* @param[in] serverIP server address DNS
*
* @returns 0 on success, error otherwise
*/
int checkHostIp(char * serverIP)
{
int status = -1;
struct addrinfo *res, *result;
int retVal;
char addrstr[100];
void *ptr;
char *localIp = "10.0.0.1";
struct addrinfo hints;
ParodusPrint("...............Inside checkHostIp..............%s \n", serverIP);
memset(&hints,0,sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = 0;
retVal = getaddrinfo(serverIP, "http", &hints, &result);
if (retVal != 0)
{
ParodusError("getaddrinfo: %s\n", gai_strerror(retVal));
}
else
{
res = result;
while(res)
{
ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr;
inet_ntop (res->ai_family, ptr, addrstr, 100);
ParodusPrint("IPv4 address of %s is %s \n", serverIP, addrstr);
if (strcmp(localIp,addrstr) == 0)
{
ParodusPrint("Host Ip resolved to 10.0.0.1\n");
status = -2;
}
else
{
ParodusPrint("Host Ip resolved correctly, proceeding with the connection\n");
status = 0;
break;
}
res = res->ai_next;
}
freeaddrinfo(result);
}
return status;
}
/*----------------------------------------------------------------------------*/
/* Internal functions */
/*----------------------------------------------------------------------------*/
/* none */

152
src/nopoll_handlers.c Normal file
View File

@@ -0,0 +1,152 @@
/**
* Copyright 2015 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 nopoll_handlers.c
*
* @description This describes nopoll handler functions.
*
*/
#include "ParodusInternal.h"
#include "nopoll_handlers.h"
#include "connection.h"
/*----------------------------------------------------------------------------*/
/* Macros */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
pthread_mutex_t g_mutex=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t g_cond=PTHREAD_COND_INITIALIZER;
ParodusMsg *ParodusMsgQ = NULL;
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
/**
* @brief listenerOnMessage_queue function to add messages to the queue
*
* @param[in] ctx The context where the connection happens.
* @param[in] conn The Websocket connection object
* @param[in] msg The message received from server for various process requests
* @param[out] user_data data which is to be sent
*/
void listenerOnMessage_queue(noPollCtx * ctx, noPollConn * conn, noPollMsg * msg,noPollPtr user_data)
{
UNUSED(ctx);
UNUSED(conn);
UNUSED(user_data);
ParodusMsg *message;
message = (ParodusMsg *)malloc(sizeof(ParodusMsg));
if(message)
{
message->msg = msg;
message->payload = (void *)nopoll_msg_get_payload (msg);
message->len = nopoll_msg_get_payload_size (msg);
message->next = NULL;
nopoll_msg_ref(msg);
pthread_mutex_lock (&g_mutex);
ParodusPrint("mutex lock in producer thread\n");
if(ParodusMsgQ == NULL)
{
ParodusMsgQ = message;
ParodusPrint("Producer added message\n");
pthread_cond_signal(&g_cond);
pthread_mutex_unlock (&g_mutex);
ParodusPrint("mutex unlock in producer thread\n");
}
else
{
ParodusMsg *temp = ParodusMsgQ;
while(temp->next)
{
temp = temp->next;
}
temp->next = message;
pthread_mutex_unlock (&g_mutex);
}
}
else
{
//Memory allocation failed
ParodusError("Memory allocation is failed\n");
}
ParodusPrint("*****Returned from listenerOnMessage_queue*****\n");
}
/**
* @brief listenerOnPingMessage function to create WebSocket listener to receive heartbeat ping messages
*
* @param[in] ctx The context where the connection happens.
* @param[in] conn Websocket connection object
* @param[in] msg The ping message received from the server
* @param[out] user_data data which is to be sent
*/
void listenerOnPingMessage (noPollCtx * ctx, noPollConn * conn, noPollMsg * msg, noPollPtr user_data)
{
UNUSED(ctx);
UNUSED(user_data);
noPollPtr payload = NULL;
payload = (noPollPtr ) nopoll_msg_get_payload(msg);
if ((payload!=NULL))
{
ParodusInfo("Ping received with payload %s, opcode %d\n",(char *)payload, nopoll_msg_opcode(msg));
if (nopoll_msg_opcode(msg) == NOPOLL_PING_FRAME)
{
nopoll_conn_send_frame (conn, nopoll_true, nopoll_true, NOPOLL_PONG_FRAME, strlen(payload), payload, 0);
heartBeatTimer = 0;
ParodusPrint("Sent Pong frame and reset HeartBeat Timer\n");
}
}
}
void listenerOnCloseMessage (noPollCtx * ctx, noPollConn * conn, noPollPtr user_data)
{
UNUSED(ctx);
UNUSED(conn);
ParodusPrint("listenerOnCloseMessage(): mutex lock in producer thread\n");
if((user_data != NULL) && (strstr(user_data, "SSL_Socket_Close") != NULL) && !LastReasonStatus)
{
ParodusInfo("Reconnect detected, setting Reconnect reason as Server close\n");
set_global_reconnect_reason("Server_closed_connection");
LastReasonStatus = true;
}
else if ((user_data == NULL) && !LastReasonStatus)
{
ParodusInfo("Reconnect detected, setting Reconnect reason as Unknown\n");
set_global_reconnect_reason("Unknown");
}
pthread_mutex_lock (&close_mut);
close_retry = true;
pthread_mutex_unlock (&close_mut);
ParodusPrint("listenerOnCloseMessage(): mutex unlock in producer thread\n");
}

74
src/nopoll_handlers.h Normal file
View File

@@ -0,0 +1,74 @@
/**
* Copyright 2015 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 nopoll_handlers.h
*
* @description This header defines nopoll handler functions.
*
*/
#ifndef _NOPOLL_HANDLERS_H_
#define _NOPOLL_HANDLERS_H_
#include "nopoll.h"
#ifdef __cplusplus
extern "C" {
#endif
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
extern pthread_mutex_t g_mutex;
extern pthread_cond_t g_cond;
extern pthread_mutex_t close_mut;
extern volatile unsigned int heartBeatTimer;
extern bool close_retry;
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
/**
* @brief listenerOnMessage_queue function to add messages to the queue
*
* @param[in] ctx The context where the connection happens.
* @param[in] conn The Websocket connection object
* @param[in] msg The message received from server for various process requests
* @param[out] user_data data which is to be sent
*/
void listenerOnMessage_queue(noPollCtx * ctx, noPollConn * conn, noPollMsg * msg,noPollPtr user_data);
/**
* @brief listenerOnPingMessage function to create WebSocket listener to receive heartbeat ping messages
*
* @param[in] ctx The context where the connection happens.
* @param[in] conn Websocket connection object
* @param[in] msg The ping message received from the server
* @param[out] user_data data which is to be sent
*/
void listenerOnPingMessage (noPollCtx * ctx, noPollConn * conn, noPollMsg * msg, noPollPtr user_data);
void listenerOnCloseMessage (noPollCtx * ctx, noPollConn * conn, noPollPtr user_data);
#ifdef __cplusplus
}
#endif
#endif

127
src/nopoll_helpers.c Normal file
View File

@@ -0,0 +1,127 @@
/**
* Copyright 2015 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 nopoll_helpers.c
*
* @description This file is used to manage incomming and outgoing messages.
*
*/
#include "ParodusInternal.h"
#include "connection.h"
#include "nopoll_helpers.h"
#include "nopoll_handlers.h"
/*----------------------------------------------------------------------------*/
/* Macros */
/*----------------------------------------------------------------------------*/
#define MAX_SEND_SIZE (60 * 1024)
#define FLUSH_WAIT_TIME (2000000LL)
/*----------------------------------------------------------------------------*/
/* External functions */
/*----------------------------------------------------------------------------*/
void setMessageHandlers()
{
nopoll_conn_set_on_msg(get_global_conn(), (noPollOnMessageHandler) listenerOnMessage_queue, NULL);
nopoll_conn_set_on_ping_msg(get_global_conn(), (noPollOnMessageHandler)listenerOnPingMessage, NULL);
nopoll_conn_set_on_close(get_global_conn(), (noPollOnCloseHandler)listenerOnCloseMessage, NULL);
}
/** To send upstream msgs to server ***/
void sendMessage(noPollConn *conn, void *msg, size_t len)
{
int bytesWritten = 0;
ParodusInfo("sendMessage length %zu\n", len);
if(nopoll_conn_is_ok(conn) && nopoll_conn_is_ready(conn))
{
//bytesWritten = nopoll_conn_send_binary(conn, msg, len);
bytesWritten = sendResponse(conn, msg, len);
ParodusPrint("Number of bytes written: %d\n", bytesWritten);
if (bytesWritten != (int) len)
{
ParodusError("Failed to send bytes %zu, bytes written were=%d (errno=%d, %s)..\n", len, bytesWritten, errno, strerror(errno));
}
}
else
{
ParodusError("Failed to send msg upstream as connection is not OK\n");
}
}
int sendResponse(noPollConn * conn, void * buffer, size_t length)
{
char *cp = buffer;
int final_len_sent = 0;
noPollOpCode frame_type = NOPOLL_BINARY_FRAME;
while (length > 0)
{
int bytes_sent, len_to_send;
len_to_send = length > MAX_SEND_SIZE ? MAX_SEND_SIZE : length;
length -= len_to_send;
bytes_sent = __nopoll_conn_send_common(conn, cp, len_to_send, length > 0 ? nopoll_false : nopoll_true, 0, frame_type);
if (bytes_sent != len_to_send)
{
if (-1 == bytes_sent || (bytes_sent = nopoll_conn_flush_writes(conn, FLUSH_WAIT_TIME, bytes_sent)) != len_to_send)
{
ParodusError("sendResponse() Failed to send all the data\n");
cp = NULL;
break;
}
}
cp += len_to_send;
final_len_sent += len_to_send;
frame_type = NOPOLL_CONTINUATION_FRAME;
}
return final_len_sent;
}
/**
* @brief __report_log Nopoll log handler
* Nopoll log handler for integrating nopoll logs
*/
void __report_log (noPollCtx * ctx, noPollDebugLevel level, const char * log_msg, noPollPtr user_data)
{
UNUSED(ctx);
UNUSED(user_data);
if (level == NOPOLL_LEVEL_DEBUG)
{
//ParodusPrint("%s\n", log_msg);
}
if (level == NOPOLL_LEVEL_INFO)
{
ParodusInfo ("%s\n", log_msg);
}
if (level == NOPOLL_LEVEL_WARNING)
{
ParodusPrint("%s\n", log_msg);
}
if (level == NOPOLL_LEVEL_CRITICAL)
{
ParodusError("%s\n", log_msg );
}
return;
}

56
src/nopoll_helpers.h Normal file
View File

@@ -0,0 +1,56 @@
/**
* Copyright 2015 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 nopoll_handlers.h
*
* @description This header defines functions to manage incomming and outgoing messages.
*
*/
#ifndef _NOPOLL_HELPERS_H_
#define _NOPOLL_HELPERS_H_
#include "nopoll.h"
#ifdef __cplusplus
extern "C" {
#endif
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
/**
* @brief Interface to create WebSocket client connections.
* Loads the WebPA config file, if not provided by the caller,
* and creates the intial connection and manages the connection wait, close mechanisms.
*/
int sendResponse(noPollConn * conn,void *str, size_t bufferSize);
void setMessageHandlers();
void sendMessage(noPollConn *conn, void *msg, size_t len);
/**
* @brief __report_log Nopoll log handler
* Nopoll log handler for integrating nopoll logs
*/
void __report_log (noPollCtx * ctx, noPollDebugLevel level, const char * log_msg, noPollPtr user_data);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,9 +1,24 @@
/**
* Copyright 2015 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 parodus_log.h
*
* @description This header defines parodus log levels
*
* Copyright (c) 2015 Comcast
*/
#include <stdarg.h>

View File

@@ -1,9 +1,24 @@
/**
* Copyright 2015 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 partners_check.c
*
* @description This describes functions to validate partner_id.
*
* Copyright (c) 2015 Comcast
*/
#include "ParodusInternal.h"
@@ -24,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));
(*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);
strcpy((*partnerIds)->partner_ids[count], partnerId);
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));
(*partnerIds)->count = 1;
(*partnerIds)->partner_ids[0] = (char *) malloc(sizeof(char) * 64);
strcpy((*partnerIds)->partner_ids[0], partnerId);
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

@@ -1,9 +1,24 @@
/**
* Copyright 2015 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 partners_check.h
*
* @description This describes functions to validate partner_id.
*
* Copyright (c) 2015 Comcast
*/
#ifndef _PARTNERS_CHECK_H_

View File

@@ -1,9 +1,24 @@
/**
* Copyright 2015 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 service_alive.c
*
* @description This file is used to manage keep alive section
*
* Copyright (c) 2015 Comcast
*/
#include "ParodusInternal.h"
@@ -82,7 +97,7 @@ void *serviceAliveTask()
else
{
ParodusInfo("No clients are registered, waiting ..\n");
sleep(70);
sleep(50);
}
}
}

View File

@@ -1,9 +1,24 @@
/**
* Copyright 2015 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 service_alive.h
*
* @description This file is used to manage keep alive section
*
* Copyright (c) 2015 Comcast
*/
#ifndef _SERVICE_ALIVE_H_

81
src/seshat_interface.c Normal file
View File

@@ -0,0 +1,81 @@
/**
* Copyright 2015 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 seshat_interface.c
*
* @description This decribes interface to register seshat service.
*
*/
#include "seshat_interface.h"
#include "ParodusInternal.h"
#include "config.h"
#include <libseshat.h>
/*----------------------------------------------------------------------------*/
/* Macros */
/*----------------------------------------------------------------------------*/
#define SESHAT_SERVICE_NAME "Parodus"
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* Internal Functions */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* External functions */
/*----------------------------------------------------------------------------*/
bool __registerWithSeshat()
{
char *seshat_url = get_parodus_cfg()->seshat_url;
char *parodus_url = get_parodus_cfg()->local_url;
char *discover_url = NULL;
bool rv = false;
if( 0 == init_lib_seshat(seshat_url) ) {
ParodusInfo("seshatlib initialized! (url %s)\n", seshat_url);
if( 0 == seshat_register(SESHAT_SERVICE_NAME, parodus_url) ) {
ParodusInfo("seshatlib registered! (url %s)\n", parodus_url);
discover_url = seshat_discover(SESHAT_SERVICE_NAME);
if( (NULL != discover_url) && (0 == strcmp(parodus_url, discover_url)) ) {
ParodusInfo("seshatlib discovered url = %s\n", discover_url);
rv = true;
} else {
ParodusError("seshatlib registration error (url %s)!", discover_url);
}
free(discover_url);
} else {
ParodusError("seshatlib not registered! (url %s)\n", parodus_url);
}
} else {
ParodusPrint("seshatlib not initialized! (url %s)\n", seshat_url);
}
shutdown_seshat_lib();
return rv;
}

54
src/seshat_interface.h Normal file
View File

@@ -0,0 +1,54 @@
/**
* Copyright 2015 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 seshat_interface.h
*
* @description This header defines interface to register seshat service.
*
*/
#ifndef _SESHAT_INTERFACE_H_
#define _SESHAT_INTERFACE_H_
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
/**
* @brief Helper function to register with seshat.
*
* @note return whether successfully registered.
*
* @return true when registered, false otherwise.
*/
bool __registerWithSeshat();
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,53 @@
/**
* Copyright 2015 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 seshat_interface_stub.c
*
* @description This decribes interface to register seshat service
*
*/
#include "seshat_interface.h"
#include "ParodusInternal.h"
/*----------------------------------------------------------------------------*/
/* Macros */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* Internal Functions */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* External functions */
/*----------------------------------------------------------------------------*/
bool __registerWithSeshat()
{
ParodusInfo("libseshat disabled, Hence proceeding without registration\n");
return true;
}

View File

@@ -1,9 +1,24 @@
/**
* Copyright 2015 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 spin_thread.c
*
* @description This file is used to define thread function
*
* Copyright (c) 2015 Comcast
*/
#include <stdlib.h>
@@ -29,7 +44,7 @@ void StartThread(void *(*start_routine) (void *))
}
else
{
ParodusPrint("Thread created Successfully %d\n", (int ) threadId);
ParodusPrint("Thread created Successfully %lu\n", (unsigned long) threadId);
}
}

View File

@@ -1,9 +1,24 @@
/**
* Copyright 2015 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 spin_thread.h
*
* @description This file is used to define thread function
*
* Copyright (c) 2015 Comcast
*/
#ifndef _SPIN_THREAD_H_

View File

@@ -37,6 +37,7 @@ void *messageHandlerTask()
listenerOnMessage(message->payload, message->len);
nopoll_msg_unref(message->msg);
free(message);
message = NULL;
}

View File

@@ -1,9 +1,24 @@
/**
* Copyright 2015 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 thread_tasks.h
*
* @description This header defines thread functions.
*
* Copyright (c) 2015 Comcast
*/
#ifndef _THREAD_TASKS_H_

543
src/token.c Normal file
View File

@@ -0,0 +1,543 @@
/**
* Copyright 2015 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 token.c
*
* @description This file contains operations for using jwt token.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <netinet/in.h>
#ifdef FEATURE_DNS_QUERY
#include <ucresolv.h>
#endif
//#include <res_update.h>
#include <netdb.h>
#include <strings.h>
#include <string.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/param.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <ctype.h>
#include <errno.h>
#include <time.h>
#include <cjwt/cjwt.h>
#include "token.h"
#include "config.h"
#include "parodus_log.h"
#include "ParodusInternal.h"
#define JWT_MAXBUF 8192
#ifdef NS_MAXMSG
#if NS_MAXMSG > JWT_MAXBUF
#define NS_MAXBUF JWT_MAXBUF
#else
#define NS_MAXBUF NS_MAXMSG
#endif
#else
#define NS_MAXBUF JWT_MAXBUF
#endif
#define TXT_REC_ID_MAXSIZE 128
#define MAX_RR_RECS 10
#define SEQ_TABLE_SIZE (MAX_RR_RECS + 1)
/*----------------------------------------------------------------------------*/
/* Macros */
/*----------------------------------------------------------------------------*/
#define ENDPOINT_NAME "endpoint"
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
/* none */
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
/* none */
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
#ifdef FEATURE_DNS_QUERY
extern int __res_ninit(res_state statp);
extern void __res_nclose(res_state statp);
extern int __res_nquery(res_state statp,
const char *name, /* domain name */
int class, int type, /* class and type of query */
u_char *answer, /* buffer to put answer */
int anslen); /* size of answer buffer */
/*----------------------------------------------------------------------------*/
/* Internal functions */
/*----------------------------------------------------------------------------*/
static void show_times (time_t exp_time, time_t cur_time)
{
char exp_buf[30];
char cur_buf[30];
ctime_r (&exp_time, exp_buf);
exp_buf[strlen(exp_buf)-1] = 0;
ctime_r (&cur_time, cur_buf);
cur_buf[strlen(cur_buf)-1] = 0;
ParodusInfo ("Exp: %d %s, Current: %d %s\n",
(int)exp_time, exp_buf+4, (int)cur_time, cur_buf+4);
}
// 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)
{
cJSON *claims = jwt->private_claims;
cJSON *endpoint = NULL;
time_t exp_time, cur_time;
int http_match;
if (!claims) {
ParodusError ("Private claims not found in jwt\n");
return TOKEN_ERR_INVALID_JWT_CONTENT;
}
endpoint = cJSON_GetObjectItem(claims, ENDPOINT_NAME);
if (!endpoint) {
ParodusError ("Endpoint claim not found in jwt\n");
return TOKEN_ERR_INVALID_JWT_CONTENT;
}
ParodusInfo ("JWT endpoint: %s\n", endpoint->valuestring);
exp_time = jwt->exp.tv_sec;
if (0 == exp_time) {
ParodusError ("exp not found in JWT payload\n");
return TOKEN_ERR_NO_EXPIRATION;
} else {
cur_time = time(NULL);
show_times (exp_time, cur_time);
if (exp_time < cur_time) {
ParodusError ("JWT has expired\n");
return TOKEN_ERR_JWT_EXPIRED;
}
}
http_match = parse_webpa_url (endpoint->valuestring,
url_buf, url_buflen, port_buf, port_buflen);
if (http_match < 0) {
ParodusError ("Invalid endpoint claim in JWT\n");
return TOKEN_ERR_BAD_ENDPOINT;
}
ParodusInfo ("JWT is_http strncmp: %d\n", http_match);
return http_match;
}
bool validate_algo(const cjwt_t *jwt)
{
// return true if jwt->header.alg is included in the set
// of allowed algorithms specified by cfg->jwt_algo
ParodusCfg *cfg = get_parodus_cfg();
int alg = jwt->header.alg;
int alg_mask;
if ((alg < 0) || (alg >= num_algorithms))
return false;
alg_mask = 1<<alg;
if ((alg_mask & cfg->jwt_algo) == 0) {
ParodusError ("Algorithm %d not allowed (mask %d)\n", alg, alg_mask);
return false;
}
return true;
}
int nquery(const char* dns_txt_record_id, u_char *nsbuf)
{
int len;
struct __res_state statp;
/* Initialize resolver */
memset (&statp, 0, sizeof(__res_state));
if (NULL == nsbuf) {
ParodusError ("nquery: nsbuf is NULL\n");
return (-1);
}
statp.options |= RES_DEBUG;
if (__res_ninit(&statp) < 0) {
ParodusError ("res_ninit error: can't initialize statp.\n");
return (-1);
}
ParodusInfo ("nquery: domain : %s\n", dns_txt_record_id);
memset (nsbuf, 0, NS_MAXBUF);
len = __res_nquery(&statp, dns_txt_record_id, ns_c_in, ns_t_txt, nsbuf, NS_MAXBUF);
if (len < 0) {
if (0 != statp.res_h_errno) {
const char *msg = hstrerror (statp.res_h_errno);
ParodusError ("Error in res_nquery: %s\n", msg);
}
return len;
}
__res_nclose (&statp);
ParodusInfo ("nquery: nsbuf (1) 0x%lx\n", (unsigned long) nsbuf);
if (len >= NS_MAXBUF) {
ParodusError ("res_nquery error: ns buffer too small.\n");
return -1;
}
return len;
}
bool valid_b64_char (char c)
{
if ((c>='A') && (c<='Z'))
return true;
if ((c>='a') && (c<='z'))
return true;
if ((c>='0') && (c<='9'))
return true;
if ((c=='/') || (c=='+') || (c=='-') || (c=='_'))
return true;
return false;
}
static bool is_digit (char c)
{
return (bool) ((c>='0') && (c<='9'));
}
// strip quotes and newlines from rr rec
const char *strip_rr_data (const char *rr_ptr, int *rrlen)
{
int len;
const char *optr = rr_ptr;
char c;
len = strlen (optr);
if (len > 0) {
c = optr[0];
if (!is_digit(c)) {
optr++;
len--;
}
}
if (len > 0) {
if (!valid_b64_char (optr[len-1]))
len--;
}
if (len > 0) {
if (!valid_b64_char (optr[len-1]))
len--;
}
*rrlen = len;
return optr;
}
// return offset to seq number in record
// return -1 if not found, -2 if invalid fmt
int find_seq_num (const char *rr_ptr, int rrlen)
{
char c;
int i;
int digit_ct = 0;
for (i=0; i<rrlen; i++)
{
c = rr_ptr[i];
if (c == ':') {
if (digit_ct >= 2)
return i - 2;
else
return -2;
}
if (is_digit (c))
digit_ct++;
else
digit_ct = 0;
}
return -1;
}
// get seq num in rr rec
// return -1 if not formatted correctly
int get_rr_seq_num (const char *rr_ptr, int rrlen)
{
char c;
int lo, hi;
if (rrlen < 3)
return -1;
if (rr_ptr[2] != ':')
return -1;
c = rr_ptr[0];
if (is_digit (c))
hi = c - '0';
else
return -1;
c = rr_ptr[1];
if (is_digit (c))
lo = c - '0';
else
return -1;
return (10*hi) + lo;
}
// scan rr recs and build seq table using seq numbers in the recs
// return num_txt_recs
int get_rr_seq_table (ns_msg *msg_handle, int num_rr_recs, rr_rec_t *seq_table)
{
ns_rr rr;
const char *rr_ptr;
int seq_pos;
int rrlen;
int i, ret, seq_num;
int num_txt_recs = 0;
if (num_rr_recs > MAX_RR_RECS) {
ParodusError ("num rr recs (%d) to big, > %d\n", num_rr_recs, MAX_RR_RECS);
return -1;
}
// clear seq table
for (i=0; i<SEQ_TABLE_SIZE; i++)
{
seq_table[i].rr_ptr = NULL;
seq_table[i].rr_len = 0;
}
// extract and concatenate all the records in rr
for (i=0; i<num_rr_recs; i++) {
ret = ns_parserr(msg_handle, ns_s_an, i, &rr);
if (ret != 0) {
ParodusError ("query_dns: ns_parserr failed: %s\n", strerror (errno));
return ret;
}
if (ns_rr_type(rr) != ns_t_txt)
continue;
++num_txt_recs;
rr_ptr = (const char *)ns_rr_rdata(rr);
ParodusPrint ("Found rr rec type %d: %s\n", ns_t_txt, rr_ptr);
rr_ptr = strip_rr_data (rr_ptr, &rrlen);
seq_pos = find_seq_num (rr_ptr, rrlen);
if (seq_pos == -2) {
ParodusError ("Invalid seq number in rr record %d\n", i);
return -1;
}
if (seq_pos < 0) {
seq_num = 0;
} else {
rr_ptr += seq_pos;
rrlen -= seq_pos;
seq_num = get_rr_seq_num (rr_ptr, rrlen);
}
ParodusPrint ("Found seq num %d in rr rec %d\n", seq_num, i);
if (seq_num < 0) {
ParodusError ("Seq number not found in rr record %d\n", i);
return -1;
}
if (seq_num > num_rr_recs) {
ParodusError ("Invalid seq number (too big) in rr record %d\n", i);
return -1;
}
if (NULL != seq_table[seq_num].rr_ptr) {
ParodusError ("Duplicate rr record number %d\n", seq_num);
return -1;
}
if (seq_num != 0) {
rr_ptr += 3; // skip the seq number
rrlen -= 3;
}
seq_table[seq_num].rr_ptr = rr_ptr;
seq_table[seq_num].rr_len = rrlen;
}
if (NULL != seq_table[0].rr_ptr) {
// sequence-less record should not be used when there
// are multiple records
if (num_txt_recs > 1) {
ParodusError ("Seq number not found in rr record\n");
return -1;
}
// when there is only one record, use the sequence-less record
seq_table[1].rr_ptr = seq_table[0].rr_ptr;
seq_table[1].rr_len = seq_table[0].rr_len;
}
// check if we got them all
for (i=1; i<num_txt_recs; i++) {
if (NULL == seq_table[i].rr_ptr) {
ParodusError ("Missing rr record number %d\n", i+1);
return -1;
}
}
return num_txt_recs;
}
int assemble_jwt_from_dns (ns_msg *msg_handle, int num_rr_recs, char *jwt_ans)
{
// slot 0 in the seq table is for the sequence-less record that
// you get when there is only one record.
rr_rec_t seq_table[SEQ_TABLE_SIZE];
int i;
int num_txt_recs = get_rr_seq_table (msg_handle, num_rr_recs, seq_table);
if (num_txt_recs < 0)
return num_txt_recs;
ParodusPrint ("Found %d TXT records\n", num_txt_recs);
jwt_ans[0] = 0;
for (i=1; i<=num_txt_recs; i++)
strncat (jwt_ans, seq_table[i].rr_ptr, seq_table[i].rr_len);
return 0;
}
int query_dns(const char* dns_txt_record_id,char *jwt_ans)
{
u_char *nsbuf;
ns_msg msg_handle;
int ret;
int l = -1;
if( !dns_txt_record_id || !jwt_ans )
return l;
nsbuf = (u_char *) malloc (NS_MAXBUF);
ParodusInfo ("nsbuf (1) 0x%lx\n", (unsigned long) nsbuf);
if (NULL == nsbuf) {
ParodusError ("Unable to allocate nsbuf in query_dns\n");
return TOKEN_ERR_MEMORY_FAIL;
}
l = nquery(dns_txt_record_id,nsbuf);
if (l < 0) {
free (nsbuf);
return l;
}
ParodusInfo ("nsbuf (2) 0x%lx\n", (unsigned long) nsbuf);
/*--
memset((void *) &msg_handle, 0x5e, sizeof (ns_msg));
ParodusInfo ("nsbuf (3) 0x%lx\n", (unsigned long) nsbuf);
msg_handle._msg = nsbuf;
*/
ParodusInfo ("ns_initparse, msglen %d, nsbuf 0x%lx\n",
l, (unsigned long) nsbuf);
ret = ns_initparse((const u_char *) nsbuf, l, &msg_handle);
if (ret != 0) {
ParodusError ("ns_initparse failed\n");
free (nsbuf);
return ret;
}
ParodusInfo ("ns_msg_count\n");
l = ns_msg_count(msg_handle, ns_s_an);
ParodusInfo ("query_dns: ns_msg_count : %d\n",l);
jwt_ans[0] = 0;
ret = assemble_jwt_from_dns (&msg_handle, l, jwt_ans);
free (nsbuf);
if (ret == 0)
ParodusInfo ("query_dns JWT: %s\n", jwt_ans);
return ret;
}
static void get_dns_txt_record_id (char *buf)
{
ParodusCfg *cfg = get_parodus_cfg();
buf[0] = 0;
sprintf (buf, "%s.%s", cfg->hw_mac, cfg->dns_txt_url);
ParodusInfo("dns_txt_record_id %s\n", buf);
}
#endif
int allow_insecure_conn(char *url_buf, int url_buflen,
char *port_buf, int port_buflen)
{
#ifdef FEATURE_DNS_QUERY
int insecure=0, ret = -1;
char *jwt_token, *key;
cjwt_t *jwt = NULL;
char dns_txt_record_id[TXT_REC_ID_MAXSIZE];
jwt_token = malloc (NS_MAXBUF);
if (NULL == jwt_token) {
ParodusError ("Unable to allocate jwt_token in allow_insecure_conn\n");
insecure = TOKEN_ERR_MEMORY_FAIL;
goto end;
}
get_dns_txt_record_id (dns_txt_record_id);
ret = query_dns(dns_txt_record_id, jwt_token);
if(ret){
if (ret == TOKEN_ERR_MEMORY_FAIL) {
insecure = ret;
} else {
insecure = TOKEN_ERR_QUERY_DNS_FAIL;
}
goto end;
}
//Decoding the jwt token
key = get_parodus_cfg()->jwt_key;
ret = cjwt_decode( jwt_token, 0, &jwt, ( const uint8_t * )key,strlen(key) );
if(ret) {
if (ret == ENOMEM) {
ParodusError ("Memory allocation failed in JWT decode\n");
} else {
ParodusError ("CJWT decode error\n");
}
insecure = TOKEN_ERR_JWT_DECODE_FAIL;
goto end;
}
ParodusPrint("Decoded CJWT successfully\n");
//validate algo from --jwt_algo
if( validate_algo(jwt) ) {
insecure = analyze_jwt (jwt, url_buf, url_buflen, port_buf, port_buflen);
} else {
insecure = TOKEN_ERR_ALGO_NOT_ALLOWED;
}
if (insecure >= 0) {
ParodusInfo ("JWT claims: %s\n", cJSON_Print (jwt->private_claims));
}
cjwt_destroy(&jwt);
end:
if (NULL != jwt_token)
free (jwt_token);
#else
(void) url_buf;
(void) url_buflen;
(void) port_buf;
(void) port_buflen;
int insecure = TOKEN_NO_DNS_QUERY;
#endif
ParodusPrint ("Allow Insecure %d\n", insecure);
return insecure;
}

92
src/token.h Normal file
View File

@@ -0,0 +1,92 @@
/**
* Copyright 2015 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 token.h
*
* @description This file contains apis and error codes for using jwt token.
*
*/
#ifndef _TOKEN_H_
#define _TOKEN_H_
/**
* @brief token error rtn codes
*
*/
typedef enum {
TOKEN_ERR_MEMORY_FAIL = -999,
TOKEN_ERR_QUERY_DNS_FAIL = -101,
TOKEN_ERR_JWT_DECODE_FAIL = -102,
TOKEN_ERR_ALGO_NOT_ALLOWED = -103,
TOKEN_ERR_INVALID_JWT_CONTENT = -104,
TOKEN_ERR_NO_EXPIRATION = -105,
TOKEN_ERR_JWT_EXPIRED = -106,
TOKEN_ERR_BAD_ENDPOINT = -107,
TOKEN_NO_DNS_QUERY = -1
} token_error_t;
/**
Connection Logic:
----- Criteria -----
Feature FeatureDnsQuery enabled
QueryGood Dns query succeeds, jwt decodes and is valid and unexpired
Endpt starts Endpoint specified in the jwt starts with http:// or https://
Config Secflag secureFlag in config is set. Currently always set.
----- Actions -----
Default Securely connect to the default URL, specified
in the config
Secure Securely connect to the endpoint given in the jwt
Insecure Insecurely connect to the endpoint given in the jwt
----- Logic Table -----
Feature Query Endpt Config Action
Good Claim SecFlag
No Default
Yes No Default
Yes Yes https Secure
Yes Yes http False Insecure
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
* @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);
#endif

52
src/token_stub.c Normal file
View File

@@ -0,0 +1,52 @@
/**
* Copyright 2015 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 token_stub.c
*
* @description This file contains operations for using jwt token.
*
*/
#include "token.h"
#include "parodus_log.h"
/*----------------------------------------------------------------------------*/
/* Macros */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
/* none */
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
/* none */
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* Internal functions */
/*----------------------------------------------------------------------------*/
int allow_insecure_conn(void)
{
ParodusInfo("CJWT is disabled, Hence proceeding without validation\n");
return 1;
}

View File

@@ -1,9 +1,24 @@
/**
* Copyright 2015 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 upstream.c
*
* @description This describes functions required to manage upstream messages.
*
* Copyright (c) 2015 Comcast
*/
#include "ParodusInternal.h"
@@ -12,6 +27,7 @@
#include "partners_check.h"
#include "connection.h"
#include "client_list.h"
#include "nopoll_helpers.h"
/*----------------------------------------------------------------------------*/
/* Macros */
@@ -27,9 +43,7 @@ size_t metaPackSize=-1;
UpStreamMsg *UpStreamMsgQ = NULL;
UpStreamMsg *ResponseMsgQ = NULL;
pthread_mutex_t res_mutex ;
pthread_mutex_t nano_mut=PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t nano_con=PTHREAD_COND_INITIALIZER;
@@ -107,7 +121,7 @@ void *handle_upstream()
buf = NULL;
ParodusInfo("nanomsg server gone into the listening mode...\n");
bytes = nn_recv (sock, &buf, NN_MSG, 0);
ParodusInfo ("Upstream message received from nanomsg client: \"%s\"\n", (char*)buf);
ParodusInfo ("Upstream message received from nanomsg client\n");
message = (UpStreamMsg *)malloc(sizeof(UpStreamMsg));
if(message)
@@ -158,8 +172,7 @@ void *processUpstreamMessage()
int rv=-1, rc = -1;
int msgType;
wrp_msg_t *msg;
void *appendData, *bytes;
size_t encodedSize;
void *bytes;
reg_list_item_t *temp = NULL;
int matchFlag = 0;
int status = -1;
@@ -197,7 +210,7 @@ void *processUpstreamMessage()
if(strcmp(temp->service_name, msg->u.reg.service_name)==0)
{
ParodusInfo("match found, client is already registered\n");
strncpy(temp->url,msg->u.reg.url, strlen(msg->u.reg.url)+1);
parStrncpy(temp->url,msg->u.reg.url, sizeof(temp->url));
if(nn_shutdown(temp->sock, 0) < 0)
{
ParodusError ("Failed to shutdown\n");
@@ -253,7 +266,7 @@ void *processUpstreamMessage()
}
else if(msgType == WRP_MSG_TYPE__EVENT)
{
ParodusInfo(" Received upstream event data\n");
ParodusInfo(" Received upstream event data: dest '%s'\n", msg->u.event.dest);
partners_t *partnersList = NULL;
int ret = validate_partner_id(msg, &partnersList);
@@ -287,24 +300,14 @@ void *processUpstreamMessage()
else
{
//Sending to server for msgTypes 3, 5, 6, 7, 8.
ParodusInfo(" Received upstream data with MsgType: %d\n", msgType);
//Appending metadata with packed msg received from client
if(metaPackSize > 0)
{
ParodusPrint("Appending received msg with metadata\n");
encodedSize = appendEncodedData( &appendData, message->msg, message->len, metadataPack, metaPackSize );
ParodusPrint("encodedSize after appending :%zu\n", encodedSize);
ParodusPrint("metadata appended upstream msg %s\n", (char *)appendData);
ParodusInfo("Sending metadata appended upstream msg to server\n");
response_queue(appendData,encodedSize);
//free( appendData);
//appendData =NULL;
}
else
{
ParodusError("Failed to send upstream as metadata packing is not successful\n");
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);
}
}
else
@@ -346,10 +349,10 @@ void sendUpstreamMsgToServer(void **resp_bytes, size_t resp_size)
ParodusPrint("encodedSize after appending :%zu\n", encodedSize);
ParodusInfo("Sending response to server\n");
response_queue(appendData,encodedSize);
sendMessage(get_global_conn(),appendData, encodedSize);
//free(appendData);
//appendData =NULL;
free(appendData);
appendData =NULL;
}
else
{
@@ -357,35 +360,3 @@ void sendUpstreamMsgToServer(void **resp_bytes, size_t resp_size)
}
}
void response_queue(void *responseMsg,int reqSize)
{
UpStreamMsg *message = (UpStreamMsg *)malloc(sizeof(UpStreamMsg));
if(message)
{
message->msg =responseMsg;
message->len =reqSize;
message->next=NULL;
pthread_mutex_lock (&res_mutex);
if(ResponseMsgQ == NULL)
{
ResponseMsgQ = message;
pthread_mutex_unlock (&res_mutex);
}
else
{
UpStreamMsg *temp = ResponseMsgQ;
while(temp->next)
{
temp = temp->next;
}
temp->next = message;
pthread_mutex_unlock (&res_mutex);
}
}
else
{
ParodusError("failure in allocation for message\n");
}
}

View File

@@ -1,9 +1,24 @@
/**
* Copyright 2015 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 upstream.h
*
* @description This header defines functions required to manage upstream messages.
*
* Copyright (c) 2015 Comcast
*/
#ifndef _UPSTREAM_H_
@@ -23,10 +38,6 @@ typedef struct UpStreamMsg__
struct UpStreamMsg__ *next;
} UpStreamMsg;
extern pthread_mutex_t res_mutex;
extern UpStreamMsg *ResponseMsgQ;
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
@@ -36,7 +47,6 @@ void *handle_upstream();
void *processUpstreamMessage();
void sendUpstreamMsgToServer(void **resp_bytes, size_t resp_size);
void response_queue(void *responseMsg,int reqSize);
#ifdef __cplusplus
}

View File

@@ -1,4 +1,4 @@
# Copyright 2016 Comcast Cable Communications Management, LLC
# Copyright 2016 Comcast Cable Communications Management, LLCD
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -12,12 +12,23 @@
# See the License for the specific language governing permissions and
# limitations under the License.
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -g -fprofile-arcs -ftest-coverage -O0")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -W -g -fprofile-arcs -ftest-coverage -O0")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DTEST ")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -g -fprofile-arcs -ftest-coverage -O0")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -W -g -fprofile-arcs -ftest-coverage -O0")
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage -O0")
set (PARODUS_COMMON_SRC ../src/string_helpers.c ../src/time.c ../src/config.c ../src/spin_thread.c)
set (PARODUS_COMMON_LIBS gcov -lcunit -lcimplog -llibseshat -lwebsockets -lcrypto -lwrp-c -luuid -lpthread -lm -lmsgpackc -lcjson -ltrower-base64 -lnanomsg -Wl,--no-as-needed -lrt )
set (PARODUS_COMMON_SRC ../src/string_helpers.c ../src/mutex.c ../src/time.c ../src/config.c ../src/spin_thread.c ../src/token.c)
set (PARODUS_COMMON_LIBS gcov -lcunit -lcimplog -lwrp-c
-luuid -lpthread -lmsgpackc -lnopoll -lnanomsg
-Wl,--no-as-needed -lcjson -lcjwt -ltrower-base64
-lssl -lcrypto -lrt -lm)
if (ENABLE_SESHAT)
set (PARODUS_COMMON_LIBS -llibseshat ${PARODUS_COMMON_LIBS})
endif (ENABLE_SESHAT)
if (FEATURE_DNS_QUERY)
set (PARODUS_COMMON_LIBS ${PARODUS_COMMON_LIBS} -lucresolv -lresolv)
endif (FEATURE_DNS_QUERY)
if(NOT DISABLE_VALGRIND)
set (MEMORY_CHECK valgrind --leak-check=full --show-reachable=yes -v)
@@ -25,31 +36,36 @@ endif ()
link_directories ( ${LIBRARY_DIR} )
#-------------------------------------------------------------------------------
# test_mutex
#-------------------------------------------------------------------------------
add_test(NAME test_mutex COMMAND ${MEMORY_CHECK} ./test_mutex)
add_executable(test_mutex test_mutex.c ../src/mutex.c)
target_link_libraries (test_mutex ${PARODUS_COMMON_LIBS} -lcmocka)
#-------------------------------------------------------------------------------
# test_networking
#-------------------------------------------------------------------------------
#add_test(NAME test_networking COMMAND ${MEMORY_CHECK} ./test_networking)
#add_executable(test_networking test_networking.c ../src/networking.c)
#target_link_libraries (test_networking ${PARODUS_COMMON_LIBS})
add_test(NAME test_networking COMMAND ${MEMORY_CHECK} ./test_networking)
add_executable(test_networking test_networking.c ../src/networking.c)
target_link_libraries (test_networking ${PARODUS_COMMON_LIBS})
#-------------------------------------------------------------------------------
# test_nopoll_helpers
#-------------------------------------------------------------------------------
#add_test(NAME test_nopoll_helpers COMMAND ${MEMORY_CHECK} ./test_nopoll_helpers)
#add_executable(test_nopoll_helpers test_nopoll_helpers.c ../src/nopoll_helpers.c)
#target_link_libraries (test_nopoll_helpers -Wl,--no-as-needed -lrt -lcmocka -lcimplog -lnopoll)
add_test(NAME test_nopoll_helpers COMMAND ${MEMORY_CHECK} ./test_nopoll_helpers)
add_executable(test_nopoll_helpers test_nopoll_helpers.c ../src/nopoll_helpers.c)
target_link_libraries (test_nopoll_helpers -Wl,--no-as-needed -lrt -lcmocka -lcimplog -lnopoll)
#-------------------------------------------------------------------------------
# libpd_test
#-------------------------------------------------------------------------------
add_executable (libpd_test libpd_test.c)
add_executable (libpd_test libpd_test.c ../src/string_helpers.c)
target_link_libraries (libpd_test
cunit
-llibparodus
-lwrp-c
-llibseshat
-luuid
-lmsgpackc
-ltrower-base64
@@ -58,7 +74,9 @@ target_link_libraries (libpd_test
-lm
-lpthread
-lrt)
if (ENABLE_SESHAT)
target_link_libraries (libpd_test -llibseshat)
endif (ENABLE_SESHAT)
#-------------------------------------------------------------------------------
# test_time
#-------------------------------------------------------------------------------
@@ -88,47 +106,70 @@ add_executable(test_string_helpers test_string_helpers.c ../src/string_helpers.c
target_link_libraries (test_string_helpers ${PARODUS_COMMON_LIBS} )
#-------------------------------------------------------------------------------
# test_lws_handlers
# test_nopoll_handlers
#-------------------------------------------------------------------------------
add_test(NAME test_lws_handlers COMMAND ${MEMORY_CHECK} ./test_lws_handlers)
add_executable(test_lws_handlers test_lws_handlers.c ../src/lws_handlers.c)
target_link_libraries (test_lws_handlers -lwebsockets -lcrypto -lcunit -lcimplog -Wl,--no-as-needed -lrt -lpthread -lm)
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)
target_link_libraries (test_nopoll_handlers -lnopoll -lcunit -lcimplog -Wl,--no-as-needed -lrt -lpthread -lm)
#-------------------------------------------------------------------------------
# test_connection
#-------------------------------------------------------------------------------
add_test(NAME test_connection COMMAND ${MEMORY_CHECK} ./test_connection)
add_executable(test_connection test_connection.c ../src/connection.c ../src/lws_handlers.c ../src/upstream.c ../src/client_list.c ../src/service_alive.c ../src/partners_check.c ${PARODUS_COMMON_SRC})
#add_executable(test_connection test_connection.c ../src/connection.c ${PARODUS_COMMON_SRC})
#target_link_libraries (test_connection ${PARODUS_COMMON_LIBS} -lcmocka)
set(SOURCES test_connection.c ../src/connection.c ${PARODUS_COMMON_SRC})
add_executable(test_connection ${SOURCES})
#target_link_libraries (test_connection ${PARODUS_CONN_LIBS} ${PARODUS_COMMON_LIBS} -lcmocka)
target_link_libraries (test_connection ${PARODUS_COMMON_LIBS} -lcmocka)
#-------------------------------------------------------------------------------
# test_connection - function createLWSconnection
# test_connection - function createNopollConnection
#-------------------------------------------------------------------------------
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 ../src/lws_handlers.c ../src/upstream.c ../src/client_list.c ../src/partners_check.c ../src/ParodusInternal.c)
target_link_libraries (test_createConnection ${PARODUS_COMMON_LIBS} -lcmocka)
#-------------------------------------------------------------------------------
# test_paroduCallback - function parodus_callback
#-------------------------------------------------------------------------------
add_test(NAME test_parodusCallback COMMAND ${MEMORY_CHECK} ./test_parodusCallback)
add_executable(test_parodusCallback test_parodusCallback.c ../src/connection.c ../src/string_helpers.c ../src/config.c ../src/upstream.c ../src/client_list.c ../src/partners_check.c)
target_link_libraries (test_parodusCallback ${PARODUS_COMMON_LIBS} -lcmocka)
#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)
#target_link_libraries (test_createConnection ${PARODUS_CONN_LIBS} ${PARODUS_COMMON_LIBS} -lcmocka )
target_link_libraries (test_createConnection ${PARODUS_COMMON_LIBS} -lcmocka )
#-------------------------------------------------------------------------------
# test_client_list
#-------------------------------------------------------------------------------
add_test(NAME test_client_list COMMAND ${MEMORY_CHECK} ./test_client_list)
add_executable(test_client_list test_client_list.c ../src/client_list.c ../src/service_alive.c ../src/upstream.c ../src/downstream.c ../src/connection.c ../src/lws_handlers.c ../src/ParodusInternal.c ../src/thread_tasks.c ../src/conn_interface.c ../src/partners_check.c ${PARODUS_COMMON_SRC})
#add_executable(test_client_list 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/ParodusInternal.c ../src/thread_tasks.c ../src/conn_interface.c ../src/partners_check.c ${PARODUS_COMMON_SRC})
#target_link_libraries (test_client_list ${PARODUS_COMMON_LIBS})
set(SOURCES 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/ParodusInternal.c ../src/thread_tasks.c ../src/conn_interface.c
../src/partners_check.c ${PARODUS_COMMON_SRC})
if (ENABLE_SESHAT)
set(SOURCES ${SOURCES} ../src/seshat_interface.c)
else()
set(SOURCES ${SOURCES} ../src/seshat_interface_stub.c)
endif (ENABLE_SESHAT)
add_executable(test_client_list ${SOURCES})
#target_link_libraries (test_client_list ${PARODUS_CONN_LIBS} ${PARODUS_COMMON_LIBS})
target_link_libraries (test_client_list ${PARODUS_COMMON_LIBS})
#-------------------------------------------------------------------------------
# test_service_alive
#-------------------------------------------------------------------------------
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/lws_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})
#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(SOURCES 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})
if (ENABLE_SESHAT)
set(SOURCES ${SOURCES} ../src/seshat_interface.c)
else()
set(SOURCES ${SOURCES} ../src/seshat_interface_stub.c)
endif (ENABLE_SESHAT)
add_executable(test_service_alive ${SOURCES})
#target_link_libraries (test_service_alive ${PARODUS_CONN_LIBS} ${PARODUS_COMMON_LIBS})
target_link_libraries (test_service_alive ${PARODUS_COMMON_LIBS})
#-------------------------------------------------------------------------------
@@ -136,13 +177,16 @@ target_link_libraries (test_service_alive ${PARODUS_COMMON_LIBS})
#-------------------------------------------------------------------------------
add_test(NAME test_config COMMAND ${MEMORY_CHECK} ./test_config)
add_executable(test_config test_config.c ../src/config.c ../src/string_helpers.c)
target_link_libraries (test_config -lcmocka -lm -Wl,--no-as-needed -lrt -lcimplog)
target_link_libraries (test_config -lcmocka
-Wl,--no-as-needed -lcimplog
-lcjson -lcjwt -ltrower-base64 -lssl -lcrypto -lrt -lm
)
#-------------------------------------------------------------------------------
# test_upstream
#-------------------------------------------------------------------------------
add_test(NAME test_upstream COMMAND ${MEMORY_CHECK} ./test_upstream)
add_executable(test_upstream test_upstream.c ../src/upstream.c)
add_executable(test_upstream test_upstream.c ../src/upstream.c ../src/string_helpers.c)
target_link_libraries (test_upstream -lcmocka ${PARODUS_COMMON_LIBS} )
#-------------------------------------------------------------------------------
@@ -152,6 +196,13 @@ add_test(NAME test_downstream COMMAND ${MEMORY_CHECK} ./test_downstream)
add_executable(test_downstream test_downstream.c ../src/downstream.c ../src/string_helpers.c)
target_link_libraries (test_downstream -lcmocka ${PARODUS_COMMON_LIBS} )
#-------------------------------------------------------------------------------
# test_downstream_more
#-------------------------------------------------------------------------------
add_test(NAME test_downstream_more COMMAND ${MEMORY_CHECK} ./test_downstream_more)
add_executable(test_downstream_more test_downstream_more.c ../src/downstream.c ../src/string_helpers.c)
target_link_libraries (test_downstream_more -lcmocka ${PARODUS_COMMON_LIBS} )
#-------------------------------------------------------------------------------
# test_thread_tasks
#-------------------------------------------------------------------------------
@@ -163,7 +214,13 @@ target_link_libraries (test_thread_tasks -lcmocka ${PARODUS_COMMON_LIBS} )
# test_conn_interface
#-------------------------------------------------------------------------------
add_test(NAME test_conn_interface COMMAND ${MEMORY_CHECK} ./test_conn_interface)
add_executable(test_conn_interface test_conn_interface.c ../src/conn_interface.c ../src/config.c ../src/string_helpers.c )
set(SOURCES test_conn_interface.c ../src/conn_interface.c ../src/config.c ../src/string_helpers.c ../src/mutex.c)
if (ENABLE_SESHAT)
set(SOURCES ${SOURCES} ../src/seshat_interface.c)
else()
set(SOURCES ${SOURCES} ../src/seshat_interface_stub.c)
endif (ENABLE_SESHAT)
add_executable(test_conn_interface ${SOURCES})
target_link_libraries (test_conn_interface -lcmocka ${PARODUS_COMMON_LIBS} )
#-------------------------------------------------------------------------------
@@ -177,46 +234,56 @@ target_link_libraries (test_ParodusInternal -lcmocka ${PARODUS_COMMON_LIBS} )
# test_partners_check
#-------------------------------------------------------------------------------
add_test(NAME test_partners_check COMMAND ${MEMORY_CHECK} ./test_partners_check)
add_executable(test_partners_check test_partners_check.c ../src/partners_check.c)
target_link_libraries (test_partners_check -lcmocka ${PARODUS_COMMON_LIBS})
add_executable(test_partners_check test_partners_check.c ../src/partners_check.c ../src/string_helpers.c)
target_link_libraries (test_partners_check -lcmocka ${PARODUS_COMMON_LIBS} -lwrp-c)
#-------------------------------------------------------------------------------
# test_token - token.c tests
#-------------------------------------------------------------------------------
add_test(NAME test_token COMMAND ${MEMORY_CHECK} ./test_token)
add_executable(test_token ${SOURCES} )
#target_link_libraries (test_token ${PARODUS_COMMON_LIBS} ${PARODUS_JWT_LIBS} -lcmocka )
target_link_libraries (test_token ${PARODUS_COMMON_LIBS} -lcmocka )
#-------------------------------------------------------------------------------
# test_seshat_interface - registerWithSeshat
#-------------------------------------------------------------------------------
add_test(NAME test_seshat_interface COMMAND ${MEMORY_CHECK} ./test_seshat_interface)
if (ENABLE_SESHAT)
set(SOURCES test_seshat_interface.c ../src/seshat_interface.c ../src/string_helpers.c)
else()
set(SOURCES test_seshat_interface_stub.c ../src/seshat_interface_stub.c)
endif (ENABLE_SESHAT)
add_executable(test_seshat_interface ${SOURCES})
target_link_libraries (test_seshat_interface -lcmocka ${PARODUS_COMMON_LIBS} -lwrp-c)
if (INTEGRATION_TESTING)
#-------------------------------------------------------------------------------
# simple_connection test
#-------------------------------------------------------------------------------
add_test(NAME simple_connection COMMAND ${MEMORY_CHECK} ./simple_connection)
add_executable(simple_connection simple_connection.c ${PARODUS_COMMON_SRC}
../src/upstream.c
../src/conn_interface.c
../src/thread_tasks.c
../src/downstream.c
../src/lws_handlers.c
../src/connection.c
../src/ParodusInternal.c
../src/client_list.c
../src/partners_check.c
../src/service_alive.c)
target_link_libraries (simple_connection ${PARODUS_COMMON_LIBS})
set(SOURCES simple_connection.c ${PARODUS_COMMON_SRC} ../src/upstream.c ../src/conn_interface.c
../src/thread_tasks.c ../src/downstream.c ../src/networking.c ../src/nopoll_helpers.c ../src/nopoll_handlers.c ../src/connection.c ../src/ParodusInternal.c ../src/client_list.c ../src/partners_check.c ../src/service_alive.c)
if (ENABLE_SESHAT)
set(SOURCES ${SOURCES} ../src/seshat_interface.c)
else()
set(SOURCES ${SOURCES} ../src/seshat_interface_stub.c)
endif (ENABLE_SESHAT)
add_executable(simple_connection ${SOURCES})
target_link_libraries (simple_connection ${PARODUS_CONN_LIBS} ${PARODUS_COMMON_LIBS} )
#-------------------------------------------------------------------------------
# simple test
#-------------------------------------------------------------------------------
add_test(NAME simple COMMAND ${MEMORY_CHECK} ./simple)
add_executable(simple simple.c
../src/upstream.c
../src/conn_interface.c
../src/downstream.c
../src/thread_tasks.c
../src/lws_handlers.c
../src/string_helpers.c
../src/time.c
../src/config.c
../src/connection.c
../src/ParodusInternal.c
../src/spin_thread.c
../src/client_list.c
../src/partners_check.c
../src/service_alive.c)
set(SOURCES simple.c ../src/upstream.c ../src/conn_interface.c ../src/downstream.c ../src/thread_tasks.c ../src/networking.c ../src/nopoll_helpers.c ../src/nopoll_handlers.c ../src/string_helpers.c ../src/mutex.c ../src/time.c
../src/config.c ../src/connection.c ../src/ParodusInternal.c ../src/spin_thread.c ../src/client_list.c ../src/partners_check.c ../src/service_alive.c)
if (ENABLE_SESHAT)
set(SOURCES ${SOURCES} ../src/seshat_interface.c)
else()
set(SOURCES ${SOURCES} ../src/seshat_interface_stub.c)
endif (ENABLE_SESHAT)
add_executable(simple ${SOURCES})
target_link_libraries (simple ${PARODUS_COMMON_LIBS} gcov -lnanomsg )
target_link_libraries (simple ${PARODUS_CONN_LIBS} ${PARODUS_COMMON_LIBS} gcov -lnopoll -lnanomsg )
endif (INTEGRATION_TESTING)

View File

@@ -28,6 +28,7 @@
#include <libparodus.h>
#include <pthread.h>
#include "../src/ParodusInternal.h"
#define SEND_EVENT_MSGS 1
@@ -127,7 +128,7 @@ char *new_str (const char *str)
char *buf = malloc (strlen(str) + 1);
if (NULL == buf)
return NULL;
strcpy (buf, str);
parStrncpy(buf, str, (strlen(str)+1));
return buf;
}

3
tests/parodus_cmd.sh Executable file
View File

@@ -0,0 +1,3 @@
sudo ./parodus --hw-model=TG1682 --hw-serial-number=Fer23u948590 --hw-manufacturer=ARRISGroup,Inc. --hw-mac=aabb33ddeeff --hw-last-reboot-reason=unknown --fw-name=TG1682_DEV_master_2016000000sdy --boot-time=123589 --webpa-ping-timeout=180 --webpa-backoff-max=0 --webpa-interface-used=p7p1 --webpa-url=https://example.net:8080 --acquire-jwt=1 --jwt-algo=RS256 --jwt-public-key-file=../../tests/webpa-rs256.pem --dns-txt-url=example.net

View File

@@ -1,712 +0,0 @@
/**
* Copyright 2010-2016 Comcast Cable Communications Management, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdarg.h>
#include <CUnit/Basic.h>
#include <stdbool.h>
#include <assert.h>
#include <nopoll.h>
//#include <nanomsg/bus.h>
#include "../src/ParodusInternal.h"
#include "../src/config.h"
#include "../src/nopoll_helpers.h"
#include "../src/downstream.h"
#include "../src/upstream.h"
#include<errno.h>
/* Nanomsg related Macros */
#define ENDPOINT "tcp://127.0.0.1:6666"
#define CLIENT1_URL "tcp://127.0.0.1:6667"
#define CLIENT2_URL "tcp://127.0.0.1:6668"
#define CLIENT3_URL "tcp://127.0.0.1:6669"
#define HTTP_CUSTOM_HEADER_COUNT 4
static void send_nanomsg_upstream(void **buf, int size);
void *handle_testsuites();
headers_t headers = { 2, {"Header 1", "Header 2"}};
void test_nanomsg_client_registration1()
{
/*****Test svc registation for nanomsg client1 ***/
ParodusInfo("test_nanomsg_client_registration1\n");
const wrp_msg_t reg = { .msg_type = WRP_MSG_TYPE__SVC_REGISTRATION,
.u.reg.service_name = "iot",
.u.reg.url = CLIENT1_URL};
void *bytes;
int size =0;
int rv1, rc;
wrp_msg_t *msg1;
int sock, bind;
int byte =0;
int t=25000;
// msgpack encode
ParodusPrint("msgpack encode\n");
size = wrp_struct_to( &reg, WRP_BYTES, &bytes );
/*** Enable this to decode and verify upstream registration msg **/
/***
rv = wrp_to_struct(bytes, size, WRP_BYTES, &message);
ParodusPrint("decoded msgType:%d\n", message->msg_type);
ParodusPrint("decoded service_name:%s\n", message->u.reg.service_name);
ParodusPrint("decoded dest:%s\n", message->u.reg.url);
wrp_free_struct(message);
***/
//nanomsg socket
sock = nn_socket (AF_SP, NN_PUSH);
int connect = nn_connect (sock, ENDPOINT);
CU_ASSERT(connect >= 0);
rc = nn_setsockopt(sock, NN_SOL_SOCKET, NN_SNDTIMEO, &t, sizeof(t));
CU_ASSERT(rc >= 0);
byte = nn_send (sock, bytes, size, 0);
ParodusInfo("----->Expected byte to be sent:%d\n", size);
ParodusInfo("----->actual byte sent:%d\n", byte);
ParodusInfo("Nanomsg client1 - Testing Upstream Registration msg send\n");
CU_ASSERT_EQUAL( byte, size );
//************************************************************
int sock1 = nn_socket (AF_SP, NN_PULL);
byte = 0;
bind = nn_bind(sock1, reg.u.reg.url);
CU_ASSERT(bind >= 0);
void *buf = NULL;
rc = nn_setsockopt(sock1, NN_SOL_SOCKET, NN_RCVTIMEO, &t, sizeof(t));
CU_ASSERT(rc >= 0);
ParodusPrint("Client 1 waiting for acknowledgement \n");
byte = nn_recv(sock1, &buf, NN_MSG, 0);
ParodusInfo("Data Received for client 1 : %s \n", (char * )buf);
rv1 = wrp_to_struct((void *)buf, byte, WRP_BYTES, &msg1);
CU_ASSERT_EQUAL( rv1, byte );
ParodusPrint("msg1->msg_type for client 1 = %d \n", msg1->msg_type);
ParodusPrint("msg1->status for client 1 = %d \n", msg1->u.auth.status);
CU_ASSERT_EQUAL(msg1->msg_type, 2);
CU_ASSERT_EQUAL(msg1->u.auth.status, 200);
rc = nn_freemsg(buf);
CU_ASSERT(rc == 0);
free(bytes);
wrp_free_struct(msg1);
rc = nn_shutdown(sock1, bind);
CU_ASSERT(rc == 0);
}
void test_nanomsg_client_registration2()
{
/*****Test svc registation for upstream - nanomsg client2 ***/
ParodusInfo("test_nanomsg_client_registration2\n");
const wrp_msg_t reg = { .msg_type = WRP_MSG_TYPE__SVC_REGISTRATION,
.u.reg.service_name = "iot2",
.u.reg.url = CLIENT2_URL};
void *bytes;
int size;
int rv1, rc;
wrp_msg_t *msg1;
int sock, bind;
int byte =0;
int t=28000;
// msgpack encode
ParodusPrint("msgpack encode\n");
size = wrp_struct_to( &reg, WRP_BYTES, &bytes );
/*** Enable this to decode and verify packed upstream registration msg **/
/**
rv = wrp_to_struct(bytes, size, WRP_BYTES, &message);
ParodusPrint("decoded msgType:%d\n", message->msg_type);
ParodusPrint("decoded service_name:%s\n", message->u.reg.service_name);
ParodusPrint("decoded dest:%s\n", message->u.reg.url);
wrp_free_struct(message);
***/
//nanomsg socket
sock = nn_socket (AF_SP, NN_PUSH);
int connect = nn_connect (sock, ENDPOINT);
CU_ASSERT( connect >= 0);
rc = nn_setsockopt(sock, NN_SOL_SOCKET, NN_SNDTIMEO, &t, sizeof(t));
CU_ASSERT(rc >= 0);
byte = nn_send (sock, bytes, size,0);
ParodusInfo("----->Expected byte to be sent:%d\n", size);
ParodusInfo("----->actual byte sent:%d\n", byte);
ParodusInfo("Nanomsg client2 - Testing Upstream Registration msg send\n");
CU_ASSERT_EQUAL( byte, size );
int sock1 = nn_socket (AF_SP, NN_PULL);
byte = 0;
bind = nn_bind(sock1, reg.u.reg.url);
CU_ASSERT(bind >= 0);
void *buf1 = NULL;
rc = nn_setsockopt(sock1, NN_SOL_SOCKET, NN_RCVTIMEO, &t, sizeof(t));
CU_ASSERT(rc >= 0);
ParodusPrint("Client 2 waiting for acknowledgement \n");
byte = nn_recv(sock1, &buf1, NN_MSG, 0);
ParodusInfo("Data Received : %s \n", (char * )buf1);
rv1 = wrp_to_struct((void *)buf1, byte, WRP_BYTES, &msg1);
CU_ASSERT_EQUAL( rv1, byte );
ParodusPrint("msg1->msg_type for client 2 = %d \n", msg1->msg_type);
ParodusPrint("msg1->status for client 2 = %d \n", msg1->u.auth.status);
CU_ASSERT_EQUAL(msg1->msg_type, 2);
CU_ASSERT_EQUAL(msg1->u.auth.status, 200);
rc = nn_freemsg(buf1);
CU_ASSERT(rc == 0);
free(bytes);
wrp_free_struct(msg1);
rc = nn_shutdown(sock1, bind);
CU_ASSERT(rc == 0);
}
void test_nanomsg_client_registration3()
{
/*****Test svc registation for upstream - nanomsg client2 ***/
ParodusInfo("test_nanomsg_client_registration3\n");
const wrp_msg_t reg = { .msg_type = WRP_MSG_TYPE__SVC_REGISTRATION,
.u.reg.service_name = "iot",
.u.reg.url = CLIENT3_URL};
void *bytes;
int size;
int rv1, rc;
wrp_msg_t *msg1;
int sock;
int byte =0;
int t=35000;
// msgpack encode
ParodusPrint("msgpack encode\n");
size = wrp_struct_to( &reg, WRP_BYTES, &bytes );
/*** Enable this to decode and verify packed upstream registration msg **/
/**
rv = wrp_to_struct(bytes, size, WRP_BYTES, &message);
ParodusPrint("decoded msgType:%d\n", message->msg_type);
ParodusPrint("decoded service_name:%s\n", message->u.reg.service_name);
ParodusPrint("decoded dest:%s\n", message->u.reg.url);
wrp_free_struct(message);
***/
//nanomsg socket
sock = nn_socket (AF_SP, NN_PUSH);
int connect = nn_connect (sock, ENDPOINT);
CU_ASSERT(connect >= 0);
rc = nn_setsockopt(sock, NN_SOL_SOCKET, NN_SNDTIMEO, &t, sizeof(t));
CU_ASSERT(rc >= 0);
byte = nn_send (sock, bytes, size,0);
ParodusInfo("----->Expected byte to be sent:%d\n", size);
ParodusInfo("----->actual byte sent:%d\n", byte);
ParodusInfo("Nanomsg client3 - Testing Upstream Registration msg send\n");
CU_ASSERT_EQUAL( byte, size );
int sock1 = nn_socket (AF_SP, NN_PULL);
byte = 0;
int bind = nn_bind(sock1, reg.u.reg.url);
CU_ASSERT(bind >= 0);
ParodusPrint("Need to close this bind %d \n", bind);
void *buf2 = NULL;
rc = nn_setsockopt(sock1, NN_SOL_SOCKET, NN_RCVTIMEO, &t, sizeof(t));
CU_ASSERT(rc >= 0);
ParodusPrint("Client 3 is waiting for acknowledgement \n");
byte = nn_recv(sock1, &buf2, NN_MSG, 0);
ParodusInfo("Data Received : %s \n", (char * )buf2);
rv1 = wrp_to_struct((void *)buf2, byte, WRP_BYTES, &msg1);
CU_ASSERT_EQUAL( rv1, byte );
ParodusPrint("msg1->msg_type for client 3 = %d \n", msg1->msg_type);
ParodusPrint("msg1->status for client 3 = %d \n", msg1->u.auth.status);
CU_ASSERT_EQUAL(msg1->msg_type, 2);
CU_ASSERT_EQUAL(msg1->u.auth.status, 200);
rc = nn_freemsg(buf2);
CU_ASSERT(rc == 0);
free(bytes);
wrp_free_struct(msg1);
rc = nn_shutdown(sock1, bind);
CU_ASSERT(rc == 0);
}
void test_nanomsg_downstream_success()
{
ParodusInfo("test_nanomsg_downstream_success\n");
int sock;
int bit=0, rc;
wrp_msg_t *message;
void *buf =NULL;
char* destVal = NULL;
// char dest[32] = {'\0'};
char *dest = NULL;
//char *temp_ptr;
int bind = -1;
const wrp_msg_t msg = { .msg_type = WRP_MSG_TYPE__SVC_REGISTRATION,
.u.reg.service_name = "iot",
.u.reg.url = CLIENT3_URL};
sock = nn_socket (AF_SP, NN_PULL);
while(bind == -1)
{
bind = nn_bind(sock, msg.u.reg.url);
sleep(3);
}
ParodusPrint("Bind returns = %d \n", bind);
ParodusPrint("***** Nanomsg client3 in Receiving mode in %s *****\n", msg.u.reg.url);
bit = nn_recv (sock, &buf, NN_MSG, 0);
ParodusInfo ("----->Received downstream request from server to client3 : \"%s\"\n", (char *)buf);
ParodusPrint("Received %d bytes\n", bit);
CU_ASSERT(bit >= 0);
//Decode and verify downstream request has received by correct registered client
wrp_to_struct(buf, bit, WRP_BYTES, &message);
destVal = message->u.req.dest;
dest = strtok(destVal , "/");
//temp_ptr = strtok(destVal , "/");
// ParodusPrint("temp_ptr = %s \n", temp_ptr);
strcpy(dest,strtok(NULL , "/"));
ParodusInfo("------>decoded dest:%s\n", dest);
CU_ASSERT_STRING_EQUAL( msg.u.reg.service_name, dest );
wrp_free_struct(message);
//To send nanomsg client response upstream
send_nanomsg_upstream(&buf, bit);
rc = nn_freemsg(buf);
CU_ASSERT(rc == 0);
rc = nn_shutdown(sock, bind);
CU_ASSERT(rc == 0);
//Need to wait for parodus to finish it's task.
sleep(10);
}
void test_nanomsg_downstream_failure()
{
int sock, bind, rc;
int bit =0;
char *buf =NULL;
ParodusError("test_nanomsg_downstream_failure\n");
sleep(60);
sock = nn_socket (AF_SP, NN_PULL);
bind = nn_bind (sock, CLIENT3_URL);
CU_ASSERT(bind >= 0);
ParodusPrint("***** Nanomsg client3 in Receiving mode *****\n");
bit = nn_recv (sock, &buf, NN_MSG, 0);
ParodusInfo ("Received downstream request from server for client3 : \"%s\"\n", buf);
CU_ASSERT(bit >= 0);
rc = nn_freemsg(buf);
CU_ASSERT(rc == 0);
rc = nn_shutdown(sock, bind);
CU_ASSERT(rc == 0);
}
void test_checkHostIp()
{
int ret;
ParodusPrint("**********************************Calling check_host_ip \n");
ret = checkHostIp("fabric.webpa.comcast.net");
ParodusPrint("------------------> Ret = %d \n", ret);
CU_ASSERT_EQUAL(ret, 0);
}
void test_sendMessage()
{
noPollConnOpts * opts;
noPollCtx *ctx = NULL;
noPollConn *conn = NULL;
ParodusPrint("**********************************Calling sendMessage \n");
const char * headerNames[HTTP_CUSTOM_HEADER_COUNT] = {"X-WebPA-Device-Name","X-WebPA-Device-Protocols","User-Agent", "X-WebPA-Convey"};
const char * headerValues[HTTP_CUSTOM_HEADER_COUNT];
headerValues[0] = "123567892366";
headerValues[1] = "wrp-0.11,getset-0.1";
headerValues[2] = "WebPA-1.6 (TG1682_DEV_master_2016000000sdy;TG1682/ARRISGroup,Inc.;)";
headerValues[3] = "zacbvfxcvglodfjdigjkdshuihgkvn";
int headerCount = HTTP_CUSTOM_HEADER_COUNT;
//ctx = nopoll_ctx_new();
opts = nopoll_conn_opts_new ();
nopoll_conn_opts_ssl_peer_verify (opts, nopoll_false);
nopoll_conn_opts_set_ssl_protocol (opts, NOPOLL_METHOD_TLSV1_2);
conn = nopoll_conn_tls_new(ctx, opts, "fabric.webpa.comcast.net", "8080", NULL, "/api/v2/device", NULL, NULL, "eth0",
headerNames, headerValues, headerCount);
/*while(conn == NULL)
{
opts = nopoll_conn_opts_new ();
nopoll_conn_opts_ssl_peer_verify (opts, nopoll_false);
nopoll_conn_opts_set_ssl_protocol (opts, NOPOLL_METHOD_TLSV1_2);
conn = nopoll_conn_tls_new(ctx, opts, "fabric.webpa.comcast.net", 8080, NULL, "/api/v2/device", NULL, NULL, "eth0",
headerNames, headerValues, headerCount);
}*/
ParodusPrint("Sending conn as %p \n", conn);
sendMessage(conn, "hello", 6);
}
void test_parseCommandLine()
{
int argc =11;
char * command[15]={'\0'};
command[0] = "parodus";
command[1] = "--hw-model=TG1682";
command[2] = "--hw-serial-number=Fer23u948590";
command[3] = "--hw-manufacturer=ARRISGroup,Inc.";
command[4] = "--hw-mac=123567892366";
command[5] = "--hw-last-reboot-reason=unknown";
command[6] = "--fw-name=TG1682_DEV_master_2016000000sdy";
command[7] = "--webpa-ping-time=180";
command[8] = "--webpa-inteface-used=eth0";
command[9] = "--webpa-url=fabric.webpa.comcast.net";
command[10] = "--webpa-backoff-max=0";
ParodusCfg parodusCfg;
memset(&parodusCfg,0,sizeof(parodusCfg));
ParodusPrint("call parseCommand\n");
parseCommandLine(argc,command,&parodusCfg);
ParodusPrint("parodusCfg.webpa_ping_timeout is %d\n", parodusCfg.webpa_ping_timeout);
ParodusPrint("parodusCfg.webpa_backoff_max is %d\n", parodusCfg.webpa_backoff_max);
CU_ASSERT_STRING_EQUAL( parodusCfg.hw_model, "TG1682");
CU_ASSERT_STRING_EQUAL( parodusCfg.hw_serial_number, "Fer23u948590");
CU_ASSERT_STRING_EQUAL( parodusCfg.hw_manufacturer, "ARRISGroup,Inc.");
CU_ASSERT_STRING_EQUAL( parodusCfg.hw_mac, "123567892366");
CU_ASSERT_STRING_EQUAL( parodusCfg.hw_last_reboot_reason, "unknown");
CU_ASSERT_STRING_EQUAL( parodusCfg.fw_name, "TG1682_DEV_master_2016000000sdy");
CU_ASSERT( parodusCfg.webpa_ping_timeout==180);
CU_ASSERT_STRING_EQUAL( parodusCfg.webpa_interface_used, "eth0");
CU_ASSERT_STRING_EQUAL( parodusCfg.webpa_url, "fabric.webpa.comcast.net");
CU_ASSERT( parodusCfg.webpa_backoff_max==0);
}
void test_loadParodusCfg()
{
ParodusPrint("Calling test_loadParodusCfg \n");
//ParodusCfg parodusCfg, tmpcfg;
ParodusCfg tmpcfg;
ParodusCfg *Cfg;
Cfg = (ParodusCfg*)malloc(sizeof(ParodusCfg));
strcpy(Cfg->hw_model, "TG1682");
strcpy(Cfg->hw_serial_number, "Fer23u948590");
strcpy(Cfg->hw_manufacturer , "ARRISGroup,Inc.");
strcpy(Cfg->hw_mac , "123567892366");
memset(&tmpcfg,0,sizeof(tmpcfg));
loadParodusCfg(Cfg,&tmpcfg);
ParodusInfo("tmpcfg.hw_model = %s, tmpcfg.hw_serial_number = %s, tmpcfg.hw_manufacturer = %s, tmpcfg.hw_mac = %s, \n", tmpcfg.hw_model,tmpcfg.hw_serial_number, tmpcfg.hw_manufacturer, tmpcfg.hw_mac);
CU_ASSERT_STRING_EQUAL( tmpcfg.hw_model, "TG1682");
CU_ASSERT_STRING_EQUAL( tmpcfg.hw_serial_number, "Fer23u948590");
CU_ASSERT_STRING_EQUAL( tmpcfg.hw_manufacturer, "ARRISGroup,Inc.");
CU_ASSERT_STRING_EQUAL( tmpcfg.hw_mac, "123567892366");
}
void add_suites( CU_pSuite *suite )
{
ParodusInfo("--------Start of Test Cases Execution ---------\n");
*suite = CU_add_suite( "tests", NULL, NULL );
CU_add_test( *suite, "Test 1", test_nanomsg_client_registration1 );
CU_add_test( *suite, "Test 2", test_nanomsg_client_registration2 );
CU_add_test( *suite, "Test 3", test_nanomsg_client_registration3 );
CU_add_test( *suite, "Test 4", test_nanomsg_downstream_success );
//CU_add_test( *suite, "Test 5", test_nanomsg_downstream_failure );
ParodusInfo("-------------Integration testing is completed-----------\n");
ParodusInfo("******************************************************************\n");
//sleep(10);
ParodusInfo("-------------Start of Unit Test Cases Execution---------\n");
CU_add_test( *suite, "UnitTest 1", test_parseCommandLine );
CU_add_test( *suite, "UnitTest 2", test_checkHostIp );
CU_add_test( *suite, "UnitTest 3", test_sendMessage );
CU_add_test( *suite, "UnitTest 4", test_loadParodusCfg );
}
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
int main( void )
{
pid_t pid, pid1;
char value[512] = {'\0'};
char* data =NULL;
int status;
char commandUrl[255];
pid_t curl_pid;
char * command[] = {"parodus","--hw-model=TG1682", "--hw-serial-number=Fer23u948590","--hw-manufacturer=ARRISGroup,Inc.","--hw-mac=123567892366","--hw-last-reboot-reason=unknown","--fw-name=TG1682_DEV_master_2016000000sdy","--boot-time=10","--webpa-ping-time=180","--webpa-inteface-used=eth0","--webpa-url=fabric-cd.webpa.comcast.net","--webpa-backoff-max=9", NULL};
//int size = sizeof(command)/sizeof(command[0]);
//int i;
//ParodusInfo("commad: ");
//for(i=0;i<size-1;i++)
//ParodusInfo("command:%s",command);
ParodusInfo("Starting parodus process \n");
const char *s = getenv("WEBPA_AUTH_HEADER");
sprintf(commandUrl, "curl -i -H \"Authorization:Basic %s\" -H \"Accept: application/json\" -w %%{time_total} -k \"https://api-cd.webpa.comcast.net:8090/api/v2/device/mac:123567892366/iot?names=Device.DeviceInfo.Webpa.X_COMCAST-COM_SyncProtocolVersion\"", s);
ParodusPrint("---------------------->>>>Executing system(commandUrl)\n");
curl_pid = getpid();
ParodusPrint("child process execution with curl_pid:%d\n", curl_pid);
pid = fork();
if (pid == -1)
{
ParodusError("fork was unsuccessful for pid (errno=%d, %s)\n",errno, strerror(errno));
return -1;
}
else if (pid == 0)
{
int err;
ParodusPrint("child process created for parodus\n");
pid = getpid();
ParodusPrint("child process execution with pid:%d\n", pid);
err = execv("../src/parodus", command);
if(errno == 2)
{
err = execv("./src/parodus", command);
}
ParodusError("err is %d, errno is %d\n",err, errno);
}
else if (pid > 0)
{
int link[2];
sleep(5);
//Starting test suites execution in new thread
ParodusPrint("Creating new thread for test suite execution\n");
pthread_t testId;
int err1 = 0;
err1 = pthread_create(&testId,NULL,handle_testsuites,(void *)&pid);
if(err1 != 0)
ParodusError("Error creating test suite thread %s\n",strerror(err1));
else
ParodusPrint("test suite thread created successfully\n");
if (pipe(link)==-1)
{
ParodusError("Failed to create pipe\n");
}
else
ParodusPrint("Created pipe to read curl output\n");
pid1 = fork();
if (pid1 == -1)
{
ParodusError("fork was unsuccessful for pid1 (errno=%d, %s)\n",errno, strerror(errno));
return -1;
}
else if(pid1 == 0)
{
while(NULL == fopen("/tmp/parodus_ready", "r"))
{
sleep(5);
}
dup2 (link[1], STDOUT_FILENO);
close(link[0]);
close(link[1]);
sleep(40);
system(commandUrl);
ParodusInfo("\n----Executed first Curl request for downstream ------- \n");
}
else if(pid1 > 0)
{
//wait fro child process to finish and read from pipe
waitpid(pid1, &status, 0);
//reading from pipe
ParodusPrint("parent process...:%d\n", pid1);
close(link[1]);
int nbytes = read(link[0], value, sizeof(value));
ParodusPrint("Read %d \n", nbytes);
if ((data = strstr(value, "message:Success")) !=NULL)
{
ParodusInfo("curl success\n");
}
else
{
ParodusError("curl failure..\n");
}
while(1);
}
}
return 0;
}
void *handle_testsuites(void* pid)
{
unsigned rv = 1;
CU_pSuite suite = NULL;
pid_t pid_parodus = *((int *)pid);
ParodusPrint("Starting handle_testsuites thread\n");
sleep(25);
if( CUE_SUCCESS == CU_initialize_registry() )
{
add_suites( &suite );
if( NULL != suite )
{
CU_basic_set_mode( CU_BRM_VERBOSE );
CU_basic_run_tests();
ParodusPrint( "\n" );
CU_basic_show_failures( CU_get_failure_list() );
ParodusPrint( "\n\n" );
rv = CU_get_number_of_tests_failed();
}
CU_cleanup_registry();
}
kill(pid_parodus, SIGKILL);
ParodusInfo("parodus process with pid %d is stopped\n", pid_parodus);
if( 0 != rv )
{
_exit(-1);
}
_exit(0);
}
static void send_nanomsg_upstream(void **buf, int size)
{
/**** To send nanomsg response to server ****/
int rv;
void *bytes;
int resp_size;
int sock;
int byte;
wrp_msg_t *message;
ParodusInfo("Decoding downstream request received from server\n");
rv = wrp_to_struct(*buf, size, WRP_BYTES, &message);
ParodusPrint("after downstream req decode:%d\n", rv);
/**** Preparing Nanomsg client response ****/
wrp_msg_t resp_m;
resp_m.msg_type = WRP_MSG_TYPE__REQ;
ParodusPrint("resp_m.msg_type:%d\n", resp_m.msg_type);
resp_m.u.req.source = message->u.req.dest;
ParodusPrint("------resp_m.u.req.source is:%s\n", resp_m.u.req.source);
resp_m.u.req.dest = message->u.req.source;
ParodusPrint("------resp_m.u.req.dest is:%s\n", resp_m.u.req.dest);
resp_m.u.req.transaction_uuid = message->u.req.transaction_uuid;
ParodusPrint("------resp_m.u.req.transaction_uuid is:%s\n", resp_m.u.req.transaction_uuid);
resp_m.u.req.headers = NULL;
resp_m.u.req.payload = "{statusCode:200,message:Success}";
ParodusPrint("------resp_m.u.req.payload is:%s\n", (char *)resp_m.u.req.payload);
resp_m.u.req.payload_size = strlen(resp_m.u.req.payload);
resp_m.u.req.metadata = NULL;
resp_m.u.req.include_spans = false;
resp_m.u.req.spans.spans = NULL;
resp_m.u.req.spans.count = 0;
ParodusPrint("Encoding downstream response\n");
resp_size = wrp_struct_to( &resp_m, WRP_BYTES, &bytes );
/*** Enable this to verify downstream response by decoding ***/
/***
wrp_msg_t *message1;
rv = wrp_to_struct(bytes, resp_size, WRP_BYTES, &message1);
ParodusPrint("after downstream response decode:%d\n", rv);
ParodusPrint("downstream response decoded msgType:%d\n", message1->msg_type);
ParodusPrint("downstream response decoded source:%s\n", message1->u.req.source);
ParodusPrint("downstream response decoded dest:%s\n", message1->u.req.dest);
ParodusPrint("downstream response decoded transaction_uuid:%s\n", message1->u.req.transaction_uuid);
ParodusPrint("downstream response decoded payload:%s\n", (char*)message1->u.req.payload);
wrp_free_struct(message1);
***/
/**** Nanomsg client sending msgs ****/
sock = nn_socket (AF_SP, NN_PUSH);
int connect = nn_connect (sock, ENDPOINT);
CU_ASSERT(connect >= 0);
sleep(1);
ParodusInfo("nanomsg client sending response upstream\n");
byte = nn_send (sock, bytes, resp_size,0);
ParodusInfo("----->Expected byte to be sent:%d\n", resp_size);
ParodusInfo("----->actual byte sent:%d\n", byte);
CU_ASSERT(byte==resp_size );
wrp_free_struct(message);
free(bytes);
ParodusPrint("---- End of send_nanomsg_upstream ----\n");
}

View File

@@ -66,17 +66,17 @@ void test_set_parodus_cfg()
{
ParodusCfg cfg;
strcpy(cfg.hw_model, "TG1682");
strcpy(cfg.hw_serial_number, "Fer23u948590");
strcpy(cfg.hw_manufacturer , "ARRISGroup,Inc.");
strcpy(cfg.hw_mac , "123567892366");
strcpy(cfg.hw_last_reboot_reason , "unknown");
strcpy(cfg.fw_name , "2.364s2");
strcpy(cfg.webpa_path_url , "/api/v2/device");
strcpy(cfg.webpa_url , "fabric-cd.webpa.comcast.net");
strcpy(cfg.webpa_interface_used , "eth0");
strcpy(cfg.webpa_protocol , "WebPA-1.6");
strcpy(cfg.webpa_uuid , "1234567-345456546");
parStrncpy(cfg.hw_model, "TG1682", sizeof(cfg.hw_model));
parStrncpy(cfg.hw_serial_number, "Fer23u948590", sizeof(cfg.hw_serial_number));
parStrncpy(cfg.hw_manufacturer , "ARRISGroup,Inc.", sizeof(cfg.hw_manufacturer));
parStrncpy(cfg.hw_mac , "123567892366", sizeof(cfg.hw_mac));
parStrncpy(cfg.hw_last_reboot_reason , "unknown", sizeof(cfg.hw_last_reboot_reason));
parStrncpy(cfg.fw_name , "2.364s2", sizeof(cfg.fw_name));
parStrncpy(cfg.webpa_path_url , "/api/v2/device", sizeof(cfg.webpa_path_url));
parStrncpy(cfg.webpa_url , "fabric-cd.webpa.comcast.net", sizeof(cfg.webpa_url));
parStrncpy(cfg.webpa_interface_used , "eth0", sizeof(cfg.webpa_interface_used));
parStrncpy(cfg.webpa_protocol , "WebPA-1.6", sizeof(cfg.webpa_protocol));
parStrncpy(cfg.webpa_uuid , "1234567-345456546", sizeof(cfg.webpa_uuid));
cfg.secureFlag = 1;
cfg.boot_time = 423457;
cfg.webpa_ping_timeout = 30;

View File

@@ -22,6 +22,7 @@
#include <setjmp.h>
#include <cmocka.h>
#include <assert.h>
#include <nopoll.h>
#include "../src/ParodusInternal.h"
#include "../src/config.h"
@@ -35,12 +36,12 @@ bool LastReasonStatus;
/* Mocks */
/*----------------------------------------------------------------------------*/
int lws_b64_encode_string(const char *content,int length,char *output, int output_size)
nopoll_bool nopoll_base64_encode(const char *content,int length,char *output, int *output_size)
{
UNUSED(content); UNUSED(length); UNUSED(output_size);
strcpy(output, "AWYFUJHUDUDKJDDRDKUIIKORE\nSFJLIRRSHLOUTDESTDJJITTESLOIUHJGDRS\nGIUY&%WSJ");
parStrncpy(output, "AWYFUJHUDUDKJDDRDKUIIKORE\nSFJLIRRSHLOUTDESTDJJITTESLOIUHJGDRS\nGIUY&%WSJ", (size_t) *output_size);
function_called();
return (int)(intptr_t)mock();
return (nopoll_bool)(intptr_t)mock();
}
char *get_global_reconnect_reason()
@@ -55,19 +56,19 @@ char *get_global_reconnect_reason()
void test_getWebpaConveyHeader()
{
ParodusCfg cfg;
strcpy(cfg.hw_model, "TG1682");
strcpy(cfg.hw_serial_number, "Fer23u948590");
strcpy(cfg.hw_manufacturer , "ARRISGroup,Inc.");
strcpy(cfg.hw_mac , "123567892366");
strcpy(cfg.hw_last_reboot_reason , "unknown");
strcpy(cfg.fw_name , "2.364s2");
strcpy(cfg.webpa_path_url , "/api/v2/device");
strcpy(cfg.webpa_url , "localhost");
strcpy(cfg.webpa_interface_used , "eth0");
strcpy(cfg.webpa_protocol , "WebPA-1.6");
strcpy(cfg.webpa_uuid , "1234567-345456546");
cfg.secureFlag = 1;
memset(&cfg, 0, sizeof(ParodusCfg));
parStrncpy(cfg.hw_model, "TG1682", sizeof(cfg.hw_model));
parStrncpy(cfg.hw_serial_number, "Fer23u948590", sizeof(cfg.hw_serial_number));
parStrncpy(cfg.hw_manufacturer , "ARRISGroup,Inc.", sizeof(cfg.hw_manufacturer));
parStrncpy(cfg.hw_mac , "123567892366", sizeof(cfg.hw_mac));
parStrncpy(cfg.hw_last_reboot_reason , "unknown", sizeof(cfg.hw_last_reboot_reason));
parStrncpy(cfg.fw_name , "2.364s2", sizeof(cfg.fw_name));
parStrncpy(cfg.webpa_path_url , "/api/v2/device", sizeof(cfg.webpa_path_url));
parStrncpy(cfg.webpa_url , "localhost", sizeof(cfg.webpa_url));
parStrncpy(cfg.webpa_interface_used , "eth0", sizeof(cfg.webpa_interface_used));
parStrncpy(cfg.webpa_protocol , "WebPA-1.6", sizeof(cfg.webpa_protocol));
parStrncpy(cfg.webpa_uuid , "1234567-345456546", sizeof(cfg.webpa_uuid));
cfg.flags = 0;
cfg.boot_time = 423457;
cfg.webpa_ping_timeout = 30;
cfg.webpa_backoff_max = 255;
@@ -76,8 +77,8 @@ void test_getWebpaConveyHeader()
will_return(get_global_reconnect_reason, (intptr_t)"Ping-Miss");
expect_function_call(get_global_reconnect_reason);
will_return(lws_b64_encode_string, 352);
expect_function_call(lws_b64_encode_string);
will_return(nopoll_base64_encode, nopoll_true);
expect_function_call(nopoll_base64_encode);
getWebpaConveyHeader();
}
@@ -89,8 +90,8 @@ void err_getWebpaConveyHeader()
will_return(get_global_reconnect_reason, (intptr_t)NULL);
expect_function_call(get_global_reconnect_reason);
will_return(lws_b64_encode_string, -1);
expect_function_call(lws_b64_encode_string);
will_return(nopoll_base64_encode, nopoll_false);
expect_function_call(nopoll_base64_encode);
getWebpaConveyHeader();
}

View File

@@ -87,13 +87,23 @@ static void *client_rcv_task()
int byte =0;
int rv1=0;
int t=25000;
int rc = -1;
int bind;
wrp_msg_t *msg1;
int sock1 = nn_socket (AF_SP, NN_PULL);
nn_bind(sock1, TEST_CLIENT1_URL);
bind = nn_bind(sock1, TEST_CLIENT1_URL);
if(bind < 0)
{
ParodusError("Unable to bind socket (errno=%d, %s)\n",errno, strerror(errno));
}
void *buf = NULL;
nn_setsockopt(sock1, NN_SOL_SOCKET, NN_RCVTIMEO, &t, sizeof(t));
rc = nn_setsockopt(sock1, NN_SOL_SOCKET, NN_RCVTIMEO, &t, sizeof(t));
if(rc < 0)
{
ParodusError ("Unable to set socket timeout (errno=%d, %s)\n",errno, strerror(errno));
}
ParodusPrint("Client 1 waiting for acknowledgement \n");
byte = nn_recv(sock1, &buf, NN_MSG, 0);
@@ -119,13 +129,23 @@ static void *client2_rcv_task()
int byte =0;
int rv1=0;
int t=25000;
int rc = -1;
int bind;
wrp_msg_t *msg1;
int sock1 = nn_socket (AF_SP, NN_PULL);
nn_bind(sock1, TEST_CLIENT2_URL);
bind = nn_bind(sock1, TEST_CLIENT2_URL);
if(bind < 0)
{
ParodusError("Unable to bind socket (errno=%d, %s)\n",errno, strerror(errno));
}
void *buf = NULL;
nn_setsockopt(sock1, NN_SOL_SOCKET, NN_RCVTIMEO, &t, sizeof(t));
rc = nn_setsockopt(sock1, NN_SOL_SOCKET, NN_RCVTIMEO, &t, sizeof(t));
if(rc < 0)
{
ParodusError ("Unable to set socket timeout (errno=%d, %s)\n",errno, strerror(errno));
}
ParodusPrint("Client 2 waiting for acknowledgement \n");
byte = nn_recv(sock1, &buf, NN_MSG, 0);

View File

@@ -25,39 +25,64 @@
#include <CUnit/Basic.h>
#include "../src/config.h"
#include "../src/ParodusInternal.h"
#define K_argc 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,
char *server_addr, int server_addr_buflen,
char *port_buf, int port_buflen);
extern unsigned int get_algo_mask (const char *algo_str);
extern unsigned int parse_num_arg (const char *arg, const char *arg_name);
/*----------------------------------------------------------------------------*/
/* Mocks */
/*----------------------------------------------------------------------------*/
void create_token_script(char *fname)
{
char command[128] = {'\0'};
FILE *fp = fopen(fname, "w");
assert_non_null(fp);
fprintf(fp, "%s", "printf secure-token-$1-$2");
fclose(fp);
sprintf(command, "chmod +x %s",fname);
system(command);
}
/*----------------------------------------------------------------------------*/
/* Tests */
/*----------------------------------------------------------------------------*/
void test_setParodusConfig()
{
ParodusCfg cfg;
memset(&cfg,0,sizeof(cfg));
strcpy(cfg.hw_model, "TG1682");
strcpy(cfg.hw_serial_number, "Fer23u948590");
strcpy(cfg.hw_manufacturer , "ARRISGroup,Inc.");
strcpy(cfg.hw_mac , "123567892366");
strcpy(cfg.hw_last_reboot_reason , "unknown");
strcpy(cfg.fw_name , "2.364s2");
strcpy(cfg.webpa_path_url , "/v1");
strcpy(cfg.webpa_url , "localhost");
strcpy(cfg.webpa_interface_used , "eth0");
strcpy(cfg.webpa_protocol , "WebPA-1.6");
strcpy(cfg.webpa_uuid , "1234567-345456546");
strcpy(cfg.partner_id , "comcast");
strcpy(cfg.seshat_url, "ipc://tmp/seshat_service.url");
cfg.secureFlag = 1;
parStrncpy(cfg.hw_model, "TG1682", sizeof(cfg.hw_model));
parStrncpy(cfg.hw_serial_number, "Fer23u948590", sizeof(cfg.hw_serial_number));
parStrncpy(cfg.hw_manufacturer , "ARRISGroup,Inc.", sizeof(cfg.hw_manufacturer));
parStrncpy(cfg.hw_mac , "123567892366", sizeof(cfg.hw_mac));
parStrncpy(cfg.hw_last_reboot_reason , "unknown", sizeof(cfg.hw_last_reboot_reason));
parStrncpy(cfg.fw_name , "2.364s2", sizeof(cfg.fw_name));
parStrncpy(cfg.webpa_path_url , "/v1", sizeof(cfg.webpa_path_url));
parStrncpy(cfg.webpa_url , "http://127.0.0.1", sizeof(cfg.webpa_url));
parStrncpy(cfg.webpa_interface_used , "eth0", sizeof(cfg.webpa_interface_used));
parStrncpy(cfg.webpa_protocol , "WebPA-1.6", sizeof(cfg.webpa_protocol));
parStrncpy(cfg.webpa_uuid , "1234567-345456546", sizeof(cfg.webpa_uuid));
parStrncpy(cfg.partner_id , "comcast", sizeof(cfg.partner_id));
#ifdef ENABLE_SESHAT
parStrncpy(cfg.seshat_url, "ipc://tmp/seshat_service.url", sizeof(cfg.seshat_url));
#endif
cfg.flags = 0;
cfg.boot_time = 423457;
cfg.webpa_ping_timeout = 30;
cfg.webpa_backoff_max = 255;
#ifdef FEATURE_DNS_QUERY
cfg.acquire_jwt = 1;
parStrncpy(cfg.dns_txt_url, "test",sizeof(cfg.dns_txt_url));
cfg.jwt_algo = 1025;
parStrncpy(cfg.jwt_key, "key.txt",sizeof(cfg.jwt_key));
#endif
set_parodus_cfg(&cfg);
ParodusCfg *temp = get_parodus_cfg();
@@ -73,13 +98,19 @@ void test_setParodusConfig()
assert_string_equal(cfg.webpa_protocol, temp->webpa_protocol);
assert_string_equal(cfg.webpa_uuid, temp->webpa_uuid);
assert_string_equal(cfg.partner_id, temp->partner_id);
#ifdef ENABLE_SESHAT
assert_string_equal(cfg.seshat_url, temp->seshat_url);
assert_int_equal((int) cfg.secureFlag, (int) temp->secureFlag);
#endif
assert_int_equal((int) cfg.flags, (int) temp->flags);
assert_int_equal((int) cfg.boot_time, (int) temp->boot_time);
assert_int_equal((int) cfg.webpa_ping_timeout, (int) temp->webpa_ping_timeout);
assert_int_equal((int) cfg.webpa_backoff_max, (int) temp->webpa_backoff_max);
#ifdef FEATURE_DNS_QUERY
assert_int_equal( (int) cfg.acquire_jwt, (int) temp->acquire_jwt);
assert_string_equal(cfg.dns_txt_url, temp->dns_txt_url);
assert_int_equal( (int) cfg.jwt_algo, (int) temp->jwt_algo);
assert_string_equal(cfg.jwt_key, temp->jwt_key);
#endif
}
void test_getParodusConfig()
@@ -87,7 +118,7 @@ void test_getParodusConfig()
ParodusCfg cfg;
memset(&cfg,0,sizeof(cfg));
strcpy(cfg.hw_model, "TG1682133");
parStrncpy(cfg.hw_model, "TG1682133",sizeof(cfg.hw_model));
set_parodus_cfg(&cfg);
ParodusCfg *temp = get_parodus_cfg();
@@ -95,33 +126,80 @@ void test_getParodusConfig()
assert_string_equal(cfg.hw_model, temp->hw_model);
}
static int open_output_file (const char *fname)
{
int fd = open(fname, O_WRONLY | O_CREAT, 0666);
if (fd<0)
{
ParodusError ("File %s open error\n", fname);
abort ();
}
return fd;
}
void write_key_to_file (const char *fname, const char *buf)
{
ssize_t nbytes;
ssize_t buflen = strlen (buf);
int fd = open_output_file(fname);
nbytes = write(fd, buf, buflen);
if (nbytes < 0)
{
ParodusError ("Write file %s error\n", fname);
close(fd);
abort ();
}
close(fd);
ParodusInfo ("%d bytes written\n", nbytes);
}
void test_parseCommandLine()
{
int argc =K_argc;
char * command[argc+1];
int i = 0;
char expectedToken[1280] = {'\0'};
#ifdef FEATURE_DNS_QUERY
const char *jwt_key = "AGdyuwyhwl2ow2ydsoioiygkshwdthuwd";
#endif
command[i++] = "parodus";
command[i++] = "--hw-model=TG1682";
command[i++] = "--hw-serial-number=Fer23u948590";
command[i++] = "--hw-manufacturer=ARRISGroup,Inc.";
command[i++] = "--hw-mac=123567892366";
command[i++] = "--hw-last-reboot-reason=unknown";
command[i++] = "--fw-name=TG1682_DEV_master_2016000000sdy";
command[i++] = "--webpa-ping-time=180";
command[i++] = "--webpa-inteface-used=br0";
command[i++] = "--webpa-url=localhost";
command[i++] = "--webpa-backoff-max=0";
command[i++] = "--boot-time=1234";
command[i++] = "--parodus-local-url=tcp://127.0.0.1:6666";
command[i++] = "--partner-id=cox";
command[i++] = "--seshat-url=ipc://127.0.0.1:7777";
command[i] = '\0';
char *command[] = {"parodus",
"--hw-model=TG1682",
"--hw-serial-number=Fer23u948590",
"--hw-manufacturer=ARRISGroup,Inc.",
"--hw-mac=123567892366",
"--hw-last-reboot-reason=unknown",
"--fw-name=TG1682_DEV_master_2016000000sdy",
"--webpa-ping-timeout=180",
"--webpa-interface-used=br0",
"--webpa-url=http://127.0.0.1",
"--webpa-backoff-max=0",
"--boot-time=1234",
"--parodus-local-url=tcp://127.0.0.1:6666",
"--partner-id=cox",
#ifdef ENABLE_SESHAT
"--seshat-url=ipc://127.0.0.1:7777",
#endif
"--force-ipv4",
"--force-ipv6",
"--token-read-script=/tmp/token.sh",
"--token-acquisition-script=/tmp/token.sh",
"--ssl-cert-path=/etc/ssl/certs/ca-certificates.crt",
#ifdef FEATURE_DNS_QUERY
"--acquire-jwt=1",
"--dns-txt-url=fabric.comcast.net",
"--jwt-public-key-file=../../tests/jwt_key.tst",
"--jwt-algo=RS256",
#endif
NULL
};
int argc = (sizeof (command) / sizeof (char *)) - 1;
ParodusCfg parodusCfg;
memset(&parodusCfg,0,sizeof(parodusCfg));
parseCommandLine(argc,command,&parodusCfg);
#ifdef FEATURE_DNS_QUERY
write_key_to_file ("../../tests/jwt_key.tst", jwt_key);
#endif
create_token_script("/tmp/token.sh");
assert_int_equal (parseCommandLine(argc,command,&parodusCfg), 0);
assert_string_equal( parodusCfg.hw_model, "TG1682");
assert_string_equal( parodusCfg.hw_serial_number, "Fer23u948590");
@@ -131,56 +209,114 @@ void test_parseCommandLine()
assert_string_equal( parodusCfg.fw_name, "TG1682_DEV_master_2016000000sdy");
assert_int_equal( (int) parodusCfg.webpa_ping_timeout,180);
assert_string_equal( parodusCfg.webpa_interface_used, "br0");
assert_string_equal( parodusCfg.webpa_url, "localhost");
assert_string_equal( parodusCfg.webpa_url, "http://127.0.0.1");
assert_int_equal( (int) parodusCfg.webpa_backoff_max,0);
assert_int_equal( (int) parodusCfg.boot_time,1234);
assert_string_equal( parodusCfg.local_url,"tcp://127.0.0.1:6666");
assert_string_equal( parodusCfg.partner_id,"cox");
#ifdef ENABLE_SESHAT
assert_string_equal( parodusCfg.seshat_url, "ipc://127.0.0.1:7777");
#endif
assert_int_equal( (int) parodusCfg.flags, FLAGS_IPV6_ONLY|FLAGS_IPV4_ONLY);
sprintf(expectedToken,"secure-token-%s-%s",parodusCfg.hw_serial_number,parodusCfg.hw_mac);
getAuthToken(&parodusCfg);
set_parodus_cfg(&parodusCfg);
assert_string_equal( get_parodus_cfg()->webpa_auth_token,expectedToken);
assert_string_equal( parodusCfg.cert_path,"/etc/ssl/certs/ca-certificates.crt");
#ifdef FEATURE_DNS_QUERY
assert_int_equal( (int) parodusCfg.acquire_jwt, 1);
assert_string_equal(parodusCfg.dns_txt_url, "fabric.comcast.net");
assert_int_equal( (int) parodusCfg.jwt_algo, 1024);
assert_string_equal ( get_parodus_cfg()->jwt_key, jwt_key);
#endif
}
void test_parseCommandLineNull()
{
parseCommandLine(0,NULL,NULL);
assert_int_equal (parseCommandLine(0,NULL,NULL), -1);
}
void err_parseCommandLine()
{
int argc =K_argc;
char * command[20]={'\0'};
command[0] = "parodus";
command[1] = "--hw-model=TG1682";
command[12] = "webpa";
int argc;
char *command[] = {"parodus",
"--hw-model=TG1682",
"--hw-serial-number=Fer23u948590",
"-Z",
"--nosuch",
"--hw-mac=123567892366",
"webpa",
NULL
};
ParodusCfg parodusCfg;
memset(&parodusCfg,0,sizeof(parodusCfg));
parseCommandLine(argc,command,&parodusCfg);
assert_string_equal( parodusCfg.hw_model, "");
assert_string_equal( parodusCfg.hw_serial_number, "");
argc = (sizeof (command) / sizeof (char *)) - 1;
// Missing webpa_url
assert_int_equal (parseCommandLine(argc,command,&parodusCfg), -1);
// Bad webpa_url
command[5] = "--webpa-url=127.0.0.1";
assert_int_equal (parseCommandLine(argc,command,&parodusCfg), -1);
// Bad mac address
command[5] = "--hw-mac=1235678923";
assert_int_equal (parseCommandLine(argc,command,&parodusCfg), -1);
command[5] = "--webpa-ping-timeout=123x";
assert_int_equal (parseCommandLine(argc,command,&parodusCfg), -1);
command[5] = "--webpa-backoff-max=";
assert_int_equal (parseCommandLine(argc,command,&parodusCfg), -1);
command[5] = "--boot-time=12x";
assert_int_equal (parseCommandLine(argc,command,&parodusCfg), -1);
#ifdef FEATURE_DNS_QUERY
command[5] = "--webpa-url=https://127.0.0.1";
command[3] = "--acquire-jwt=1";
command[4] = "--dns-txt-url=fabric.comcast.net";
// missing algo
assert_int_equal (parseCommandLine(argc,command,&parodusCfg), -1);
command[4] = "--jwt-algo=none:RS256";
// disallowed alogrithm none
assert_int_equal (parseCommandLine(argc,command,&parodusCfg), -1);
command[4] = "--jwt-algo=RS256";
// missing jwt public key file
assert_int_equal (parseCommandLine(argc,command,&parodusCfg), -1);
#endif
}
void test_loadParodusCfg()
{
ParodusCfg tmpcfg;
ParodusCfg *Cfg;
ParodusCfg *Cfg = NULL;
Cfg = (ParodusCfg*)malloc(sizeof(ParodusCfg));
char protocol[32] = {'\0'};
strcpy(Cfg->hw_model, "TG1682");
strcpy(Cfg->hw_serial_number, "Fer23u948590");
strcpy(Cfg->hw_manufacturer , "ARRISGroup,Inc.");
strcpy(Cfg->hw_mac , "123567892366");
strcpy(Cfg->hw_last_reboot_reason , "unknown");
strcpy(Cfg->fw_name , "2.364s2");
strcpy(Cfg->webpa_path_url , "/v1");
strcpy(Cfg->webpa_url , "localhost");
strcpy(Cfg->webpa_interface_used , "eth0");
strcpy(Cfg->webpa_protocol , "WebPA-1.6");
strcpy(Cfg->local_url , "tcp://10.0.0.1:6000");
strcpy(Cfg->partner_id , "shaw");
parStrncpy(Cfg->hw_model, "TG1682", sizeof(Cfg->hw_model));
parStrncpy(Cfg->hw_serial_number, "Fer23u948590", sizeof(Cfg->hw_serial_number));
parStrncpy(Cfg->hw_manufacturer , "ARRISGroup,Inc.", sizeof(Cfg->hw_manufacturer));
parStrncpy(Cfg->hw_mac , "123567892366", sizeof(Cfg->hw_mac));
parStrncpy(Cfg->hw_last_reboot_reason , "unknown", sizeof(Cfg->hw_last_reboot_reason));
parStrncpy(Cfg->fw_name , "2.364s2", sizeof(Cfg->fw_name));
parStrncpy(Cfg->webpa_path_url , "/v1", sizeof(Cfg->webpa_path_url));
parStrncpy(Cfg->webpa_url , "http://127.0.0.1", sizeof(Cfg->webpa_url));
parStrncpy(Cfg->webpa_interface_used , "eth0", sizeof(Cfg->webpa_interface_used));
snprintf(protocol, sizeof(protocol), "%s-%s", PROTOCOL_VALUE, GIT_COMMIT_TAG);
parStrncpy(Cfg->webpa_protocol , protocol, sizeof(Cfg->webpa_protocol));
parStrncpy(Cfg->local_url , "tcp://10.0.0.1:6000", sizeof(Cfg->local_url));
parStrncpy(Cfg->partner_id , "shaw", sizeof(Cfg->partner_id));
#ifdef FEATURE_DNS_QUERY
Cfg->acquire_jwt = 1;
parStrncpy(Cfg->dns_txt_url, "fabric",sizeof(Cfg->dns_txt_url));
Cfg->jwt_algo = 1025;
parStrncpy(Cfg->jwt_key, "AGdyuwyhwl2ow2ydsoioiygkshwdthuwd",sizeof(Cfg->jwt_key));
#endif
parStrncpy(Cfg->token_acquisition_script , "/tmp/token.sh", sizeof(Cfg->token_acquisition_script));
parStrncpy(Cfg->token_read_script , "/tmp/token.sh", sizeof(Cfg->token_read_script));
parStrncpy(Cfg->cert_path, "/etc/ssl.crt",sizeof(Cfg->cert_path));
#ifdef ENABLE_SESHAT
parStrncpy(Cfg->seshat_url, "ipc://tmp/seshat_service.url", sizeof(Cfg->seshat_url));
#endif
memset(&tmpcfg,0,sizeof(ParodusCfg));
loadParodusCfg(Cfg,&tmpcfg);
@@ -190,6 +326,19 @@ void test_loadParodusCfg()
assert_string_equal( tmpcfg.hw_mac, "123567892366");
assert_string_equal( tmpcfg.local_url, "tcp://10.0.0.1:6000");
assert_string_equal( tmpcfg.partner_id, "shaw");
assert_string_equal( tmpcfg.webpa_protocol, protocol);
#ifdef FEATURE_DNS_QUERY
assert_int_equal( (int) tmpcfg.acquire_jwt, 1);
assert_string_equal(tmpcfg.dns_txt_url, "fabric");
assert_int_equal( (int) tmpcfg.jwt_algo, 1025);
assert_string_equal(tmpcfg.jwt_key, "AGdyuwyhwl2ow2ydsoioiygkshwdthuwd");
#endif
assert_string_equal( tmpcfg.token_acquisition_script,"/tmp/token.sh");
assert_string_equal( tmpcfg.token_read_script,"/tmp/token.sh");
assert_string_equal(tmpcfg.cert_path, "/etc/ssl.crt");
#ifdef ENABLE_SESHAT
assert_string_equal(tmpcfg.seshat_url, "ipc://tmp/seshat_service.url");
#endif
free(Cfg);
}
@@ -206,9 +355,8 @@ void test_loadParodusCfgNull()
assert_string_equal(temp.hw_model, "");
assert_string_equal(temp.hw_serial_number, "");
assert_string_equal(temp.hw_manufacturer, "");
assert_int_equal( (int) temp.secureFlag,1);
assert_int_equal( (int) temp.flags,0);
assert_string_equal( temp.webpa_path_url, WEBPA_PATH_URL);
assert_string_equal( temp.webpa_protocol, WEBPA_PROTOCOL_VALUE);
assert_string_equal( temp.webpa_uuid,"1234567-345456546");
assert_string_equal( temp.local_url, PARODUS_UPSTREAM);
@@ -221,6 +369,124 @@ void err_loadParodusCfg()
loadParodusCfg(NULL,&cfg);
}
void test_parodusGitVersion()
{
FILE *fp;
char version[32] = {'\0'};
char *command = "git describe --tags --always";
int n;
size_t len;
fp = popen(command,"r");
while(fgets(version, 32, fp) !=NULL)
{
len = strlen(version);
if (len > 0 && version[len-1] == '\n')
{
version[--len] = '\0';
}
}
pclose(fp);
printf ("version: %s\n", version);
printf ("GIT_COMMIT_TAG: %s\n", GIT_COMMIT_TAG);
n = strcmp( version, GIT_COMMIT_TAG);
assert_int_equal(n, 0);
}
void test_setDefaultValuesToCfg()
{
ParodusCfg *cfg = (ParodusCfg *) malloc(sizeof(ParodusCfg));
memset(cfg,0,sizeof(ParodusCfg));
setDefaultValuesToCfg(cfg);
assert_string_equal( cfg->local_url, PARODUS_UPSTREAM);
#ifdef FEATURE_DNS_QUERY
assert_int_equal(cfg->acquire_jwt, 0);
assert_string_equal(cfg->dns_txt_url, DNS_TXT_URL);
assert_string_equal(cfg->jwt_key, "\0");
assert_int_equal( (int)cfg->jwt_algo, 0);
#endif
assert_string_equal(cfg->cert_path, "\0");
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");
}
void err_setDefaultValuesToCfg()
{
setDefaultValuesToCfg(NULL);
}
void test_parse_num_arg ()
{
assert_int_equal (parse_num_arg ("1234", "1234"), 1234);
assert_int_equal (parse_num_arg ("1", "1"), 1);
assert_int_equal (parse_num_arg ("0", "0"), 0);
assert_true (parse_num_arg ("", "empty arg") == (unsigned int) -1);
assert_true (parse_num_arg ("0x", "non-num arg") == (unsigned int) -1);
}
void test_parse_mac_address ()
{
char result[14];
assert_int_equal (parse_mac_address (result, "aabbccddeeff"), 0);
assert_string_equal (result, "aabbccddeeff");
assert_int_equal (parse_mac_address (result, "aa:bb:cc:dd:ee:ff"), 0);
assert_string_equal (result, "aabbccddeeff");
assert_int_equal (parse_mac_address (result, "aabbccddeeff0"), -1);
assert_int_equal (parse_mac_address (result, "aa:bb:c:dd:ee:ff:00"), -1);
assert_int_equal (parse_mac_address (result, ""), -1);
}
void test_server_is_http ()
{
const char *server_ptr;
assert_int_equal (server_is_http ("https://127.0.0.1", &server_ptr), 0);
assert_string_equal (server_ptr, "127.0.0.1");
assert_int_equal (server_is_http ("http://127.0.0.1", &server_ptr), 1);
assert_string_equal (server_ptr, "127.0.0.1");
assert_int_equal (server_is_http ("127.0.0.1", &server_ptr), -1);
}
void test_parse_webpa_url ()
{
char addr_buf[80];
char port_buf[8];
assert_int_equal (parse_webpa_url ("fabric.webpa.comcast.net:8080",
addr_buf, 80, port_buf, 8), -1);
assert_int_equal (parse_webpa_url ("https://fabric.webpa.comcast.net:8080",
addr_buf, 80, port_buf, 8), 0);
assert_string_equal (addr_buf, "fabric.webpa.comcast.net");
assert_string_equal (port_buf, "8080");
assert_int_equal (parse_webpa_url ("https://fabric.webpa.comcast.net/",
addr_buf, 80, port_buf, 8), 0);
assert_string_equal (addr_buf, "fabric.webpa.comcast.net");
assert_string_equal (port_buf, "443");
assert_int_equal (parse_webpa_url ("http://fabric.webpa.comcast.net:8080",
addr_buf, 80, port_buf, 8), 1);
assert_string_equal (addr_buf, "fabric.webpa.comcast.net");
assert_string_equal (port_buf, "8080");
assert_int_equal (parse_webpa_url ("http://fabric.webpa.comcast.net",
addr_buf, 80, port_buf, 8), 1);
assert_string_equal (addr_buf, "fabric.webpa.comcast.net");
assert_string_equal (port_buf, "80");
}
void test_get_algo_mask ()
{
assert_true (get_algo_mask ("RS256:RS512") == 5120);
assert_true (get_algo_mask ("none:RS256") == (unsigned int) -1);
assert_true (get_algo_mask ("nosuch") == (unsigned int) -1);
#if ALLOW_NON_RSA_ALG
assert_true (get_algo_mask ("ES256:RS256") == 1026);
#else
assert_true (get_algo_mask ("ES256:RS256") == (unsigned int) -1);
#endif
}
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
@@ -233,9 +499,17 @@ int main(void)
cmocka_unit_test(test_loadParodusCfg),
cmocka_unit_test(test_loadParodusCfgNull),
cmocka_unit_test(err_loadParodusCfg),
cmocka_unit_test(test_parse_num_arg),
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_parseCommandLine),
cmocka_unit_test(test_parseCommandLineNull),
cmocka_unit_test(err_parseCommandLine),
cmocka_unit_test(test_parodusGitVersion),
cmocka_unit_test(test_setDefaultValuesToCfg),
cmocka_unit_test(err_setDefaultValuesToCfg),
};
return cmocka_run_group_tests(tests, NULL, NULL);

View File

@@ -21,6 +21,7 @@
#include <setjmp.h>
#include <cmocka.h>
#include <assert.h>
#include <nopoll.h>
#include "../src/ParodusInternal.h"
#include "../src/conn_interface.h"
@@ -32,22 +33,47 @@
/*----------------------------------------------------------------------------*/
UpStreamMsg *UpStreamMsgQ;
ParodusMsg *ParodusMsgQ;
bool conn_retry;
struct lws *wsi_dumb;
extern bool close_retry;
extern pthread_mutex_t close_mut;
extern volatile unsigned int heartBeatTimer;
/*----------------------------------------------------------------------------*/
/* Mocks */
/*----------------------------------------------------------------------------*/
void createLWSconnection()
int createNopollConnection(noPollCtx *ctx)
{
function_called();
UNUSED(ctx);
function_called();
return (int) mock();
}
void nopoll_log_set_handler (noPollCtx *ctx, noPollLogHandler handler, noPollPtr user_data)
{
UNUSED(ctx); UNUSED(handler); UNUSED(user_data);
function_called();
}
void __report_log (noPollCtx * ctx, noPollDebugLevel level, const char * log_msg, noPollPtr user_data)
{
UNUSED(ctx); UNUSED(level); UNUSED(log_msg); UNUSED(user_data);
function_called();
}
void nopoll_thread_handlers ( noPollMutexCreate mutex_create,
noPollMutexDestroy mutex_destroy,
noPollMutexLock mutex_lock,
noPollMutexUnlock mutex_unlock
)
{
UNUSED(mutex_create); UNUSED(mutex_destroy); UNUSED(mutex_lock); UNUSED(mutex_unlock);
function_called();
}
void packMetaData()
{
function_called();
}
void *handle_upstream()
{
return NULL;
@@ -68,9 +94,9 @@ void *serviceAliveTask()
return NULL;
}
int lws_service(struct lws_context * context,int timeout)
int nopoll_loop_wait(noPollCtx * ctx,long timeout)
{
UNUSED(context); UNUSED(timeout);
UNUSED(ctx); UNUSED(timeout);
function_called();
return (int) mock();
}
@@ -81,21 +107,32 @@ void set_global_reconnect_reason(char *reason)
function_called();
}
void lws_context_destroy(struct lws_context * context)
void close_and_unref_connection(noPollConn *conn)
{
UNUSED(context);
UNUSED(conn);
function_called();
}
struct lws_context *get_global_context(void)
void nopoll_cleanup_library ()
{
function_called();
return (struct lws_context *) (intptr_t)mock();
}
void set_global_context(struct lws_context *contextRef)
void nopoll_ctx_unref(noPollCtx * ctx)
{
UNUSED(contextRef);
UNUSED(ctx);
function_called();
}
noPollConn *get_global_conn(void)
{
function_called();
return (noPollConn *) (intptr_t)mock();
}
void set_global_conn(noPollConn *conn)
{
UNUSED(conn);
function_called();
}
@@ -105,6 +142,11 @@ void StartThread(void *(*start_routine) (void *))
function_called();
}
noPollCtx* nopoll_ctx_new(void)
{
function_called();
return (noPollCtx*) (intptr_t)mock();
}
void initKeypress()
{
function_called();
@@ -113,115 +155,169 @@ void initKeypress()
/* Tests */
/*----------------------------------------------------------------------------*/
void test_createLWSsocket()
void test_createSocketConnection()
{
noPollCtx *ctx;
ParodusCfg cfg;
memset(&cfg,0,sizeof(ParodusCfg));
conn_retry = true;
expect_function_call(createLWSconnection);
pthread_mutex_lock (&close_mut);
close_retry = false;
pthread_mutex_unlock (&close_mut);
expect_function_call(nopoll_thread_handlers);
will_return(nopoll_ctx_new, (intptr_t)&ctx);
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);
expect_function_calls(StartThread, 4);
expect_function_call(initKeypress);
will_return(get_global_context, NULL);
expect_function_call(get_global_context);
will_return(lws_service, 1);
expect_function_call(lws_service);
will_return(get_global_context, NULL);
expect_function_call(get_global_context);
expect_function_call(lws_context_destroy);
expect_function_call(createLWSconnection);
will_return(get_global_context, NULL);
expect_function_call(get_global_context);
expect_function_call(lws_context_destroy);
createLWSsocket(&cfg,initKeypress);
will_return(nopoll_loop_wait, 1);
expect_function_call(nopoll_loop_wait);
expect_function_call(set_global_reconnect_reason);
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);
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(initKeypress);
}
void test_createLWSsocket1()
void test_createSocketConnection1()
{
noPollCtx *ctx;
ParodusCfg cfg;
memset(&cfg,0,sizeof(ParodusCfg));
conn_retry = true;
expect_function_call(createLWSconnection);
memset(&cfg,0, sizeof(ParodusCfg));
pthread_mutex_lock (&close_mut);
close_retry = true;
pthread_mutex_unlock (&close_mut);
expect_function_call(nopoll_thread_handlers);
will_return(nopoll_ctx_new, (intptr_t)&ctx);
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(get_global_context, NULL);
expect_function_call(get_global_context);
will_return(lws_service, 1);
expect_function_call(lws_service);
will_return(get_global_context, NULL);
expect_function_call(get_global_context);
expect_function_call(lws_context_destroy);
expect_function_call(createLWSconnection);
will_return(get_global_context, NULL);
expect_function_call(get_global_context);
expect_function_call(lws_context_destroy);
createLWSsocket(&cfg,NULL);
expect_function_calls(StartThread, 4);
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);
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);
}
void test_createLWSsocket2()
void test_createSocketConnection2()
{
noPollCtx *ctx;
ParodusCfg cfg;
memset(&cfg,0,sizeof(ParodusCfg));
strcpy(cfg.hw_model, "TG1682");
strcpy(cfg.hw_serial_number, "Fer23u948590");
strcpy(cfg.hw_manufacturer , "ARRISGroup,Inc.");
strcpy(cfg.hw_mac , "123567892366");
strcpy(cfg.hw_last_reboot_reason , "unknown");
strcpy(cfg.fw_name , "2.364s2");
strcpy(cfg.webpa_path_url , "/v1");
strcpy(cfg.webpa_url , "localhost");
strcpy(cfg.webpa_interface_used , "eth0");
strcpy(cfg.webpa_protocol , "WebPA-1.6");
strcpy(cfg.webpa_uuid , "1234567-345456546");
parStrncpy(cfg.hw_model, "TG1682", sizeof(cfg.hw_model));
parStrncpy(cfg.hw_serial_number, "Fer23u948590", sizeof(cfg.hw_serial_number));
parStrncpy(cfg.hw_manufacturer , "ARRISGroup,Inc.", sizeof(cfg.hw_manufacturer));
parStrncpy(cfg.hw_mac , "123567892366", sizeof(cfg.hw_mac));
parStrncpy(cfg.hw_last_reboot_reason , "unknown", sizeof(cfg.hw_last_reboot_reason));
parStrncpy(cfg.fw_name , "2.364s2", sizeof(cfg.fw_name));
parStrncpy(cfg.webpa_path_url , "/v1", sizeof(cfg.webpa_path_url));
parStrncpy(cfg.webpa_url , "localhost", sizeof(cfg.webpa_url));
parStrncpy(cfg.webpa_interface_used , "eth0", sizeof(cfg.webpa_interface_used));
parStrncpy(cfg.webpa_protocol , "WebPA-1.6", sizeof(cfg.webpa_protocol));
parStrncpy(cfg.webpa_uuid , "1234567-345456546", sizeof(cfg.webpa_uuid));
cfg.webpa_ping_timeout = 1;
set_parodus_cfg(&cfg);
conn_retry = true;
expect_function_call(createLWSconnection);
pthread_mutex_lock (&close_mut);
close_retry = false;
pthread_mutex_unlock (&close_mut);
expect_function_call(nopoll_thread_handlers);
will_return(nopoll_ctx_new, (intptr_t)&ctx);
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(get_global_context, NULL);
expect_function_call(get_global_context);
will_return(lws_service, 1);
expect_function_call(lws_service);
will_return(get_global_context, NULL);
expect_function_call(get_global_context);
expect_function_call(lws_context_destroy);
expect_function_call(createLWSconnection);
will_return(get_global_context, NULL);
expect_function_call(get_global_context);
expect_function_call(lws_context_destroy);
createLWSsocket(&cfg,NULL);
expect_function_calls(StartThread, 4);
will_return(nopoll_loop_wait, 1);
will_return(nopoll_loop_wait, 1);
will_return(nopoll_loop_wait, 1);
will_return(nopoll_loop_wait, 1);
will_return(nopoll_loop_wait, 1);
will_return(nopoll_loop_wait, 1);
will_return(nopoll_loop_wait, 1);
expect_function_calls(nopoll_loop_wait, 7);
expect_function_call(set_global_reconnect_reason);
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);
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);
}
void err_createLWSsocket()
void err_createSocketConnection()
{
conn_retry = true;
expect_function_call(createLWSconnection);
pthread_mutex_lock (&close_mut);
close_retry = true;
pthread_mutex_unlock (&close_mut);
heartBeatTimer = 0;
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(get_global_context, NULL);
expect_function_call(get_global_context);
will_return(lws_service, 1);
expect_function_call(lws_service);
will_return(get_global_context, NULL);
expect_function_call(get_global_context);
expect_function_call(lws_context_destroy);
expect_function_call(createLWSconnection);
will_return(get_global_context, NULL);
expect_function_call(get_global_context);
expect_function_call(lws_context_destroy);
createLWSsocket(NULL,NULL);
expect_function_calls(StartThread, 4);
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);
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 */
/*----------------------------------------------------------------------------*/
@@ -229,10 +325,10 @@ void err_createLWSsocket()
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_createLWSsocket),
cmocka_unit_test(test_createLWSsocket1),
cmocka_unit_test(test_createLWSsocket2),
cmocka_unit_test(err_createLWSsocket),
cmocka_unit_test(test_createSocketConnection),
cmocka_unit_test(test_createSocketConnection1),
cmocka_unit_test(test_createSocketConnection2),
cmocka_unit_test(err_createSocketConnection),
};
return cmocka_run_group_tests(tests, NULL, NULL);

View File

@@ -22,6 +22,7 @@
#include <setjmp.h>
#include <cmocka.h>
#include <assert.h>
#include <nopoll.h>
#include "../src/ParodusInternal.h"
#include "../src/connection.h"
@@ -44,21 +45,29 @@ char* getWebpaConveyHeader()
return NULL;
}
int checkHostIp(char * serverIP)
{
UNUSED(serverIP);
return 0;
}
void setMessageHandlers()
{
}
/*----------------------------------------------------------------------------*/
/* Tests */
/*----------------------------------------------------------------------------*/
void test_get_global_context()
void test_get_global_conn()
{
assert_null(get_global_context());
assert_null(get_global_conn());
}
void test_set_global_context()
void test_set_global_conn()
{
static struct lws_context *context;
set_global_context(context);
assert_ptr_equal(context, get_global_context());
static noPollConn *gNPConn;
set_global_conn(gNPConn);
assert_ptr_equal(gNPConn, get_global_conn());
}
void test_get_global_reconnect_reason()
@@ -73,6 +82,10 @@ void test_set_global_reconnect_reason()
assert_string_equal(reason, get_global_reconnect_reason());
}
void test_closeConnection()
{
close_and_unref_connection(get_global_conn());
}
/*----------------------------------------------------------------------------*/
/* External Functions */
@@ -80,10 +93,11 @@ void test_set_global_reconnect_reason()
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_get_global_context),
cmocka_unit_test(test_set_global_context),
cmocka_unit_test(test_get_global_conn),
cmocka_unit_test(test_set_global_conn),
cmocka_unit_test(test_get_global_reconnect_reason),
cmocka_unit_test(test_set_global_reconnect_reason),
cmocka_unit_test(test_closeConnection),
};
return cmocka_run_group_tests(tests, NULL, NULL);

View File

@@ -22,65 +22,547 @@
#include <setjmp.h>
#include <cmocka.h>
#include <assert.h>
#include <nopoll.h>
#include "../src/ParodusInternal.h"
#include "../src/connection.h"
#include "../src/config.h"
#include "../src/upstream.h"
#include "../src/lws_handlers.h"
#define SECURE_WEBPA_URL "https://127.0.0.1"
#define UNSECURE_WEBPA_URL "http://127.0.0.1"
#define HOST_IP "127.0.0.1"
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
bool conn_retry;
volatile unsigned int heartBeatTimer;
bool close_retry;
bool LastReasonStatus;
volatile unsigned int heartBeatTimer;
pthread_mutex_t close_mut;
int g_status;
char *g_redirect_url;
int mock_strncmp = true;
/*----------------------------------------------------------------------------*/
/* Mocks */
/*----------------------------------------------------------------------------*/
struct lws_context* lws_create_context ( struct lws_context_creation_info * info)
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)
{
function_called();
return (struct lws_context *) (intptr_t)mock();
}
struct lws* lws_client_connect_via_info (struct lws_client_connect_info * ccinfo)
{
function_called();
return (struct lws *) (intptr_t)mock();
UNUSED(host_port); UNUSED(host_name); UNUSED(get_url); UNUSED(protocols);
UNUSED(origin); UNUSED(opts);
function_called();
check_expected((intptr_t)ctx);
check_expected((intptr_t)host_ip);
return (noPollConn *) (intptr_t)mock();
}
int lws_service(struct lws_context * context,int timeout)
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(context); UNUSED(timeout);
UNUSED(options); UNUSED(host_port); UNUSED(host_name); UNUSED(get_url); UNUSED(protocols);
UNUSED(origin);
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);
function_called();
check_expected((intptr_t)ctx);
check_expected((intptr_t)host_ip);
return (noPollConn *) (intptr_t)mock();
}
nopoll_bool nopoll_conn_is_ok (noPollConn * conn)
{
UNUSED(conn);
function_called();
return (nopoll_bool) mock();
}
int getGlobalHttpStatus()
{
return g_status;
}
void setGlobalHttpStatus(int status)
{
g_status=status;
}
void setGlobalRedirectUrl (char *redirect_url)
{
g_redirect_url = redirect_url;
}
nopoll_bool nopoll_conn_wait_until_connection_ready (noPollConn * conn, int timeout, int *status, char * message)
{
UNUSED(timeout); UNUSED(message);
UNUSED(conn);
*status = getGlobalHttpStatus();
if (NULL != g_redirect_url)
parStrncpy (message, g_redirect_url, 128);
function_called();
return (nopoll_bool) mock();
}
int allow_insecure_conn (void)
{
function_called ();
return (int) mock();
}
char* getWebpaConveyHeader()
{
function_called();
return (char*) (intptr_t)mock();
}
int checkHostIp(char * serverIP)
{
(void) serverIP;
function_called();
return (int) mock();
}
void getCurrentTime(struct timespec *timer)
{
(void) timer;
function_called();
}
long timeValDiff(struct timespec *starttime, struct timespec *finishtime)
{
(void) starttime; (void) finishtime;
function_called();
return (long) mock();
}
int kill(pid_t pid, int sig)
{
UNUSED(pid); UNUSED(sig);
function_called();
return (int) mock();
}
void nopoll_conn_close(noPollConn *conn)
{
UNUSED(conn);
function_called();
}
int nopoll_conn_ref_count(noPollConn * conn)
{
UNUSED(conn);
function_called();
return (int) mock();
}
void nopoll_conn_unref( noPollConn * conn)
{
UNUSED(conn);
function_called();
}
int standard_strncmp(const char *s1, const char *s2, size_t n)
{
size_t i;
for (i=0; i<n; i++) {
if (s1[i] != s2[i])
return s1[i] - s2[i];
if (0 == s1[i])
return 0;
}
return 0;
}
int strncmp(const char *s1, const char *s2, size_t n)
{
if (!mock_strncmp)
return standard_strncmp (s1, s2, n);
function_called();
return (int) mock();
}
char *strtok(char *str, const char *delim)
{
UNUSED(str); UNUSED(delim);
function_called();
return (char*) (intptr_t)mock();
}
void setMessageHandlers()
{
function_called();
}
/*----------------------------------------------------------------------------*/
/* Tests */
/*----------------------------------------------------------------------------*/
void test_createSecureConnection()
{
noPollConn *gNPConn;
noPollCtx *ctx = nopoll_ctx_new();
ParodusCfg *cfg = (ParodusCfg*)malloc(sizeof(ParodusCfg));
memset(cfg, 0, sizeof(ParodusCfg));
struct lws_context *lwscontext;
struct lws * info;
conn_retry = false;
cfg->secureFlag = 1;
strcpy(cfg->webpa_url , "fabric.webpa.comcast.net");
mock_strncmp = false;
cfg->flags = 0;
#ifdef FEATURE_DNS_QUERY
cfg->acquire_jwt = 1;
#endif
parStrncpy(cfg->webpa_url , SECURE_WEBPA_URL, sizeof(cfg->webpa_url));
set_parodus_cfg(cfg);
will_return(lws_create_context, (intptr_t)&lwscontext);
expect_function_call(lws_create_context);
will_return(lws_client_connect_via_info, (intptr_t)&info);
expect_function_call(lws_client_connect_via_info);
will_return(lws_service, 1);
expect_function_call(lws_service);
createLWSconnection();
assert_non_null(ctx);
#ifdef FEATURE_DNS_QUERY
will_return (allow_insecure_conn, 0);
expect_function_call (allow_insecure_conn);
#endif
will_return(getWebpaConveyHeader, (intptr_t)"WebPA-1.6 (TG1682)");
expect_function_call(getWebpaConveyHeader);
expect_value(nopoll_conn_tls_new6, (intptr_t)ctx, (intptr_t)ctx);
expect_string(nopoll_conn_tls_new6, (intptr_t)host_ip, HOST_IP);
will_return(nopoll_conn_tls_new6, NULL);
expect_function_call(nopoll_conn_tls_new6);
expect_value(nopoll_conn_tls_new, (intptr_t)ctx, (intptr_t)ctx);
expect_string(nopoll_conn_tls_new, (intptr_t)host_ip, HOST_IP);
will_return(nopoll_conn_tls_new, (intptr_t)&gNPConn);
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_until_connection_ready, nopoll_true);
expect_function_call(nopoll_conn_wait_until_connection_ready);
expect_function_call(setMessageHandlers);
int ret = createNopollConnection(ctx);
assert_int_equal(ret, nopoll_true);
free(cfg);
nopoll_ctx_unref (ctx);
}
void test_createConnection()
{
noPollConn *gNPConn;
noPollCtx *ctx = nopoll_ctx_new();
ParodusCfg *cfg = (ParodusCfg*)malloc(sizeof(ParodusCfg));
memset(cfg, 0, sizeof(ParodusCfg));
assert_non_null(cfg);
mock_strncmp = false;
cfg->flags = 0;
#ifdef FEATURE_DNS_QUERY
cfg->acquire_jwt = 1;
#endif
parStrncpy(cfg->webpa_url , UNSECURE_WEBPA_URL, sizeof(cfg->webpa_url));
set_parodus_cfg(cfg);
assert_non_null(ctx);
#ifdef FEATURE_DNS_QUERY
will_return (allow_insecure_conn, 1);
expect_function_call (allow_insecure_conn);
#endif
will_return(getWebpaConveyHeader, (intptr_t)"WebPA-1.6 (TG1682)");
expect_function_call(getWebpaConveyHeader);
expect_value(nopoll_conn_new_opts, (intptr_t)ctx, (intptr_t)ctx);
expect_string(nopoll_conn_new_opts, (intptr_t)host_ip, HOST_IP);
will_return(nopoll_conn_new_opts, (intptr_t)&gNPConn);
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_until_connection_ready, nopoll_true);
expect_function_call(nopoll_conn_wait_until_connection_ready);
expect_function_call(setMessageHandlers);
int ret = createNopollConnection(ctx);
assert_int_equal(ret, nopoll_true);
free(cfg);
nopoll_ctx_unref (ctx);
}
void test_createConnectionConnNull()
{
noPollConn *gNPConn;
noPollCtx *ctx = nopoll_ctx_new();
ParodusCfg *cfg = (ParodusCfg*)malloc(sizeof(ParodusCfg));
memset(cfg, 0, sizeof(ParodusCfg));
mock_strncmp = false;
cfg->flags = 0;
cfg->webpa_backoff_max = 2;
#ifdef FEATURE_DNS_QUERY
cfg->acquire_jwt = 1;
#endif
parStrncpy(cfg->webpa_url , SECURE_WEBPA_URL,sizeof(cfg->webpa_url));
set_parodus_cfg(cfg);
assert_non_null(ctx);
#ifdef FEATURE_DNS_QUERY
will_return (allow_insecure_conn, 0);
expect_function_call (allow_insecure_conn);
#endif
will_return(getWebpaConveyHeader, (intptr_t)"");
expect_function_call(getWebpaConveyHeader);
expect_value(nopoll_conn_tls_new6, (intptr_t)ctx, (intptr_t)ctx);
expect_string(nopoll_conn_tls_new6, (intptr_t)host_ip, HOST_IP);
will_return(nopoll_conn_tls_new6, NULL);
expect_function_call(nopoll_conn_tls_new6);
expect_value(nopoll_conn_tls_new, (intptr_t)ctx, (intptr_t)ctx);
expect_string(nopoll_conn_tls_new, (intptr_t)host_ip, HOST_IP);
will_return(nopoll_conn_tls_new, (intptr_t)NULL);
expect_function_call(nopoll_conn_tls_new);
will_return(checkHostIp, -2);
expect_function_call(checkHostIp);
expect_function_call(getCurrentTime);
expect_value(nopoll_conn_tls_new6, (intptr_t)ctx, (intptr_t)ctx);
expect_string(nopoll_conn_tls_new6, (intptr_t)host_ip, HOST_IP);
will_return(nopoll_conn_tls_new6, NULL);
expect_function_call(nopoll_conn_tls_new6);
expect_value(nopoll_conn_tls_new, (intptr_t)ctx, (intptr_t)ctx);
expect_string(nopoll_conn_tls_new,(intptr_t)host_ip, HOST_IP);
will_return(nopoll_conn_tls_new, (intptr_t)NULL);
expect_function_call(nopoll_conn_tls_new);
will_return(checkHostIp, -2);
expect_function_call(checkHostIp);
expect_function_call(getCurrentTime);
will_return(timeValDiff, 15*60*1000);
expect_function_call(timeValDiff);
will_return(timeValDiff, 15*60*1000);
expect_function_call(timeValDiff);
will_return(kill, 1);
expect_function_call(kill);
expect_value(nopoll_conn_tls_new6, (intptr_t)ctx, (intptr_t)ctx);
expect_string(nopoll_conn_tls_new6, (intptr_t)host_ip, HOST_IP);
will_return(nopoll_conn_tls_new6, NULL);
expect_function_call(nopoll_conn_tls_new6);
expect_value(nopoll_conn_tls_new, (intptr_t)ctx, (intptr_t)ctx);
expect_string(nopoll_conn_tls_new, (intptr_t)host_ip, HOST_IP);
will_return(nopoll_conn_tls_new, (intptr_t)&gNPConn);
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_until_connection_ready, nopoll_true);
expect_function_call(nopoll_conn_wait_until_connection_ready);
expect_function_call(setMessageHandlers);
createNopollConnection(ctx);
free(cfg);
nopoll_ctx_unref (ctx);
}
void test_createConnectionConnNotOk()
{
noPollConn *gNPConn;
noPollCtx *ctx = nopoll_ctx_new();
ParodusCfg *cfg = (ParodusCfg*)malloc(sizeof(ParodusCfg));
memset(cfg, 0, sizeof(ParodusCfg));
assert_non_null(cfg);
mock_strncmp = false;
cfg->flags = 0;
#ifdef FEATURE_DNS_QUERY
cfg->acquire_jwt = 1;
#endif
parStrncpy(cfg->webpa_url , UNSECURE_WEBPA_URL, sizeof(cfg->webpa_url));
set_parodus_cfg(cfg);
assert_non_null(ctx);
#ifdef FEATURE_DNS_QUERY
will_return (allow_insecure_conn, 1);
expect_function_call (allow_insecure_conn);
#endif
will_return(getWebpaConveyHeader, (intptr_t)"WebPA-1.6 (TG1682)");
expect_function_call(getWebpaConveyHeader);
expect_value(nopoll_conn_new_opts, (intptr_t)ctx, (intptr_t)ctx);
expect_string(nopoll_conn_new_opts, (intptr_t)host_ip, HOST_IP);
will_return(nopoll_conn_new_opts, (intptr_t)&gNPConn);
expect_function_call(nopoll_conn_new_opts);
will_return(nopoll_conn_is_ok, nopoll_false);
expect_function_call(nopoll_conn_is_ok);
expect_function_call(nopoll_conn_close);
will_return(nopoll_conn_ref_count, 1);
expect_function_call(nopoll_conn_ref_count);
expect_function_call(nopoll_conn_unref);
expect_value(nopoll_conn_new_opts, (intptr_t)ctx, (intptr_t)ctx);
expect_string(nopoll_conn_new_opts, (intptr_t)host_ip, HOST_IP);
will_return(nopoll_conn_new_opts, (intptr_t)&gNPConn);
expect_function_call(nopoll_conn_new_opts);
will_return(nopoll_conn_is_ok, nopoll_true);
expect_function_call(nopoll_conn_is_ok);
setGlobalHttpStatus(0);
will_return(nopoll_conn_wait_until_connection_ready, nopoll_false);
expect_function_call(nopoll_conn_wait_until_connection_ready);
expect_function_call(nopoll_conn_close);
will_return(nopoll_conn_ref_count, 0);
expect_function_call(nopoll_conn_ref_count);
expect_value(nopoll_conn_new_opts, (intptr_t)ctx, (intptr_t)ctx);
expect_string(nopoll_conn_new_opts, (intptr_t)host_ip, HOST_IP);
will_return(nopoll_conn_new_opts, (intptr_t)&gNPConn);
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_until_connection_ready, nopoll_true);
expect_function_call(nopoll_conn_wait_until_connection_ready);
expect_function_call(setMessageHandlers);
int ret = createNopollConnection(ctx);
assert_int_equal(ret, nopoll_true);
free(cfg);
nopoll_ctx_unref (ctx);
}
void test_createConnectionConnRedirect()
{
noPollConn *gNPConn;
noPollCtx *ctx = nopoll_ctx_new();
ParodusCfg *cfg = (ParodusCfg*)malloc(sizeof(ParodusCfg));
memset(cfg, 0, sizeof(ParodusCfg));
assert_non_null(cfg);
mock_strncmp = false;
cfg->flags = 0;
#ifdef FEATURE_DNS_QUERY
cfg->acquire_jwt = 1;
#endif
parStrncpy(cfg->webpa_url , UNSECURE_WEBPA_URL, sizeof(cfg->webpa_url));
set_parodus_cfg(cfg);
assert_non_null(ctx);
#ifdef FEATURE_DNS_QUERY
will_return (allow_insecure_conn, 1);
expect_function_call (allow_insecure_conn);
#endif
will_return(getWebpaConveyHeader, (intptr_t)"WebPA-1.6 (TG1682)");
expect_function_call(getWebpaConveyHeader);
expect_value(nopoll_conn_new_opts, (intptr_t)ctx, (intptr_t)ctx);
expect_string(nopoll_conn_new_opts, (intptr_t)host_ip, HOST_IP);
will_return(nopoll_conn_new_opts, (intptr_t)&gNPConn);
expect_function_call(nopoll_conn_new_opts);
will_return(nopoll_conn_is_ok, nopoll_false);
expect_function_call(nopoll_conn_is_ok);
expect_function_call(nopoll_conn_close);
will_return(nopoll_conn_ref_count, 1);
expect_function_call(nopoll_conn_ref_count);
expect_function_call(nopoll_conn_unref);
expect_value(nopoll_conn_new_opts, (intptr_t)ctx, (intptr_t)ctx);
expect_string(nopoll_conn_new_opts, (intptr_t)host_ip, HOST_IP);
will_return(nopoll_conn_new_opts, (intptr_t)&gNPConn);
expect_function_call(nopoll_conn_new_opts);
will_return(nopoll_conn_is_ok, nopoll_true);
expect_function_call(nopoll_conn_is_ok);
setGlobalHttpStatus(307);
setGlobalRedirectUrl ("Redirect:http://10.0.0.12");
will_return(nopoll_conn_wait_until_connection_ready, nopoll_false);
expect_function_call(nopoll_conn_wait_until_connection_ready);
expect_function_call(nopoll_conn_close);
will_return(nopoll_conn_ref_count, 1);
expect_function_call(nopoll_conn_ref_count);
expect_function_call(nopoll_conn_unref);
expect_value(nopoll_conn_new_opts, (intptr_t)ctx, (intptr_t)ctx);
expect_string(nopoll_conn_new_opts, (intptr_t)host_ip, "10.0.0.12");
will_return(nopoll_conn_new_opts, (intptr_t)&gNPConn);
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_until_connection_ready, nopoll_true);
expect_function_call(nopoll_conn_wait_until_connection_ready);
expect_function_call(setMessageHandlers);
int ret = createNopollConnection(ctx);
assert_int_equal(ret, nopoll_true);
free(cfg);
nopoll_ctx_unref (ctx);
}
void err_createConnectionCtxNull()
{
noPollCtx *ctx = NULL;
assert_null(ctx);
int ret = createNopollConnection(ctx);
assert_int_equal(ret, nopoll_false);
}
void test_standard_strncmp ()
{
assert_int_equal (standard_strncmp ("abcde", "abcde", 100), 0);
assert_true (standard_strncmp ("abcde", "abcdf", 100) < 0);
assert_true (standard_strncmp ("abcd", "abcdf", 100) < 0);
assert_true (standard_strncmp ("abcdf", "abcde", 100) > 0);
assert_true (standard_strncmp ("abcde", "abcd", 100) > 0);
assert_int_equal (standard_strncmp ("abcde", "abcff", 3), 0);
}
/*----------------------------------------------------------------------------*/
@@ -90,7 +572,13 @@ void test_createSecureConnection()
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_standard_strncmp),
cmocka_unit_test(test_createSecureConnection),
cmocka_unit_test(test_createConnection),
cmocka_unit_test(test_createConnectionConnNull),
cmocka_unit_test(test_createConnectionConnNotOk),
cmocka_unit_test(test_createConnectionConnRedirect),
cmocka_unit_test(err_createConnectionCtxNull),
};
return cmocka_run_group_tests(tests, NULL, NULL);

View File

@@ -65,8 +65,8 @@ ssize_t wrp_to_struct( const void *bytes, const size_t length,
(*msg)->u.req.partner_ids = (partners_t *) malloc(sizeof(partners_t));
(*msg)->u.req.partner_ids->count = 1;
(*msg)->u.req.partner_ids->partner_ids[0] = (char *) malloc(sizeof(char) *64);
strcpy((*msg)->u.req.dest,"mac:1122334455/iot");
strcpy((*msg)->u.req.partner_ids->partner_ids[0],"comcast");
parStrncpy((*msg)->u.req.dest,"mac:1122334455/iot", 100);
parStrncpy((*msg)->u.req.partner_ids->partner_ids[0],"comcast", 64);
return (ssize_t) mock();
}
@@ -89,15 +89,12 @@ int validate_partner_id(wrp_msg_t *msg, partners_t **partnerIds)
void test_listenerOnMessage()
{
char * msg = "Hello";
char * message = (char*)malloc(sizeof(char)*strlen(msg));
strcpy(message,msg);
will_return(wrp_to_struct, 1);
expect_function_calls(wrp_to_struct, 1);
reg_list_item_t *head = (reg_list_item_t *) malloc(sizeof(reg_list_item_t));
memset(head, 0, sizeof(reg_list_item_t));
strcpy(head->service_name, "iot");
strcpy(head->url, "tcp://10.0.0.1:6600");
parStrncpy(head->service_name, "iot", sizeof(head->service_name));
parStrncpy(head->url, "tcp://10.0.0.1:6600", sizeof(head->url));
will_return(get_numOfClients, 1);
expect_function_call(get_numOfClients);
@@ -107,33 +104,31 @@ void test_listenerOnMessage()
expect_function_call(get_global_node);
will_return(nn_send, 20);
expect_function_calls(nn_send, 1);
listenerOnMessage(message, strlen(message));
listenerOnMessage("Hello", 6);
free(head);
}
void test_listenerOnMessageMultipleClients()
{
char * msg = "Hello";
char * message = (char*)malloc(sizeof(char)*strlen(msg));
strcpy(message,msg);
will_return(wrp_to_struct, 1);
expect_function_calls(wrp_to_struct, 1);
reg_list_item_t *head2 = (reg_list_item_t *) malloc(sizeof(reg_list_item_t));
memset(head2, 0, sizeof(reg_list_item_t));
strcpy(head2->service_name, "iot");
strcpy(head2->url, "tcp://10.0.0.1:6622");
parStrncpy(head2->service_name, "iot", sizeof(head2->service_name));
parStrncpy(head2->url, "tcp://10.0.0.1:6622", sizeof(head2->url));
reg_list_item_t *head1 = (reg_list_item_t *) malloc(sizeof(reg_list_item_t));
memset(head1, 0, sizeof(reg_list_item_t));
strcpy(head1->service_name, "lmlite");
strcpy(head1->url, "tcp://10.0.0.1:6611");
parStrncpy(head1->service_name, "lmlite", sizeof(head1->service_name));
parStrncpy(head1->url, "tcp://10.0.0.1:6611", sizeof(head1->url));
head1->next = head2;
reg_list_item_t *head = (reg_list_item_t *) malloc(sizeof(reg_list_item_t));
memset(head, 0, sizeof(reg_list_item_t));
strcpy(head->service_name, "config");
strcpy(head->url, "tcp://10.0.0.1:6600");
parStrncpy(head->service_name, "config", sizeof(head->service_name));
parStrncpy(head->url, "tcp://10.0.0.1:6600", sizeof(head->url));
head->next = head1;
will_return(get_numOfClients, 3);
@@ -145,7 +140,7 @@ void test_listenerOnMessageMultipleClients()
will_return(nn_send, 20);
expect_function_calls(nn_send, 1);
listenerOnMessage(message, strlen(message));
listenerOnMessage("Hello", 6);
free(head1);
free(head2);
free(head);
@@ -153,20 +148,14 @@ void test_listenerOnMessageMultipleClients()
void err_listenerOnMessage()
{
char * msg = "Hello";
char * message = (char*)malloc(sizeof(char)*strlen(msg));
strcpy(message,msg);
will_return(wrp_to_struct, 0);
expect_function_calls(wrp_to_struct, 1);
listenerOnMessage(message, strlen(message));
listenerOnMessage("Hello", 6);
}
void err_listenerOnMessageServiceUnavailable()
{
char * msg = "Hello";
char * message = (char*)malloc(sizeof(char)*strlen(msg));
strcpy(message,msg);
will_return(wrp_to_struct, 2);
expect_function_calls(wrp_to_struct, 1);
@@ -178,14 +167,11 @@ void err_listenerOnMessageServiceUnavailable()
expect_function_call(get_global_node);
expect_function_call(sendUpstreamMsgToServer);
listenerOnMessage(message, strlen(message));
listenerOnMessage("Hello", 6);
}
void err_listenerOnMessageInvalidPartnerId()
{
char * msg = "Hello";
char * message = (char*)malloc(sizeof(char)*strlen(msg));
strcpy(message,msg);
will_return(wrp_to_struct, 2);
expect_function_calls(wrp_to_struct, 1);
@@ -195,7 +181,7 @@ void err_listenerOnMessageInvalidPartnerId()
expect_function_call(validate_partner_id);
expect_function_call(sendUpstreamMsgToServer);
listenerOnMessage(message, strlen(message));
listenerOnMessage("Hello", 6);
}
void err_listenerOnMessageAllNull()

View File

@@ -0,0 +1,315 @@
/**
* Copyright 2017 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 <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <wrp-c.h>
#include <CUnit/Basic.h>
#include "../src/downstream.h"
/*----------------------------------------------------------------------------*/
/* Macros */
/*----------------------------------------------------------------------------*/
/* none */
/*----------------------------------------------------------------------------*/
/* Data Structures */
/*----------------------------------------------------------------------------*/
typedef struct {
wrp_msg_t s;
wrp_msg_t r;
} test_t;
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
static test_t tests[] = {
{
.s.msg_type = WRP_MSG_TYPE__CREATE,
.s.u.crud.transaction_uuid = "c2bb1f16-09c8-11e7-93ae-92361f002671",
.s.u.crud.source = "fake-server1",
.s.u.crud.dest = "fake-client1/iot",
.s.u.crud.partner_ids = NULL,
.s.u.crud.headers = NULL,
.s.u.crud.metadata = NULL,
.s.u.crud.include_spans = false,
.s.u.crud.spans.spans = NULL,
.s.u.crud.spans.count = 0,
.s.u.crud.path = "Some path",
.s.u.crud.payload = "Some binary",
.s.u.crud.payload_size = 11,
.r.msg_type = WRP_MSG_TYPE__CREATE,
.r.u.crud.transaction_uuid = "c2bb1f16-09c8-11e7-93ae-92361f002671",
.r.u.crud.source = "fake-client1",
.r.u.crud.dest = "fake-server1",
.r.u.crud.partner_ids = NULL,
.r.u.crud.headers = NULL,
.r.u.crud.metadata = NULL,
.r.u.crud.include_spans = false,
.r.u.crud.spans.spans = NULL,
.r.u.crud.spans.count = 0,
.r.u.crud.path = "Some path",
.r.u.crud.payload = "{\"statusCode\":531,\"message\":\"Service Unavailable\"}",
.r.u.crud.payload_size = 50,
},
{
.s.msg_type = WRP_MSG_TYPE__RETREIVE,
.s.u.crud.transaction_uuid = "c2bb1f16-09c8-11e7-93ae-92361f002671",
.s.u.crud.source = "fake-server2",
.s.u.crud.dest = "fake-client2/iot",
.s.u.crud.partner_ids = NULL,
.s.u.crud.headers = NULL,
.s.u.crud.metadata = NULL,
.s.u.crud.include_spans = false,
.s.u.crud.spans.spans = NULL,
.s.u.crud.spans.count = 0,
.s.u.crud.path = "Some path",
.s.u.crud.payload = NULL,
.s.u.crud.payload_size = 0,
.r.msg_type = WRP_MSG_TYPE__RETREIVE,
.r.u.crud.transaction_uuid = "c2bb1f16-09c8-11e7-93ae-92361f002671",
.r.u.crud.source = "fake-client2",
.r.u.crud.dest = "fake-server2",
.r.u.crud.partner_ids = NULL,
.r.u.crud.headers = NULL,
.r.u.crud.metadata = NULL,
.r.u.crud.include_spans = false,
.r.u.crud.spans.spans = NULL,
.r.u.crud.spans.count = 0,
.r.u.crud.path = "Some path",
.r.u.crud.payload = "{\"statusCode\":531,\"message\":\"Service Unavailable\"}",
.r.u.crud.payload_size = 50,
},
{
.s.msg_type = WRP_MSG_TYPE__UPDATE,
.s.u.crud.transaction_uuid = "c2bb1f16-09c8-11e7-93ae-92361f002671",
.s.u.crud.source = "fake-server3",
.s.u.crud.dest = "fake-client3/iot",
.s.u.crud.partner_ids = NULL,
.s.u.crud.headers = NULL,
.s.u.crud.metadata = NULL,
.s.u.crud.include_spans = false,
.s.u.crud.spans.spans = NULL,
.s.u.crud.spans.count = 0,
.s.u.crud.path = "Some path",
.s.u.crud.payload = NULL,
.s.u.crud.payload_size = 0,
.r.msg_type = WRP_MSG_TYPE__UPDATE,
.r.u.crud.transaction_uuid = "c2bb1f16-09c8-11e7-93ae-92361f002671",
.r.u.crud.source = "fake-client3",
.r.u.crud.dest = "fake-server3",
.r.u.crud.partner_ids = NULL,
.r.u.crud.headers = NULL,
.r.u.crud.metadata = NULL,
.r.u.crud.include_spans = false,
.r.u.crud.spans.spans = NULL,
.r.u.crud.spans.count = 0,
.r.u.crud.path = "Some path",
.r.u.crud.payload = "{\"statusCode\":531,\"message\":\"Service Unavailable\"}",
.r.u.crud.payload_size = 50,
},
{
.s.msg_type = WRP_MSG_TYPE__DELETE,
.s.u.crud.transaction_uuid = "c2bb1f16-09c8-11e7-93ae-92361f002671",
.s.u.crud.source = "fake-server4",
.s.u.crud.dest = "fake-client4/iot",
.s.u.crud.partner_ids = NULL,
.s.u.crud.headers = NULL,
.s.u.crud.metadata = NULL,
.s.u.crud.include_spans = false,
.s.u.crud.spans.spans = NULL,
.s.u.crud.spans.count = 0,
.s.u.crud.path = "Some path",
.s.u.crud.payload = NULL,
.s.u.crud.payload_size = 0,
.r.msg_type = WRP_MSG_TYPE__DELETE,
.r.u.crud.transaction_uuid = "c2bb1f16-09c8-11e7-93ae-92361f002671",
.r.u.crud.source = "fake-client4",
.r.u.crud.dest = "fake-server4",
.r.u.crud.partner_ids = NULL,
.r.u.crud.headers = NULL,
.r.u.crud.metadata = NULL,
.r.u.crud.include_spans = false,
.r.u.crud.spans.spans = NULL,
.r.u.crud.spans.count = 0,
.r.u.crud.path = "Some path",
.r.u.crud.payload = "{\"statusCode\":531,\"message\":\"Service Unavailable\"}",
.r.u.crud.payload_size = 50,
},
{
.s.msg_type = WRP_MSG_TYPE__EVENT,
.s.u.event.source = "fake-server5",
.s.u.event.dest = "fake-client5/iot",
.s.u.event.partner_ids = NULL,
.s.u.event.headers = NULL,
.s.u.event.metadata = NULL,
.s.u.event.payload = NULL,
.s.u.event.payload_size = 0,
.r = {0},
},
};
static uint8_t i;
/*----------------------------------------------------------------------------*/
/* Mocks */
/*----------------------------------------------------------------------------*/
int validate_partner_id(wrp_msg_t *msg, partners_t **partnerIds)
{
(void) msg; (void) partnerIds;
return 1;
}
ssize_t wrp_to_struct( const void *bytes, const size_t length, const enum wrp_format fmt,
wrp_msg_t **msg )
{
(void) bytes; (void) length; (void) fmt;
*msg = (wrp_msg_t*) malloc(sizeof(wrp_msg_t));
(*msg)->msg_type = tests[i].s.msg_type;
if( WRP_MSG_TYPE__EVENT == tests[i].s.msg_type ) {
(*msg)->u.event.source = strdup(tests[i].s.u.event.source);
(*msg)->u.event.dest = strdup(tests[i].s.u.event.dest);
}
else
{
(*msg)->u.crud.source = strdup(tests[i].s.u.crud.source);
(*msg)->u.crud.dest = strdup(tests[i].s.u.crud.dest);
(*msg)->u.crud.transaction_uuid = strdup(tests[i].s.u.crud.transaction_uuid);
(*msg)->u.crud.path = strdup(tests[i].s.u.crud.path);
}
return (ssize_t) sizeof(tests[i].s);
}
ssize_t wrp_struct_to( const wrp_msg_t *msg, const enum wrp_format fmt, void **bytes )
{
(void) fmt;
*bytes = malloc(1);
CU_ASSERT(WRP_MSG_TYPE__EVENT != msg->msg_type);
CU_ASSERT(tests[i].r.msg_type == msg->msg_type);
CU_ASSERT_STRING_EQUAL(tests[i].r.u.crud.transaction_uuid, msg->u.crud.transaction_uuid);
printf("tests[%d].r.u.crud.source = %s, msg->u.crud.source = %s\n", i, tests[i].r.u.crud.source, msg->u.crud.source);
CU_ASSERT_STRING_EQUAL(tests[i].r.u.crud.source, msg->u.crud.source);
CU_ASSERT_STRING_EQUAL(tests[i].r.u.crud.dest, msg->u.crud.dest);
CU_ASSERT_STRING_EQUAL(tests[i].r.u.crud.path, msg->u.crud.path);
CU_ASSERT(tests[i].r.u.crud.payload_size == msg->u.crud.payload_size);
CU_ASSERT(0 == memcmp(tests[i].r.u.crud.payload, msg->u.crud.payload, msg->u.crud.payload_size));
return 1;
}
void sendUpstreamMsgToServer(void **resp_bytes, size_t resp_size)
{
(void) resp_bytes; (void) resp_size;
}
int get_numOfClients()
{
return 0;
}
reg_list_item_t *get_global_node(void)
{
return NULL;
}
void wrp_free_struct( wrp_msg_t *msg )
{
if( WRP_MSG_TYPE__EVENT == tests[i].s.msg_type ) {
if( NULL != msg->u.event.source) {
free(msg->u.event.source);
}
if( NULL != msg->u.event.dest) {
free(msg->u.event.dest);
}
}
else
{
if( NULL != msg->u.crud.source) {
free(msg->u.crud.source);
}
if( NULL != msg->u.crud.dest) {
free(msg->u.crud.dest);
}
if( NULL != msg->u.crud.transaction_uuid) {
free(msg->u.crud.transaction_uuid);
}
if( NULL != msg->u.crud.path) {
free(msg->u.crud.path);
}
}
}
/*----------------------------------------------------------------------------*/
/* Tests */
/*----------------------------------------------------------------------------*/
void test_listenerOnMessage()
{
size_t t_size = sizeof(tests)/sizeof(test_t);
void *msg = malloc(1);
for( i = 0; i < t_size; i++ ) {
listenerOnMessage(msg, 0);
}
free(msg);
}
void add_suites( CU_pSuite *suite )
{
printf("--------Start of Test Cases Execution ---------\n");
*suite = CU_add_suite( "tests", NULL, NULL );
CU_add_test( *suite, "Test 1", test_listenerOnMessage );
}
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
int main( void )
{
unsigned rv = 1;
CU_pSuite suite = NULL;
if( CUE_SUCCESS == CU_initialize_registry() ) {
add_suites( &suite );
if( NULL != suite ) {
CU_basic_set_mode( CU_BRM_VERBOSE );
CU_basic_run_tests();
printf( "\n" );
CU_basic_show_failures( CU_get_failure_list() );
printf( "\n\n" );
rv = CU_get_number_of_tests_failed();
}
CU_cleanup_registry();
}
return rv;
}

130
tests/test_mutex.c Normal file
View File

@@ -0,0 +1,130 @@
/**
* 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 <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <CUnit/Basic.h>
#include "../src/ParodusInternal.h"
#include "../src/mutex.h"
struct shared_data {
noPollPtr mutex;
int number;
};
/*----------------------------------------------------------------------------*/
/* Mocks */
/*----------------------------------------------------------------------------*/
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr)
{
UNUSED(attr); UNUSED(mutex);
return (int)mock();
}
int pthread_mutex_destroy(pthread_mutex_t *mutex)
{
UNUSED(mutex);
return (int)mock();
}
/*----------------------------------------------------------------------------*/
/* Tests */
/*----------------------------------------------------------------------------*/
void* a(void *in)
{
struct shared_data *data = (struct shared_data*) in;
lockMutex(data->mutex);
data->number++;
data->number++;
data->number++;
unlockMutex(data->mutex);
return NULL;
}
void* b(void *in)
{
struct shared_data *data = (struct shared_data*) in;
lockMutex(data->mutex);
data->number+=10;
data->number+=10;
data->number+=10;
unlockMutex(data->mutex);
return NULL;
}
void test_Mutex()
{
volatile struct shared_data data;
pthread_t thread[2];
data.number = 0;
will_return(pthread_mutex_init, 0);
data.mutex = createMutex();
pthread_create(&thread[0], NULL, a, (void*)(&data));
pthread_create(&thread[1], NULL, b, (void*)(&data));
pthread_join(thread[0], NULL);
pthread_join(thread[1], NULL);
will_return(pthread_mutex_destroy, 0);
destroyMutex(data.mutex);
assert_int_equal(33, data.number);
}
void err_mutex()
{
static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
noPollPtr mutex = &mtx;
will_return(pthread_mutex_destroy, -1);
destroyMutex(mutex);
will_return(pthread_mutex_init, -1);
mutex = createMutex();
destroyMutex(mutex);
}
void err_mutexNull()
{
lockMutex(NULL);
unlockMutex(NULL);
destroyMutex(NULL);
}
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
int main( void )
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_Mutex),
cmocka_unit_test(err_mutex),
cmocka_unit_test(err_mutexNull),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}

View File

@@ -17,30 +17,72 @@
#include <stdarg.h>
#include <stdbool.h>
#include <CUnit/Basic.h>
#include <nopoll.h>
#include <nopoll_private.h>
#include <pthread.h>
#include "../src/lws_handlers.h"
#include "../src/nopoll_handlers.h"
#include "../src/parodus_log.h"
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
volatile unsigned int heartBeatTimer;
bool LastReasonStatus;
pthread_mutex_t close_mut;
bool close_retry;
/*----------------------------------------------------------------------------*/
/* Mocks */
/*----------------------------------------------------------------------------*/
void set_global_reconnect_reason(char *reason)
{
(void) reason;
}
const unsigned char *nopoll_msg_get_payload(noPollMsg *msg)
{
if( NULL != msg ) {
return (unsigned char *) "Dummy payload";
}
return NULL;
}
noPollOpCode nopoll_msg_opcode (noPollMsg * msg)
{
if(NULL != msg)
{
return NOPOLL_PING_FRAME;
}
return NOPOLL_UNKNOWN_OP_CODE;
}
int nopoll_msg_get_payload_size(noPollMsg *msg)
{
(void) msg;
return 1;
}
int nopoll_conn_send_frame (noPollConn * conn, nopoll_bool fin, nopoll_bool masked,
noPollOpCode op_code, long length, noPollPtr content, long sleep_in_header)
{
(void) conn; (void) fin; (void) masked; (void) op_code;
(void) length; (void) content; (void) sleep_in_header;
return 0;
}
/*----------------------------------------------------------------------------*/
/* Tests */
/*----------------------------------------------------------------------------*/
void *a(void *in)
{
void *msg = "Dummy Payload";
noPollMsg msg;
(void) in;
listenerOnrequest_queue(msg,13 );
listenerOnMessage_queue(NULL, NULL, &msg, NULL);
pthread_exit(0);
return NULL;
@@ -48,10 +90,10 @@ void *a(void *in)
void *b(void *in)
{
void *msg = "Dummy Payload1";
noPollMsg msg;
(void) in;
listenerOnrequest_queue(msg, 14);
listenerOnMessage_queue(NULL, NULL, &msg, NULL);
pthread_exit(0);
return NULL;
@@ -69,11 +111,55 @@ void test_listenerOnMessage_queue()
}
void *a1(void *in)
{
char str[] = "SSL_Socket_Close";
(void) in;
LastReasonStatus = false;
listenerOnCloseMessage(NULL, NULL, NULL);
LastReasonStatus = false;
listenerOnCloseMessage(NULL, NULL, (noPollPtr) str);
LastReasonStatus = true;
listenerOnCloseMessage(NULL, NULL, NULL);
LastReasonStatus = true;
listenerOnCloseMessage(NULL, NULL, (noPollPtr) str);
pthread_exit(0);
return NULL;
}
void test_listenerOnCloseMessage()
{
pthread_t thread_a;
pthread_create(&thread_a, NULL, a1, NULL);
pthread_join(thread_a, NULL);
}
void test_listenerOnPingMessage()
{
noPollConn c;
noPollMsg m;
listenerOnPingMessage(NULL, &c, NULL, NULL);
listenerOnPingMessage(NULL, &c, &m, NULL);
listenerOnPingMessage(NULL, NULL, NULL, NULL);
}
void add_suites( CU_pSuite *suite )
{
ParodusInfo("--------Start of Test Cases Execution ---------\n");
*suite = CU_add_suite( "tests", NULL, NULL );
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 );
}
/*----------------------------------------------------------------------------*/

267
tests/test_nopoll_helpers.c Normal file
View File

@@ -0,0 +1,267 @@
/**
* 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 <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <nopoll.h>
#include "../src/parodus_log.h"
#include "../src/nopoll_helpers.h"
/*----------------------------------------------------------------------------*/
/* Macros */
/*----------------------------------------------------------------------------*/
#define UNUSED(x) (void )(x)
#define MAX_SEND_SIZE (60 * 1024)
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
static noPollConn *conn;
/*----------------------------------------------------------------------------*/
/* Mocks */
/*----------------------------------------------------------------------------*/
nopoll_bool nopoll_conn_is_ok( noPollConn *conn )
{
ParodusInfo("function_called : %s\n",__FUNCTION__);
function_called();
check_expected((intptr_t)conn);
return (nopoll_bool)mock();
}
nopoll_bool nopoll_conn_is_ready( noPollConn *conn )
{
ParodusInfo("function_called : %s\n",__FUNCTION__);
function_called();
check_expected((intptr_t)conn);
return (nopoll_bool)mock();
}
int __nopoll_conn_send_common (noPollConn * conn, const char * content, long length, nopoll_bool has_fin, long sleep_in_header, noPollOpCode frame_type)
{
UNUSED(has_fin); UNUSED(sleep_in_header); UNUSED(frame_type); UNUSED(content);
ParodusInfo("function_called : %s\n",__FUNCTION__);
function_called();
check_expected((intptr_t)conn);
check_expected(length);
return (int)mock();
}
int nopoll_conn_flush_writes(noPollConn * conn, long timeout, int previous_result)
{
UNUSED(timeout);
ParodusInfo("function_called : %s\n",__FUNCTION__);
function_called();
check_expected((intptr_t)conn);
check_expected(previous_result);
return (int)mock();
}
noPollConn *get_global_conn()
{
return conn;
}
void listenerOnMessage_queue(noPollCtx * ctx, noPollConn * conn, noPollMsg * msg,noPollPtr user_data)
{
UNUSED(ctx); UNUSED(conn); UNUSED(msg); UNUSED(user_data);
}
void listenerOnPingMessage (noPollCtx * ctx, noPollConn * conn, noPollMsg * msg, noPollPtr user_data)
{
UNUSED(ctx); UNUSED(conn); UNUSED(msg); UNUSED(user_data);
}
void listenerOnCloseMessage (noPollCtx * ctx, noPollConn * conn, noPollPtr user_data)
{
UNUSED(ctx); UNUSED(conn); UNUSED(user_data);
}
/*----------------------------------------------------------------------------*/
/* Tests */
/*----------------------------------------------------------------------------*/
void test_setMessageHandlers()
{
setMessageHandlers();
}
void test_sendResponse()
{
int len = strlen("Hello Parodus!");
expect_value(__nopoll_conn_send_common, (intptr_t)conn, (intptr_t)conn);
expect_value(__nopoll_conn_send_common, length,(intptr_t) len);
will_return(__nopoll_conn_send_common, (intptr_t)len);
expect_function_calls(__nopoll_conn_send_common, 1);
int bytesWritten = sendResponse(conn, "Hello Parodus!", len);
ParodusPrint("Number of bytes written: %d\n", bytesWritten);
assert_int_equal(bytesWritten, len);
}
void test_sendResponseWithFragments()
{
int len = (MAX_SEND_SIZE*2)+64;
expect_value(__nopoll_conn_send_common, (intptr_t)conn, (intptr_t)conn);
expect_value(__nopoll_conn_send_common, length, MAX_SEND_SIZE);
will_return(__nopoll_conn_send_common, MAX_SEND_SIZE);
expect_value(__nopoll_conn_send_common, (intptr_t)conn, (intptr_t)conn);
expect_value(__nopoll_conn_send_common, length, MAX_SEND_SIZE);
will_return(__nopoll_conn_send_common, MAX_SEND_SIZE);
expect_value(__nopoll_conn_send_common, (intptr_t)conn, (intptr_t)conn);
expect_value(__nopoll_conn_send_common, length, 64);
will_return(__nopoll_conn_send_common, 64);
expect_function_calls(__nopoll_conn_send_common, 3);
int bytesWritten = sendResponse(conn, "Hello Parodus!", len);
ParodusPrint("Number of bytes written: %d\n", bytesWritten);
assert_int_equal(bytesWritten, len);
}
void err_sendResponse()
{
int len = strlen("Hello Parodus!");
expect_value(__nopoll_conn_send_common, (intptr_t)conn, (intptr_t)conn);
expect_value(__nopoll_conn_send_common, length, (intptr_t)len);
will_return(__nopoll_conn_send_common, -1);
expect_function_calls(__nopoll_conn_send_common, 1);
int bytesWritten = sendResponse(conn, "Hello Parodus!", len);
ParodusPrint("Number of bytes written: %d\n", bytesWritten);
assert_int_equal(bytesWritten, 0);
}
void err_sendResponseFlushWrites()
{
int len = strlen("Hello Parodus!");
expect_value(__nopoll_conn_send_common, (intptr_t)conn, (intptr_t)conn);
expect_value(__nopoll_conn_send_common, length, len);
will_return(__nopoll_conn_send_common, len-3);
expect_function_calls(__nopoll_conn_send_common, 1);
expect_value(nopoll_conn_flush_writes, (intptr_t)conn, (intptr_t)conn);
expect_value(nopoll_conn_flush_writes, previous_result, len-3);
will_return(nopoll_conn_flush_writes, len-3);
expect_function_calls(nopoll_conn_flush_writes, 1);
int bytesWritten = sendResponse(conn, "Hello Parodus!", len);
ParodusPrint("Number of bytes written: %d\n", bytesWritten);
assert_int_equal(bytesWritten, 0);
}
void err_sendResponseConnNull()
{
int len = strlen("Hello Parodus!");
expect_value(__nopoll_conn_send_common, (intptr_t)conn, (intptr_t)NULL);
expect_value(__nopoll_conn_send_common, length, len);
will_return(__nopoll_conn_send_common, -1);
expect_function_calls(__nopoll_conn_send_common, 1);
int bytesWritten = sendResponse(NULL, "Hello Parodus!", len);
ParodusPrint("Number of bytes written: %d\n", bytesWritten);
assert_int_equal(bytesWritten, 0);
}
void test_sendMessage()
{
int len = strlen("Hello Parodus!");
expect_value(nopoll_conn_is_ok, (intptr_t)conn, (intptr_t)conn);
will_return(nopoll_conn_is_ok, nopoll_true);
expect_function_call(nopoll_conn_is_ok);
expect_value(nopoll_conn_is_ready, (intptr_t)conn, (intptr_t)conn);
will_return(nopoll_conn_is_ready, nopoll_true);
expect_function_call(nopoll_conn_is_ready);
expect_value(__nopoll_conn_send_common, (intptr_t)conn, (intptr_t)conn);
expect_value(__nopoll_conn_send_common, length, len);
will_return(__nopoll_conn_send_common, len);
expect_function_calls(__nopoll_conn_send_common, 1);
sendMessage(conn, "Hello Parodus!", len);
}
void err_sendMessage()
{
int len = strlen("Hello Parodus!");
expect_value(nopoll_conn_is_ok, (intptr_t)conn, (intptr_t)conn);
will_return(nopoll_conn_is_ok, nopoll_true);
expect_function_call(nopoll_conn_is_ok);
expect_value(nopoll_conn_is_ready, (intptr_t)conn, (intptr_t)conn);
will_return(nopoll_conn_is_ready, nopoll_true);
expect_function_call(nopoll_conn_is_ready);
expect_value(__nopoll_conn_send_common, (intptr_t)conn,(intptr_t) conn);
expect_value(__nopoll_conn_send_common, length, len);
will_return(__nopoll_conn_send_common, len-2);
expect_function_calls(__nopoll_conn_send_common, 1);
expect_value(nopoll_conn_flush_writes, (intptr_t)conn, (intptr_t)conn);
expect_value(nopoll_conn_flush_writes, previous_result, len-2);
will_return(nopoll_conn_flush_writes, len-3);
expect_function_calls(nopoll_conn_flush_writes, 1);
sendMessage(conn, "Hello Parodus!", len);
}
void err_sendMessageConnNull()
{
int len = strlen("Hello Parodus!");
expect_value(nopoll_conn_is_ok, (intptr_t)conn, (intptr_t)NULL);
will_return(nopoll_conn_is_ok, nopoll_false);
expect_function_call(nopoll_conn_is_ok);
sendMessage(NULL, "Hello Parodus!", len);
}
void test_reportLog()
{
__report_log(NULL, NOPOLL_LEVEL_DEBUG, "Debug", NULL);
__report_log(NULL, NOPOLL_LEVEL_INFO, "Info", NULL);
__report_log(NULL, NOPOLL_LEVEL_WARNING, "Warning", NULL);
__report_log(NULL, NOPOLL_LEVEL_CRITICAL, "Critical", NULL);
}
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_setMessageHandlers),
cmocka_unit_test(test_sendResponse),
cmocka_unit_test(test_sendResponseWithFragments),
cmocka_unit_test(err_sendResponse),
cmocka_unit_test(err_sendResponseFlushWrites),
cmocka_unit_test(err_sendResponseConnNull),
cmocka_unit_test(test_sendMessage),
cmocka_unit_test(err_sendMessage),
cmocka_unit_test(err_sendMessageConnNull),
cmocka_unit_test(test_reportLog),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}

View File

@@ -1,389 +0,0 @@
/**
* Copyright 2010-2016 Comcast Cable Communications Management, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdarg.h>
#include <CUnit/Basic.h>
#include <stdbool.h>
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <assert.h>
#include "../src/ParodusInternal.h"
#include "../src/connection.h"
#include "../src/config.h"
#include "../src/upstream.h"
#include "../src/lws_handlers.h"
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
bool conn_retry;
volatile unsigned int heartBeatTimer;
bool LastReasonStatus;
/*----------------------------------------------------------------------------*/
/* Mocks */
/*----------------------------------------------------------------------------*/
int lws_is_final_fragment (struct lws * wsi)
{
function_called();
return (int) mock();
}
int lws_callback_on_writable (struct lws * wsi)
{
return 1;
}
void listenerOnrequest_queue(void *requestMsg,int reqSize)
{
UNUSED(requestMsg);
UNUSED(reqSize);
}
int lws_write (struct lws * wsi,unsigned char * buf,size_t len,enum lws_write_protocol protocol)
{
function_called();
return (int) mock();
}
char* getWebpaConveyHeader()
{
function_called();
return (char*) (intptr_t)mock();
}
int LWS_WARN_UNUSED_RESULT lws_add_http_header_by_name (struct lws * wsi,const unsigned char *name,const unsigned char *value,int length,unsigned char **p,unsigned char *end)
{
function_called();
return (int) mock();
}
/*----------------------------------------------------------------------------*/
/* Tests */
/*----------------------------------------------------------------------------*/
void test_callBack1()
{
struct lws *info = malloc(10);
void *user = "connection";
void *in = "payload";
size_t size = 0;
parodus_callback(info,LWS_CALLBACK_CLIENT_ESTABLISHED,user,in,size);
if(!conn_retry)
{
ParodusInfo("Success: conn_retry status changed %d\n",conn_retry);
}
free(info);
}
void test_callBack2()
{
struct lws *info = malloc(10);
void *user = "connection";
void *in = "payload";
size_t size = 0;
parodus_callback(info,LWS_CALLBACK_CLOSED,user,in,size);
if(conn_retry)
{
ParodusInfo("Success: conn_retry status changed %d\n",conn_retry);
}
free(info);
}
void test_callBack3()
{
struct lws *info = malloc(10);
void *user = "connection";
size_t size = 0;
void *bytes;
const wrp_msg_t msg = { .msg_type = WRP_MSG_TYPE__REQ,
.u.req.transaction_uuid = "c07ee5e1-70be-444c-a156-097c767ad8aa",
.u.req.content_type = "application/json",
.u.req.source = "source-address",
.u.req.dest = "dest-address",
.u.req.partner_ids = NULL,
.u.req.headers = NULL,
.u.req.include_spans = false,
.u.req.spans.spans = NULL,
.u.req.spans.count = 0,
.u.req.payload = "Test libwebsocket reciever callback",
.u.req.payload_size = 35
};
size = wrp_struct_to( &msg, WRP_BYTES, &bytes );
will_return(lws_is_final_fragment,1);
expect_function_call(lws_is_final_fragment);
parodus_callback(info,LWS_CALLBACK_CLIENT_RECEIVE,user,bytes,size);
free(bytes);
free(info);
}
void test_callBack4()
{
struct lws *info = malloc(10);
void *user = "connection";
size_t size = 0;
void *bytes;
ParodusInfo( "\n Inside test_encode_decode()....\n" );
const wrp_msg_t msg = { .msg_type = WRP_MSG_TYPE__REQ,
.u.req.transaction_uuid = "c07ee5e1-70be-444c-a156-097c767ad8aa",
.u.req.content_type = "application/json",
.u.req.source = "source-address",
.u.req.dest = "dest-address",
.u.req.partner_ids = NULL,
.u.req.headers = NULL,
.u.req.include_spans = false,
.u.req.spans.spans = NULL,
.u.req.spans.count = 0,
.u.req.payload = "Test libwebsocket reciever callback",
.u.req.payload_size = 35
};
size = wrp_struct_to( &msg, WRP_BYTES, &bytes );
will_return(lws_is_final_fragment,0);
expect_function_call(lws_is_final_fragment);
parodus_callback(info,LWS_CALLBACK_CLIENT_RECEIVE,user,bytes,size);
will_return(lws_is_final_fragment,0);
expect_function_call(lws_is_final_fragment);
parodus_callback(info,LWS_CALLBACK_CLIENT_RECEIVE,user,bytes,size);
will_return(lws_is_final_fragment,1);
expect_function_call(lws_is_final_fragment);
parodus_callback(info,LWS_CALLBACK_CLIENT_RECEIVE,user,bytes,size);
free(bytes);
free(info);
}
void test_callBack5()
{
struct lws *info = malloc(10);
void *user = "connection";
void *in = "payload";
size_t size = 0;
parodus_callback(info,LWS_CALLBACK_CLIENT_CONNECTION_ERROR,user,in,size);
if(conn_retry)
{
ParodusInfo("Success: conn_retry status changed %d\n",conn_retry);
}
free(info);
}
void test_callBack6()
{
struct lws *info = malloc(10);
void *user = "connection";
void *in = "payload";
size_t size = 0;
UpStreamMsg *message = (UpStreamMsg *)malloc(sizeof(UpStreamMsg));
message->msg = (char*)malloc(sizeof(char)*10);
strcpy(message->msg,"payload");
message->len = 7;
message->next = NULL;
ResponseMsgQ = message;
will_return(lws_write,7);
expect_function_call(lws_write);
parodus_callback(info,LWS_CALLBACK_CLIENT_WRITEABLE,user,in,size);
free(message->msg);
free(message);
free(info);
}
void test_callBack7()
{
struct lws *info = malloc(10);
void *user = "connection";
void *in = "payload";
size_t size = 0;
UpStreamMsg *message = (UpStreamMsg *)malloc(sizeof(UpStreamMsg));
message->msg = (char*)malloc(sizeof(char)*10);
strcpy(message->msg,"payload");
message->len = 7;
message->next = NULL;
ResponseMsgQ = message;
will_return(lws_write,-1);
expect_function_call(lws_write);
parodus_callback(info,LWS_CALLBACK_CLIENT_WRITEABLE,user,in,size);
free(message->msg);
free(message);
free(info);
}
void test_callBack8()
{
struct lws *info = malloc(10);
void *user = "connection";
void *in = "payload";
size_t size = 0;
UpStreamMsg *message = (UpStreamMsg *)malloc(sizeof(UpStreamMsg));
message->msg = (char*)malloc(sizeof(char)*10);
strcpy(message->msg,"payload");
message->len = 7;
message->next = NULL;
ResponseMsgQ = message;
will_return(lws_write,5);
expect_function_call(lws_write);
parodus_callback(info,LWS_CALLBACK_CLIENT_WRITEABLE,user,in,size);
free(message->msg);
free(message);
free(info);
}
void test_callBack9()
{
struct lws *info = malloc(10);
void *user = "connection";
void *in = "payload";
size_t size = 0;
will_return(getWebpaConveyHeader, (intptr_t)"WebPA-1.6 (TG1682)");
expect_function_call(getWebpaConveyHeader);
will_return(lws_add_http_header_by_name,0);
expect_function_call(lws_add_http_header_by_name);
will_return(lws_add_http_header_by_name,0);
expect_function_call(lws_add_http_header_by_name);
will_return(lws_add_http_header_by_name,0);
expect_function_call(lws_add_http_header_by_name);
will_return(lws_add_http_header_by_name,0);
expect_function_call(lws_add_http_header_by_name);
parodus_callback(info,LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER,user,in,size);
free(info);
}
void test_callBack10()
{
struct lws *info = malloc(10);
void *user = "connection";
void *in = "payload";
size_t size = 0;
will_return(getWebpaConveyHeader, (intptr_t)"");
expect_function_call(getWebpaConveyHeader);
will_return(lws_add_http_header_by_name,1);
expect_function_call(lws_add_http_header_by_name);
parodus_callback(info,LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER,user,in,size);
free(info);
}
void test_callBack11()
{
struct lws *info = malloc(10);
void *user = "connection";
void *in = "payload";
size_t size = 0;
will_return(getWebpaConveyHeader, (intptr_t)"");
expect_function_call(getWebpaConveyHeader);
will_return(lws_add_http_header_by_name,0);
expect_function_call(lws_add_http_header_by_name);
will_return(lws_add_http_header_by_name,1);
expect_function_call(lws_add_http_header_by_name);
parodus_callback(info,LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER,user,in,size);
free(info);
}
void test_callBack12()
{
struct lws *info = malloc(10);
void *user = "connection";
void *in = "payload";
size_t size = 0;
will_return(getWebpaConveyHeader, (intptr_t)"");
expect_function_call(getWebpaConveyHeader);
will_return(lws_add_http_header_by_name,0);
expect_function_call(lws_add_http_header_by_name);
will_return(lws_add_http_header_by_name,0);
expect_function_call(lws_add_http_header_by_name);
will_return(lws_add_http_header_by_name,1);
expect_function_call(lws_add_http_header_by_name);
parodus_callback(info,LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER,user,in,size);
free(info);
}
void test_callBack13()
{
struct lws *info = malloc(10);
void *user = "connection";
void *in = "payload";
size_t size = 0;
will_return(getWebpaConveyHeader, (intptr_t)"");
expect_function_call(getWebpaConveyHeader);
will_return(lws_add_http_header_by_name,0);
expect_function_call(lws_add_http_header_by_name);
will_return(lws_add_http_header_by_name,0);
expect_function_call(lws_add_http_header_by_name);
will_return(lws_add_http_header_by_name,0);
expect_function_call(lws_add_http_header_by_name);
parodus_callback(info,LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER,user,in,size);
free(info);
}
void test_callBack14()
{
struct lws *info = malloc(10);
void *user = "connection";
void *in = "payload";
size_t size = 0;
will_return(getWebpaConveyHeader, (intptr_t)"WebPA-1.6 (TG1682)");
expect_function_call(getWebpaConveyHeader);
will_return(lws_add_http_header_by_name,0);
expect_function_call(lws_add_http_header_by_name);
will_return(lws_add_http_header_by_name,0);
expect_function_call(lws_add_http_header_by_name);
will_return(lws_add_http_header_by_name,0);
expect_function_call(lws_add_http_header_by_name);
will_return(lws_add_http_header_by_name,1);
expect_function_call(lws_add_http_header_by_name);
parodus_callback(info,LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER,user,in,size);
free(info);
}
void test_callBack15()
{
struct lws *info = malloc(10);
void *in = "payload";
size_t size = 0;
X509_STORE_CTX *ctx;
ctx = X509_STORE_CTX_new();
parodus_callback(info,LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION,ctx,in,size);
free(info);
}
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_callBack1),
cmocka_unit_test(test_callBack2),
cmocka_unit_test(test_callBack3),
cmocka_unit_test(test_callBack4),
cmocka_unit_test(test_callBack5),
cmocka_unit_test(test_callBack6),
cmocka_unit_test(test_callBack7),
cmocka_unit_test(test_callBack8),
cmocka_unit_test(test_callBack9),
cmocka_unit_test(test_callBack10),
cmocka_unit_test(test_callBack11),
cmocka_unit_test(test_callBack12),
cmocka_unit_test(test_callBack13),
cmocka_unit_test(test_callBack14),
cmocka_unit_test(test_callBack15),
};
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));
strcpy(cfg.partner_id, "comcast");
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));
strcpy(cfg.partner_id, "comcast");
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));
strcpy(cfg.partner_id, "comcast");
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,14 +122,15 @@ void test_validate_partner_id_for_event()
ParodusCfg cfg;
memset(&cfg, 0, sizeof(ParodusCfg));
strcpy(cfg.partner_id, "comcast");
parStrncpy(cfg.partner_id, "abc,*,comcast", sizeof(cfg.partner_id));
will_return(get_parodus_cfg, (intptr_t)&cfg);
expect_function_call(get_parodus_cfg);
partners_t *list = NULL;
int ret = validate_partner_id(msg, &list);
assert_int_equal(ret, 1);
assert_int_equal(ret, 1);
free(list);
free(msg);
}
@@ -141,7 +142,7 @@ void test_validate_partner_id_for_event_listNULL()
ParodusCfg cfg;
memset(&cfg, 0, sizeof(ParodusCfg));
strcpy(cfg.partner_id, "comcast");
parStrncpy(cfg.partner_id, "comcast", sizeof(cfg.partner_id));
will_return(get_parodus_cfg, (intptr_t)&cfg);
expect_function_call(get_parodus_cfg);
@@ -180,7 +181,7 @@ void test_validate_partner_id_for_event_withoutId()
partners_t *partner_ids = (partners_t *) malloc(sizeof(partners_t));
partner_ids->count = 1;
partner_ids->partner_ids[0] = (char *) malloc(sizeof(char)*64);
strcpy(partner_ids->partner_ids[0], "shaw");
parStrncpy(partner_ids->partner_ids[0], "shaw", 64);
wrp_msg_t *msg = (wrp_msg_t*) malloc(sizeof(wrp_msg_t));
memset(msg, 0, sizeof(wrp_msg_t));
@@ -189,7 +190,7 @@ void test_validate_partner_id_for_event_withoutId()
ParodusCfg cfg;
memset(&cfg, 0, sizeof(ParodusCfg));
strcpy(cfg.partner_id, "comcast");
parStrncpy(cfg.partner_id, "comcast", sizeof(cfg.partner_id));
will_return(get_parodus_cfg, (intptr_t)&cfg);
expect_function_call(get_parodus_cfg);

View File

@@ -77,13 +77,23 @@ static void *client_rcv_task()
int byte =0;
int rv1=0;
int t=25000;
int rc = -1;
int bind;
wrp_msg_t *msg1;
sock1 = nn_socket (AF_SP, NN_PULL);
nn_bind(sock1, TEST_SERVICE_URL);
bind = nn_bind(sock1, TEST_SERVICE_URL);
if(bind < 0)
{
ParodusError("Unable to bind socket (errno=%d, %s)\n",errno, strerror(errno));
}
void *buf = NULL;
nn_setsockopt(sock1, NN_SOL_SOCKET, NN_RCVTIMEO, &t, sizeof(t));
rc = nn_setsockopt(sock1, NN_SOL_SOCKET, NN_RCVTIMEO, &t, sizeof(t));
if(rc < 0)
{
ParodusError ("Unable to set socket timeout (errno=%d, %s)\n",errno, strerror(errno));
}
ParodusPrint("Client 1 waiting for acknowledgement \n");
byte = nn_recv(sock1, &buf, NN_MSG, 0);

View File

@@ -0,0 +1,187 @@
/**
* 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 <stdarg.h>
#include <stdbool.h>
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <assert.h>
#include <nopoll.h>
#include "../src/ParodusInternal.h"
#include "../src/seshat_interface.h"
#include "../src/config.h"
/*----------------------------------------------------------------------------*/
/* Macros */
/*----------------------------------------------------------------------------*/
#define URL "url"
#define LRU "lru"
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
ParodusCfg g_config;
/*----------------------------------------------------------------------------*/
/* Mocks */
/*----------------------------------------------------------------------------*/
ParodusCfg *get_parodus_cfg(void)
{
return &g_config;
}
int init_lib_seshat (const char *url)
{
UNUSED(url);
function_called();
return (int) mock();
}
int shutdown_seshat_lib (void)
{
function_called();
return (int) mock();
}
int seshat_register(const char *service, const char *url)
{
UNUSED(service); UNUSED(url);
function_called();
return (int) mock();
}
char* seshat_discover(const char *service)
{
UNUSED(service);
function_called();
return (char *) mock();
}
int allow_insecure_conn(void)
{
return 0;
}
/*----------------------------------------------------------------------------*/
/* Tests */
/*----------------------------------------------------------------------------*/
void test_all_pass()
{
parStrncpy(g_config.local_url, URL, sizeof(g_config.local_url));
will_return(init_lib_seshat, 0);
expect_function_call(init_lib_seshat);
will_return(seshat_register, 0);
expect_function_call(seshat_register);
char *d_url = malloc(sizeof(g_config.local_url));
parStrncpy(d_url, g_config.local_url, sizeof(g_config.local_url));
will_return(seshat_discover, d_url);
expect_function_call(seshat_discover);
will_return(shutdown_seshat_lib, 0);
expect_function_call(shutdown_seshat_lib);
assert_true(__registerWithSeshat());
memset(&g_config, '\0', sizeof(g_config));
}
void test_init_fail()
{
will_return(init_lib_seshat, -1);
expect_function_call(init_lib_seshat);
will_return(shutdown_seshat_lib, 0);
expect_function_call(shutdown_seshat_lib);
assert_false(__registerWithSeshat());
}
void test_register_fail()
{
will_return(init_lib_seshat, 0);
expect_function_call(init_lib_seshat);
will_return(seshat_register, -1);
expect_function_call(seshat_register);
will_return(shutdown_seshat_lib, 0);
expect_function_call(shutdown_seshat_lib);
assert_false(__registerWithSeshat());
}
void test_discover_fail()
{
will_return(init_lib_seshat, 0);
expect_function_call(init_lib_seshat);
will_return(seshat_register, 0);
expect_function_call(seshat_register);
will_return(seshat_discover, 0);
expect_function_call(seshat_discover);
will_return(shutdown_seshat_lib, 0);
expect_function_call(shutdown_seshat_lib);
assert_false(__registerWithSeshat());
}
void test_discover_pass_but_lru_expected_fail()
{
parStrncpy(g_config.local_url, URL, sizeof(g_config.local_url));
will_return(init_lib_seshat, 0);
expect_function_call(init_lib_seshat);
will_return(seshat_register, 0);
expect_function_call(seshat_register);
char *d_url = malloc(sizeof(g_config.local_url));
parStrncpy(d_url, LRU, sizeof(g_config.local_url));
will_return(seshat_discover, d_url);
expect_function_call(seshat_discover);
will_return(shutdown_seshat_lib, 0);
expect_function_call(shutdown_seshat_lib);
assert_false(__registerWithSeshat());
}
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_all_pass),
cmocka_unit_test(test_init_fail),
cmocka_unit_test(test_register_fail),
cmocka_unit_test(test_discover_fail),
cmocka_unit_test(test_discover_pass_but_lru_expected_fail),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}

View File

@@ -0,0 +1,61 @@
/**
* 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 <stdarg.h>
#include <stdbool.h>
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <assert.h>
#include "../src/seshat_interface.h"
/*----------------------------------------------------------------------------*/
/* Macros */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* Function Prototypes */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* Mocks */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/* Tests */
/*----------------------------------------------------------------------------*/
void test_registration()
{
assert_true(__registerWithSeshat());
}
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_registration),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}

678
tests/test_token.c Normal file
View File

@@ -0,0 +1,678 @@
/**
* 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 <stdarg.h>
#include <CUnit/Basic.h>
#include <stdbool.h>
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <resolv.h>
#include <cmocka.h>
#include <assert.h>
#include <cjwt/cjwt.h>
#include "../src/token.h"
#include "../src/ParodusInternal.h"
#include "../src/connection.h"
#include "../src/config.h"
const char *header = "{ \"alg\": \"RS256\", \"typ\": \"JWT\"}";
time_t exp_time_good = 2147483647; // 1/18/2038
time_t exp_time_bad = 1463955372; // 5/22/2016
const char *payload_good = "{" \
"\"iss\": \"SHA256:jdcRysFunWUAT852huQoIM9GN6k2s5c7iTMTMgujPAk\"," \
"\"endpoint\": \"https://fabric.webpa.comcast.net:8080/\"}";
const char *payload_insec = "{" \
"\"iss\": \"SHA256:jdcRysFunWUAT852huQoIM9GN6k2s5c7iTMTMgujPAk\"," \
"\"endpoint\": \"http://fabric.webpa.comcast.net:8080/\"}";
// missing endpoint
const char *payload_no_end = "{" \
"\"iss\": \"SHA256:jdcRysFunWUAT852huQoIM9GN6k2s5c7iTMTMgujPAk\"}";
const char *txt_record_id = "aabbccddeeff.test.webpa.comcast.net";
#define MAX_RR_RECS 10
const char *dns_recs_test =
"\"03:ji81f9B4vnaENEZJgPzYiYdVLvbkgg9rbI7RVcEjutIszb7XZA\"\n"
"\"01:eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MTQ3NjQ3OTksImlzcyI6IlNIQTI1NjpqZGNSeXNGdW5XVUFUODUyaHVRb0lNOUdONmsyczVjN2lUTVRNZ3VqUEFrIiwiZW5kcG9pbnQiOiJodHRwczovL2ZhYnJpYy53ZWJwYS5jb21jYXN0Lm5ldDo4MDgwLyJ9.ahYvcvZxKfKt-enfMZOT9JwCr7eGECv2fUYEDbVdm\"\n"
"\"02:X1Jq1iPnD8MqkSOyHUQ8a17DOFQSmv8C3ZTKkjtFHEUR8l-KYhaA8bmU7Fzo8m0f4Ub411p4r4VE3KOdv8TWbKgKKIElONJmimpCDvHaUG6SZTaGB_proHyw5Vy5RzK4EAUc0C36hPBF6pIQfl5DgT1I66MHDcklMx2af2_F26Wv4rRX3pU_Q6fvustJhRTBcCJa7S6NZrm_Ca9rkRk5v2dyXkzrrB0_PCIoHITom8DPF8N56EDGzLyY25-\"\n"
;
const char *dns_recs_extra =
"\"03:ji81f9B4vnaENEZJgPzYiYdVLvbkgg9rbI7RVcEjutIszb7XZA\"\n"
"\"01:eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MTQ3NjQ3OTksImlzcyI6IlNIQTI1NjpqZGNSeXNGdW5XVUFUODUyaHVRb0lNOUdONmsyczVjN2lUTVRNZ3VqUEFrIiwiZW5kcG9pbnQiOiJodHRwczovL2ZhYnJpYy53ZWJwYS5jb21jYXN0Lm5ldDo4MDgwLyJ9.ahYvcvZxKfKt-enfMZOT9JwCr7eGECv2fUYEDbVdm\"\n"
"\n" // non-txt record type
"\"02:X1Jq1iPnD8MqkSOyHUQ8a17DOFQSmv8C3ZTKkjtFHEUR8l-KYhaA8bmU7Fzo8m0f4Ub411p4r4VE3KOdv8TWbKgKKIElONJmimpCDvHaUG6SZTaGB_proHyw5Vy5RzK4EAUc0C36hPBF6pIQfl5DgT1I66MHDcklMx2af2_F26Wv4rRX3pU_Q6fvustJhRTBcCJa7S6NZrm_Ca9rkRk5v2dyXkzrrB0_PCIoHITom8DPF8N56EDGzLyY25-\"\n"
;
char *rr_recs_test[] = {
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MTQ3NjQ3OTksImlzcyI6IlNIQTI1NjpqZGNSeXNGdW5XVUFUODUyaHVRb0lNOUdONmsyczVjN2lUTVRNZ3VqUEFrIiwiZW5kcG9pbnQiOiJodHRwczovL2ZhYnJpYy53ZWJwYS5jb21jYXN0Lm5ldDo4MDgwLyJ9.ahYvcvZxKfKt-enfMZOT9JwCr7eGECv2fUYEDbVdm",
"X1Jq1iPnD8MqkSOyHUQ8a17DOFQSmv8C3ZTKkjtFHEUR8l-KYhaA8bmU7Fzo8m0f4Ub411p4r4VE3KOdv8TWbKgKKIElONJmimpCDvHaUG6SZTaGB_proHyw5Vy5RzK4EAUc0C36hPBF6pIQfl5DgT1I66MHDcklMx2af2_F26Wv4rRX3pU_Q6fvustJhRTBcCJa7S6NZrm_Ca9rkRk5v2dyXkzrrB0_PCIoHITom8DPF8N56EDGzLyY25-",
"ji81f9B4vnaENEZJgPzYiYdVLvbkgg9rbI7RVcEjutIszb7XZA"
};
char *dns_jwt_test =
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MTQ3NjQ3OTksImlzcyI6IlNIQTI1NjpqZGNSeXNGdW5XVUFUODUyaHVRb0lNOUdONmsyczVjN2lUTVRNZ3VqUEFrIiwiZW5kcG9pbnQiOiJodHRwczovL2ZhYnJpYy53ZWJwYS5jb21jYXN0Lm5ldDo4MDgwLyJ9.ahYvcvZxKfKt-enfMZOT9JwCr7eGECv2fUYEDbVdm"
"X1Jq1iPnD8MqkSOyHUQ8a17DOFQSmv8C3ZTKkjtFHEUR8l-KYhaA8bmU7Fzo8m0f4Ub411p4r4VE3KOdv8TWbKgKKIElONJmimpCDvHaUG6SZTaGB_proHyw5Vy5RzK4EAUc0C36hPBF6pIQfl5DgT1I66MHDcklMx2af2_F26Wv4rRX3pU_Q6fvustJhRTBcCJa7S6NZrm_Ca9rkRk5v2dyXkzrrB0_PCIoHITom8DPF8N56EDGzLyY25-"
"ji81f9B4vnaENEZJgPzYiYdVLvbkgg9rbI7RVcEjutIszb7XZA"
;
const char *dns_recs_fabric =
"\"eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJlbmRwb2ludCI6Imh0dHBzOi8vZmFicmljLndlYnBhLmNvbWNhc3QubmV0OjgwODAvIn0.24cvUmCGYqqXuSsgC7nNnle2JH-uy6Jwp5BKXADhXpc\""
;
char *rr_recs_fabric[] = {
"eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJlbmRwb2ludCI6Imh0dHBzOi8vZmFicmljLndlYnBhLmNvbWNhc3QubmV0OjgwODAvIn0.24cvUmCGYqqXuSsgC7nNnle2JH-uy6Jwp5BKXADhXpc"
};
const char *dns_recs_err1 = // missing seq
"\"03:ji81f9B4vnaENEZJgPzYiYdVLvbkgg9rbI7RVcEjutIszb7XZA\"\n"
"\"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MTQ3NjQ3OTksImlzcyI6IlNIQTI1NjpqZGNSeXNGdW5XVUFUODUyaHVRb0lNOUdONmsyczVjN2lUTVRNZ3VqUEFrIiwiZW5kcG9pbnQiOiJodHRwczovL2ZhYnJpYy53ZWJwYS5jb21jYXN0Lm5ldDo4MDgwLyJ9.ahYvcvZxKfKt-enfMZOT9JwCr7eGECv2fUYEDbVdm\"\n"
"\"02:X1Jq1iPnD8MqkSOyHUQ8a17DOFQSmv8C3ZTKkjtFHEUR8l-KYhaA8bmU7Fzo8m0f4Ub411p4r4VE3KOdv8TWbKgKKIElONJmimpCDvHaUG6SZTaGB_proHyw5Vy5RzK4EAUc0C36hPBF6pIQfl5DgT1I66MHDcklMx2af2_F26Wv4rRX3pU_Q6fvustJhRTBcCJa7S6NZrm_Ca9rkRk5v2dyXkzrrB0_PCIoHITom8DPF8N56EDGzLyY25-\"\n"
;
const char *dns_recs_err2 = // invalid seq
"\"03:ji81f9B4vnaENEZJgPzYiYdVLvbkgg9rbI7RVcEjutIszb7XZA\"\n"
"\"0:eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MTQ3NjQ3OTksImlzcyI6IlNIQTI1NjpqZGNSeXNGdW5XVUFUODUyaHVRb0lNOUdONmsyczVjN2lUTVRNZ3VqUEFrIiwiZW5kcG9pbnQiOiJodHRwczovL2ZhYnJpYy53ZWJwYS5jb21jYXN0Lm5ldDo4MDgwLyJ9.ahYvcvZxKfKt-enfMZOT9JwCr7eGECv2fUYEDbVdm\"\n"
"\"02:X1Jq1iPnD8MqkSOyHUQ8a17DOFQSmv8C3ZTKkjtFHEUR8l-KYhaA8bmU7Fzo8m0f4Ub411p4r4VE3KOdv8TWbKgKKIElONJmimpCDvHaUG6SZTaGB_proHyw5Vy5RzK4EAUc0C36hPBF6pIQfl5DgT1I66MHDcklMx2af2_F26Wv4rRX3pU_Q6fvustJhRTBcCJa7S6NZrm_Ca9rkRk5v2dyXkzrrB0_PCIoHITom8DPF8N56EDGzLyY25-\"\n"
;
const char *dns_recs_err3 = // invalid seq too high
"\"03:ji81f9B4vnaENEZJgPzYiYdVLvbkgg9rbI7RVcEjutIszb7XZA\"\n"
"\"99:eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MTQ3NjQ3OTksImlzcyI6IlNIQTI1NjpqZGNSeXNGdW5XVUFUODUyaHVRb0lNOUdONmsyczVjN2lUTVRNZ3VqUEFrIiwiZW5kcG9pbnQiOiJodHRwczovL2ZhYnJpYy53ZWJwYS5jb21jYXN0Lm5ldDo4MDgwLyJ9.ahYvcvZxKfKt-enfMZOT9JwCr7eGECv2fUYEDbVdm\"\n"
"\"02:X1Jq1iPnD8MqkSOyHUQ8a17DOFQSmv8C3ZTKkjtFHEUR8l-KYhaA8bmU7Fzo8m0f4Ub411p4r4VE3KOdv8TWbKgKKIElONJmimpCDvHaUG6SZTaGB_proHyw5Vy5RzK4EAUc0C36hPBF6pIQfl5DgT1I66MHDcklMx2af2_F26Wv4rRX3pU_Q6fvustJhRTBcCJa7S6NZrm_Ca9rkRk5v2dyXkzrrB0_PCIoHITom8DPF8N56EDGzLyY25-\"\n"
;
const char *dns_recs_err4 = // duplicate seq number
"\"03:ji81f9B4vnaENEZJgPzYiYdVLvbkgg9rbI7RVcEjutIszb7XZA\"\n"
"\"03:ji81f9B4vnaENEZJgPzYiYdVLvbkgg9rbI7RVcEjutIszb7XZA\"\n"
"\"01:eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MTQ3NjQ3OTksImlzcyI6IlNIQTI1NjpqZGNSeXNGdW5XVUFUODUyaHVRb0lNOUdONmsyczVjN2lUTVRNZ3VqUEFrIiwiZW5kcG9pbnQiOiJodHRwczovL2ZhYnJpYy53ZWJwYS5jb21jYXN0Lm5ldDo4MDgwLyJ9.ahYvcvZxKfKt-enfMZOT9JwCr7eGECv2fUYEDbVdm\"\n"
"\"02:X1Jq1iPnD8MqkSOyHUQ8a17DOFQSmv8C3ZTKkjtFHEUR8l-KYhaA8bmU7Fzo8m0f4Ub411p4r4VE3KOdv8TWbKgKKIElONJmimpCDvHaUG6SZTaGB_proHyw5Vy5RzK4EAUc0C36hPBF6pIQfl5DgT1I66MHDcklMx2af2_F26Wv4rRX3pU_Q6fvustJhRTBcCJa7S6NZrm_Ca9rkRk5v2dyXkzrrB0_PCIoHITom8DPF8N56EDGzLyY25-\"\n"
;
const char *dns_recs_err5 = // missing rec 1
"\"03:ji81f9B4vnaENEZJgPzYiYdVLvbkgg9rbI7RVcEjutIszb7XZA\"\n"
"\n" // non-txt record type
"\"02:X1Jq1iPnD8MqkSOyHUQ8a17DOFQSmv8C3ZTKkjtFHEUR8l-KYhaA8bmU7Fzo8m0f4Ub411p4r4VE3KOdv8TWbKgKKIElONJmimpCDvHaUG6SZTaGB_proHyw5Vy5RzK4EAUc0C36hPBF6pIQfl5DgT1I66MHDcklMx2af2_F26Wv4rRX3pU_Q6fvustJhRTBcCJa7S6NZrm_Ca9rkRk5v2dyXkzrrB0_PCIoHITom8DPF8N56EDGzLyY25-\"\n"
;
cjwt_t jwt1; // secure, payload good
cjwt_t jwt2; // secure, payload good, but expired
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);
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);
extern const char *strip_rr_data (const char *rr_ptr, int *rrlen);
extern int find_seq_num (const char *rr_ptr, int rrlen);
extern int get_rr_seq_num (const char *rr_ptr, int rrlen);
extern int get_rr_seq_table (ns_msg *msg_handle, int num_rr_recs, rr_rec_t *seq_table);
extern int assemble_jwt_from_dns (ns_msg *msg_handle, int num_rr_recs, char *jwt_ans);
extern int query_dns(const char* dns_txt_record_id,char *jwt_ans);
extern void read_key_from_file (const char *fname, char *buf, size_t buflen);
extern const char *get_tok (const char *src, int delim, char *result, int resultsize);
extern unsigned int get_algo_mask (const char *algo_str);
int setup_test_jwts (void)
{
memset (&jwt1, 0, sizeof(cjwt_t));
jwt1.exp.tv_sec = exp_time_good;
jwt1.private_claims = cJSON_Parse ((char *) payload_good);
if (NULL == jwt1.private_claims) {
printf ("Invalid json struct payload_good\n");
return -1;
}
memset (&jwt2, 0, sizeof(cjwt_t));
jwt2.exp.tv_sec = exp_time_bad;
jwt2.private_claims = cJSON_Parse ((char *) payload_good);
if (NULL == jwt2.private_claims) {
printf ("Invalid json struct payload_good\n");
return -1;
}
memset (&jwt3, 0, sizeof(cjwt_t));
jwt3.exp.tv_sec = exp_time_good;
jwt3.private_claims = cJSON_Parse ((char *) payload_insec);
if (NULL == jwt3.private_claims) {
printf ("Invalid json struct payload_insec\n");
return -1;
}
memset (&jwt4, 0, sizeof(cjwt_t));
jwt4.exp.tv_sec = exp_time_good;
jwt4.private_claims = cJSON_Parse ((char *) payload_no_end);
if (NULL == jwt4.private_claims) {
printf ("Invalid json struct payload_good\n");
return -1;
}
return 0;
}
static int get_dns_text (const char *dns_rec_id, u_char *nsbuf, int bufsize)
{
const char *rec = NULL;
if (strstr (dns_rec_id, ".test.") != NULL)
rec = dns_recs_test;
else if (strstr (dns_rec_id, ".extra.") != NULL)
rec = dns_recs_extra;
else if (strstr (dns_rec_id, ".fabric.") != NULL)
rec = dns_recs_fabric;
else if (strstr (dns_rec_id, ".err1.") != NULL)
rec = dns_recs_err1;
else if (strstr (dns_rec_id, ".err2.") != NULL)
rec = dns_recs_err2;
else if (strstr (dns_rec_id, ".err3.") != NULL)
rec = dns_recs_err3;
else if (strstr (dns_rec_id, ".err4.") != NULL)
rec = dns_recs_err4;
else if (strstr (dns_rec_id, ".err5.") != NULL)
rec = dns_recs_err5;
else
return -1;
strncpy ((char *) nsbuf, rec, bufsize);
return 0;
}
/*----------------------------------------------------------------------------*/
/* Mocks */
/*----------------------------------------------------------------------------*/
int ns_initparse(const u_char *nsbuf, int l, ns_msg *msg_handle)
{
UNUSED(l);
char *buf = (char*) nsbuf;
char *next;
int i, count = 0;
msg_handle->_msg_ptr = nsbuf;
while (true)
{
if (buf[0] == 0)
break;
count++;
next = strchr (buf, '\n');
if (NULL == next)
break;
*next = 0;
buf = ++next;
}
for (i=0; i<ns_s_max; i++) {
if (i == ns_s_an)
msg_handle->_counts[i] = count;
else
msg_handle->_counts[i] = 0;
}
return 0;
}
int ns_parserr(ns_msg *msg_handle, ns_sect sect, int rec, ns_rr *rr)
{
UNUSED(sect);
int i, l;
char *ptr = (char *) msg_handle->_msg_ptr;
if (rec >= msg_handle->_counts[ns_s_an]) {
errno = EINVAL;
return -1;
}
for (i=0; i < rec; i++) {
l = strlen (ptr);
ptr += (l+1);
}
if (strlen (ptr) == 0) {
rr->type = ns_t_key;
} else {
rr->type = ns_t_txt;
}
rr->rdata = (u_char *) ptr;
return 0;
}
int __res_ninit (res_state statp)
{
UNUSED(statp);
function_called ();
return (int) mock();
}
int __res_nquery (res_state statp, const char * txt_record,
int class, int type_, u_char * buf, int bufsize)
{
UNUSED(statp); UNUSED(class); UNUSED(type_);
int ret = get_dns_text (txt_record, buf, bufsize);
if (ret == 0)
return strlen ( (char*) buf);
else
return -1;
}
void __res_nclose (res_state statp)
{
UNUSED (statp);
function_called ();
}
void test_analyze_jwt ()
{
int ret = setup_test_jwts ();
assert_int_equal (ret, 0);
ret = analyze_jwt (&jwt1);
assert_int_equal (ret, 0);
ret = analyze_jwt (&jwt2);
assert_int_equal (ret, TOKEN_ERR_JWT_EXPIRED);
ret = analyze_jwt (&jwt3);
assert_int_equal (ret, 1);
ret = analyze_jwt (&jwt4);
assert_int_equal (ret, TOKEN_ERR_INVALID_JWT_CONTENT);
}
void test_validate_algo ()
{
bool ret;
ParodusCfg cfg;
parStrncpy (cfg.jwt_algo, "none:RS256", sizeof(cfg.jwt_algo));
set_parodus_cfg (&cfg);
jwt1.header.alg = alg_rs256;
ret = validate_algo (&jwt1);
assert_int_equal (ret, 1);
jwt1.header.alg = alg_rs512;
ret = validate_algo (&jwt1);
assert_int_equal (ret, 0);
}
void test_nquery ()
{
int len;
u_char nsbuf[8192];
will_return (__res_ninit, 0);
expect_function_call (__res_ninit);
expect_function_call (__res_nclose);
len = nquery (txt_record_id, nsbuf);
assert_int_equal (len, strlen(dns_recs_test));
will_return (__res_ninit, -1);
expect_function_call (__res_ninit);
len = nquery (txt_record_id, nsbuf);
assert_int_equal (len, -1);
will_return (__res_ninit, 0);
expect_function_call (__res_ninit);
len = nquery (".nosuch.", nsbuf);
assert_int_equal (len, -1);
}
void test_valid_b64_char()
{
assert_int_equal (valid_b64_char ('A'), 1);
assert_int_equal (valid_b64_char ('@'), 0);
}
void test_strip_rrdata ()
{
const char *s1 = "\"01:this-is-the-test-string-\"\n";
const char *s2 = "\"01:this-is-the-test-string-\n";
const char *ss1 = "01:this-is-the-test-string-";
int s1len = strlen (ss1);
const char *result;
int rlen;
result = strip_rr_data (s1, &rlen);
assert_int_equal (rlen, s1len);
if (rlen == s1len) {
assert_int_equal (strncmp (result, ss1, rlen), 0);
}
result = strip_rr_data (s2, &rlen);
assert_int_equal (rlen, s1len);
if (rlen == s1len) {
assert_int_equal (strncmp (result, ss1, rlen), 0);
}
}
void test_find_seq_num ()
{
int pos;
const char *s1 = "01:this-is-it";
const char *s2 = "1:this-is-it";
const char *s3 = ":this-is-it";
const char *s4 = ".01:this-is-it";
const char *s5 = "..01:this-is-it";
const char *s6 = "99999";
const char *s7 = "xxxxx";
pos = find_seq_num (s1, strlen(s1));
assert_int_equal (pos, 0);
pos = find_seq_num (s2, strlen(s2));
assert_int_equal (pos, -2);
pos = find_seq_num (s3, strlen(s3));
assert_int_equal (pos, -2);
pos = find_seq_num (s4, strlen(s4));
assert_int_equal (pos, 1);
pos = find_seq_num (s5, strlen(s5));
assert_int_equal (pos, 2);
pos = find_seq_num (s6, strlen(s6));
assert_int_equal (pos, -1);
pos = find_seq_num (s7, strlen(s7));
assert_int_equal (pos, -1);
}
void test_get_rr_seq_num ()
{
int result;
const char *s1 = "01:this-is-it";
const char *s2 = "1:this-is-it";
const char *s3 = ":this-is-it";
const char *s4 = "11:this-is-it";
result = get_rr_seq_num (s1, strlen(s1));
assert_int_equal (result, 1);
result = get_rr_seq_num (s2, strlen(s2));
assert_int_equal (result, -1);
result = get_rr_seq_num (s3, strlen(s3));
assert_int_equal (result, -1);
result = get_rr_seq_num (s4, strlen(s4));
assert_int_equal (result, 11);
}
void test_get_rr_seq_table()
{
#define SEQ_TABLE_SIZE (MAX_RR_RECS + 1)
u_char nsbuf[4096];
ns_msg msg_handle;
int i, num_txt_recs, ret;
rr_rec_t seq_table[SEQ_TABLE_SIZE];
memset (&msg_handle, 0, sizeof(ns_msg));
ret = get_dns_text (".test.", nsbuf, 4096);
assert_int_equal (ret, 0);
ns_initparse (nsbuf, 4096, &msg_handle);
assert_int_equal (msg_handle._counts[ns_s_an], 3);
num_txt_recs = get_rr_seq_table (&msg_handle, 3, seq_table);
assert_int_equal (num_txt_recs, 3);
assert_ptr_equal (seq_table[0].rr_ptr, NULL);
for (i=0; i<3; i++) {
int len = strlen (rr_recs_test[i]);
assert_int_equal (len, seq_table[i+1].rr_len);
ret = strncmp (seq_table[i+1].rr_ptr, rr_recs_test[i], len);
assert_int_equal (ret, 0);
}
ret = get_dns_text (".fabric.", nsbuf, 4096);
assert_int_equal (ret, 0);
ns_initparse (nsbuf, 4096, &msg_handle);
assert_int_equal (msg_handle._counts[ns_s_an], 1);
num_txt_recs = get_rr_seq_table (&msg_handle, 1, seq_table);
assert_int_equal (num_txt_recs, 1);
assert_ptr_not_equal (seq_table[0].rr_ptr, NULL);
if (NULL != seq_table[0].rr_ptr) {
int len = strlen (rr_recs_fabric[0]);
assert_int_equal (len, seq_table[0].rr_len);
ret = strncmp (seq_table[0].rr_ptr, rr_recs_fabric[0], len);
assert_int_equal (ret, 0);
}
ret = get_dns_text (".extra.", nsbuf, 4096);
assert_int_equal (ret, 0);
ns_initparse (nsbuf, 4096, &msg_handle);
assert_int_equal (msg_handle._counts[ns_s_an], 4);
num_txt_recs = get_rr_seq_table (&msg_handle, 4, seq_table);
assert_int_equal (num_txt_recs, 3);
assert_ptr_equal (seq_table[0].rr_ptr, NULL);
for (i=0; i<3; i++) {
int len = strlen (rr_recs_test[i]);
assert_int_equal (len, seq_table[i+1].rr_len);
ret = strncmp (seq_table[i+1].rr_ptr, rr_recs_test[i], len);
assert_int_equal (ret, 0);
}
ret = get_dns_text (".err1.", nsbuf, 4096);
assert_int_equal (ret, 0);
ns_initparse (nsbuf, 4096, &msg_handle);
assert_int_equal (msg_handle._counts[ns_s_an], 3);
num_txt_recs = get_rr_seq_table (&msg_handle, 3, seq_table);
assert_int_equal (num_txt_recs, -1);
ret = get_dns_text (".err2.", nsbuf, 4096);
assert_int_equal (ret, 0);
ns_initparse (nsbuf, 4096, &msg_handle);
assert_int_equal (msg_handle._counts[ns_s_an], 3);
num_txt_recs = get_rr_seq_table (&msg_handle, 3, seq_table);
assert_int_equal (num_txt_recs, -1);
ret = get_dns_text (".err3.", nsbuf, 4096);
assert_int_equal (ret, 0);
ns_initparse (nsbuf, 4096, &msg_handle);
assert_int_equal (msg_handle._counts[ns_s_an], 3);
num_txt_recs = get_rr_seq_table (&msg_handle, 3, seq_table);
assert_int_equal (num_txt_recs, -1);
ret = get_dns_text (".err4.", nsbuf, 4096);
assert_int_equal (ret, 0);
ns_initparse (nsbuf, 4096, &msg_handle);
assert_int_equal (msg_handle._counts[ns_s_an], 4);
num_txt_recs = get_rr_seq_table (&msg_handle, 4, seq_table);
assert_int_equal (num_txt_recs, -1);
ret = get_dns_text (".err5.", nsbuf, 4096);
assert_int_equal (ret, 0);
ns_initparse (nsbuf, 4096, &msg_handle);
assert_int_equal (msg_handle._counts[ns_s_an], 3);
num_txt_recs = get_rr_seq_table (&msg_handle, 3, seq_table);
assert_int_equal (num_txt_recs, -1);
}
void test_assemble_jwt_from_dns ()
{
ns_msg msg_handle;
u_char nsbuf[4096];
char jwt_token[8192];
int ret;
memset (&msg_handle, 0, sizeof(ns_msg));
ret = get_dns_text (".test.", nsbuf, 4096);
assert_int_equal (ret, 0);
ns_initparse (nsbuf, 4096, &msg_handle);
assert_int_equal (msg_handle._counts[ns_s_an], 3);
ret = assemble_jwt_from_dns (&msg_handle, 3, jwt_token);
assert_int_equal (ret, 0);
ret = strcmp (dns_jwt_test, jwt_token);
assert_int_equal (ret, 0);
ret = get_dns_text (".err5.", nsbuf, 4096);
assert_int_equal (ret, 0);
ns_initparse (nsbuf, 4096, &msg_handle);
assert_int_equal (msg_handle._counts[ns_s_an], 3);
ret = assemble_jwt_from_dns (&msg_handle, 3, jwt_token);
assert_int_equal (ret, -1);
}
void test_query_dns ()
{
int ret;
char jwt_buf[8192];
will_return (__res_ninit, 0);
expect_function_call (__res_ninit);
expect_function_call (__res_nclose);
ret = query_dns (txt_record_id, jwt_buf);
assert_int_equal (ret, 0);
will_return (__res_ninit, 0);
expect_function_call (__res_ninit);
//expect_function_call (__res_nclose);
ret = query_dns (".nosuch.", jwt_buf);
assert_int_equal (ret, -1);
will_return (__res_ninit, 0);
expect_function_call (__res_ninit);
expect_function_call (__res_nclose);
ret = query_dns (".err5.", jwt_buf);
assert_int_equal (ret, -1);
}
void test_allow_insecure_conn ()
{
int insecure;
ParodusCfg *cfg = get_parodus_cfg();
parStrncpy (cfg->hw_mac, "aabbccddeeff", sizeof(cfg->hw_mac));
parStrncpy (cfg->dns_txt_url, "test", sizeof(cfg->dns_txt_url));
parStrncpy (cfg->jwt_algo, "none:RS256", sizeof(cfg->jwt_algo));
read_key_from_file ("../../tests/webpa-rs256.pem", cfg->jwt_key, 4096);
will_return (__res_ninit, 0);
expect_function_call (__res_ninit);
expect_function_call (__res_nclose);
insecure = allow_insecure_conn ();
assert_int_equal (insecure, 0);
parStrncpy (cfg->hw_mac, "aabbccddeeff", sizeof(cfg->hw_mac));
parStrncpy (cfg->dns_txt_url, "err5", sizeof(cfg->dns_txt_url));
will_return (__res_ninit, 0);
expect_function_call (__res_ninit);
expect_function_call (__res_nclose);
insecure = allow_insecure_conn ();
assert_int_equal (insecure, TOKEN_ERR_QUERY_DNS_FAIL);
parStrncpy (cfg->hw_mac, "aabbccddeeff", sizeof(cfg->hw_mac));
parStrncpy (cfg->dns_txt_url, "test", sizeof(cfg->dns_txt_url));
parStrncpy (cfg->jwt_algo, "none:RS256", sizeof(cfg->jwt_algo));
parStrncpy (cfg->jwt_key, "xxxxxxxxxx", sizeof(cfg->jwt_key));
will_return (__res_ninit, 0);
expect_function_call (__res_ninit);
expect_function_call (__res_nclose);
insecure = allow_insecure_conn ();
assert_int_equal (insecure, TOKEN_ERR_JWT_DECODE_FAIL);
parStrncpy (cfg->hw_mac, "aabbccddeeff", sizeof(cfg->hw_mac));
parStrncpy (cfg->dns_txt_url, "test", sizeof(cfg->dns_txt_url));
parStrncpy (cfg->jwt_algo, "none:RS512", sizeof(cfg->jwt_algo));
read_key_from_file ("../../tests/webpa-rs256.pem", cfg->jwt_key, 4096);
will_return (__res_ninit, 0);
expect_function_call (__res_ninit);
expect_function_call (__res_nclose);
insecure = allow_insecure_conn ();
assert_int_equal (insecure, TOKEN_ERR_ALGO_NOT_ALLOWED);
}
void test_get_tok()
{
const char *str0 = "";
const char *str1 = "none";
const char *str2 = "none:rs256";
char result[20];
const char *next;
next = get_tok (str0, ':', result, 20);
assert_ptr_equal (next, NULL);
assert_int_equal ((int) result[0], 0);
next = get_tok (str1, ':', result, 20);
assert_string_equal (result, "none");
assert_ptr_equal (next, NULL);
next = get_tok (str2, ':', result, 20);
assert_string_equal (result, "none");
next = get_tok (next, ':', result, 20);
assert_string_equal (result, "rs256");
assert_ptr_equal (next, NULL);
}
void test_get_algo_mask ()
{
unsigned mask;
mask = get_algo_mask ("none");
assert_int_equal ((int) mask, 1);
mask = get_algo_mask ("none:rs256");
assert_int_equal ((int) mask, 1025);
}
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_analyze_jwt),
cmocka_unit_test(test_validate_algo),
cmocka_unit_test(test_nquery),
cmocka_unit_test(test_valid_b64_char),
cmocka_unit_test(test_strip_rrdata),
cmocka_unit_test(test_find_seq_num),
cmocka_unit_test(test_get_rr_seq_num),
cmocka_unit_test(test_get_rr_seq_table),
cmocka_unit_test(test_assemble_jwt_from_dns),
cmocka_unit_test(test_query_dns),
//cmocka_unit_test(test_allow_insecure_conn),
cmocka_unit_test(test_get_tok),
cmocka_unit_test(test_get_algo_mask),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}

52
tests/test_token_stub.c Normal file
View File

@@ -0,0 +1,52 @@
/**
* 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 <stdarg.h>
#include <CUnit/Basic.h>
#include <stdbool.h>
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>
#include <assert.h>
#include "../src/token.h"
/*----------------------------------------------------------------------------*/
/* Mocks */
/*----------------------------------------------------------------------------*/
void test_allow_insecure_conn ()
{
int insecure;
insecure = allow_insecure_conn ();
assert_int_equal (insecure, 1);
}
/*----------------------------------------------------------------------------*/
/* External Functions */
/*----------------------------------------------------------------------------*/
int main(void)
{
const struct CMUnitTest tests[] = {
cmocka_unit_test(test_allow_insecure_conn),
};
return cmocka_run_group_tests(tests, NULL, NULL);
}

View File

@@ -22,6 +22,7 @@
#include <setjmp.h>
#include <cmocka.h>
#include <nopoll.h>
#include <wrp-c.h>
#include <nanomsg/nn.h>
@@ -34,6 +35,7 @@
/*----------------------------------------------------------------------------*/
/* File Scoped Variables */
/*----------------------------------------------------------------------------*/
static noPollConn *conn;
static char *reconnect_reason = "webpa_process_starts";
static ParodusCfg parodusCfg;
extern size_t metaPackSize;
@@ -44,6 +46,10 @@ wrp_msg_t *temp = NULL;
/* Mocks */
/*----------------------------------------------------------------------------*/
noPollConn *get_global_conn()
{
return conn;
}
char *get_global_reconnect_reason()
{
@@ -61,7 +67,11 @@ int get_numOfClients()
function_called();
return (int)mock();
}
void sendMessage(noPollConn *conn, void *msg, size_t len)
{
(void) conn; (void) msg; (void) len;
function_called();
}
ParodusCfg *get_parodus_cfg(void)
{
@@ -81,7 +91,7 @@ size_t appendEncodedData( void **appendData, void *encodedBuffer, size_t encoded
(void) encodedBuffer; (void) encodedSize; (void) metadataPack; (void) metadataSize;
function_called();
char *data = (char *) malloc (sizeof(char) * 100);
strcpy(data, "AAAAAAAAYYYYIGkYTUYFJH");
parStrncpy(data, "AAAAAAAAYYYYIGkYTUYFJH", 100);
*appendData = data;
return (size_t)mock();
}
@@ -269,7 +279,7 @@ void test_processUpstreamMessage()
will_return(appendEncodedData, 100);
expect_function_call(appendEncodedData);
//expect_function_call(sendMessage);
expect_function_call(sendMessage);
expect_function_call(wrp_free_struct);
will_return(nn_freemsg,1);
@@ -306,7 +316,7 @@ void test_processUpstreamMessageInvalidPartner()
will_return(appendEncodedData, 100);
expect_function_call(appendEncodedData);
//expect_function_call(sendMessage);
expect_function_call(sendMessage);
expect_function_call(wrp_free_struct);
will_return(nn_freemsg,1);
@@ -330,8 +340,8 @@ void test_processUpstreamMessageRegMsg()
reg_list_item_t *head = (reg_list_item_t *) malloc(sizeof(reg_list_item_t));
memset(head, 0, sizeof(reg_list_item_t));
strcpy(head->service_name, "iot");
strcpy(head->url, "tcp://10.0.0.1:6600");
parStrncpy(head->service_name, "iot", sizeof(head->service_name));
parStrncpy(head->url, "tcp://10.0.0.1:6600", sizeof(head->url));
temp = (wrp_msg_t *) malloc(sizeof(wrp_msg_t));
memset(temp,0,sizeof(wrp_msg_t));
@@ -390,8 +400,8 @@ void test_processUpstreamMessageRegMsgNoClients()
reg_list_item_t *head = (reg_list_item_t *) malloc(sizeof(reg_list_item_t));
memset(head, 0, sizeof(reg_list_item_t));
strcpy(head->service_name, "iot");
strcpy(head->url, "tcp://10.0.0.1:6600");
parStrncpy(head->service_name, "iot", sizeof(head->service_name));
parStrncpy(head->url, "tcp://10.0.0.1:6600", sizeof(head->url));
temp = (wrp_msg_t *) malloc(sizeof(wrp_msg_t));
memset(temp,0,sizeof(wrp_msg_t));
@@ -486,11 +496,11 @@ void err_processUpstreamMessageRegMsg()
UpStreamMsgQ->next->next = NULL;
reg_list_item_t *head = (reg_list_item_t *) malloc(sizeof(reg_list_item_t));
strcpy(head->service_name, "iot");
strcpy(head->url, "tcp://10.0.0.1:6600");
parStrncpy(head->service_name, "iot", sizeof(head->service_name));
parStrncpy(head->url, "tcp://10.0.0.1:6600", sizeof(head->url));
head->next = (reg_list_item_t *) malloc(sizeof(reg_list_item_t));
strcpy(head->next->service_name, "iot");
strcpy(head->next->url, "tcp://10.0.0.1:6600");
parStrncpy(head->next->service_name, "iot", sizeof(head->service_name));
parStrncpy(head->next->url, "tcp://10.0.0.1:6600", sizeof(head->url));
head->next->next = NULL;
temp = (wrp_msg_t *) malloc(sizeof(wrp_msg_t));
@@ -553,7 +563,7 @@ void test_sendUpstreamMsgToServer()
will_return(appendEncodedData, 100);
expect_function_call(appendEncodedData);
//expect_function_call(sendMessage);
expect_function_call(sendMessage);
sendUpstreamMsgToServer(&bytes, 110);
free(bytes);
}

9
tests/webpa-rs256.pem Normal file
View File

@@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkZeQUMqDkMu/dQgTcycJ
/rrgqfKQkoYFTMO7GnK87/OWiftHmtDJYPgktlcHheOPfkGln5ay1WJSitmtWNaH
+RvBFK/ZsXpIuGm7R6wdSc7e6g9fTaSAfNX/+a8VxHUo58AinXxcq4LnHbuaGjEz
jw77TLuZGyUuHiany8O8tc+DbnYKvRquScsccI6z/QwZKFtXUjJZ91hJ97zC8o7N
Ae7n/Jg+Bs0uz9c1/bf/Jqbu6OidFbCr2FN42UupuAZ8DiPp2fWD5Q9qmp1ADk+V
+TeZPxTCq/WB4dzSCd5v/FvFmO8tH6Ptkltij4pke7Dsi80TVRlcMDXAWxSFXOQV
qwIDAQAB
-----END PUBLIC KEY-----