diff --git a/CMakeLists.txt b/CMakeLists.txt index dc12587..6ed5490 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,12 +24,11 @@ set(PREFIX_DIR ${CMAKE_CURRENT_BINARY_DIR}/_prefix) set(INCLUDE_DIR ${INSTALL_DIR}/include) set(LIBRARY_DIR ${INSTALL_DIR}/lib) set(LIBRARY_DIR64 ${INSTALL_DIR}/lib64) -set(LIBPD_DIR ${CMAKE_CURRENT_BINARY_DIR}/lib/src) set(TEST_RESULTS_DIR ${CMAKE_CURRENT_BINARY_DIR}/test_results) file(MAKE_DIRECTORY ${TEST_RESULTS_DIR}) include_directories(${INCLUDE_DIR} - ${INCLUDE_DIR}/cJSON + ${INCLUDE_DIR}/cjson ${INCLUDE_DIR}/nopoll ${INCLUDE_DIR}/msgpack ${INCLUDE_DIR}/trower-base64 @@ -41,13 +40,16 @@ include_directories(${INCLUDE_DIR} add_definitions(-std=c99) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_GNU_SOURCE -DNOPOLL_LOGGER ") -#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror -Wall") -#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror -Wall -Wno-missing-field-initializers") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror -Wall") + # pthread external dependency #------------------------------------------------------------------------------- find_package (Threads) +if (NOT BUILD_YOCTO) + # base64 external dependency #------------------------------------------------------------------------------- ExternalProject_Add(trower-base64 @@ -138,7 +140,9 @@ ExternalProject_Add(wrp-c add_library(libwrp-c STATIC SHARED IMPORTED) add_dependencies(libwrp-c wrp-c) -link_directories ( ${LIBRARY_DIR} ${LIBRARY_DIR64} ${LIBPD_DIR}) +endif () + +link_directories ( ${LIBRARY_DIR} ${LIBRARY_DIR64}) add_subdirectory(src) if (BUILD_TESTING) diff --git a/patches/nopoll.patch b/patches/nopoll.patch index e40df1d..3ff5224 100644 --- a/patches/nopoll.patch +++ b/patches/nopoll.patch @@ -1,8 +1,17 @@ diff --git a/src/nopoll_conn.c b/src/nopoll_conn.c -index 8612bfd..c2965b2 100644 +index 8612bfd..cd6f9da 100644 --- a/src/nopoll_conn.c +++ b/src/nopoll_conn.c -@@ -193,6 +193,36 @@ nopoll_bool nopoll_conn_set_sock_tcp_nodelay (NOPOLL_SOCKET so +@@ -48,7 +48,7 @@ + + #include + #include +- ++#include + #if defined(NOPOLL_OS_UNIX) + # include + #endif +@@ -193,6 +193,37 @@ nopoll_bool nopoll_conn_set_sock_tcp_nodelay (NOPOLL_SOCKET so return nopoll_true; } /* end */ @@ -18,18 +27,19 @@ index 8612bfd..c2965b2 100644 +nopoll_bool nopoll_conn_set_outbound_interface (noPollCtx * ctx, NOPOLL_SOCKET socket, + const char * outbound_interface) +{ -+ -+ /* local variables */ -+ int result = nopoll_false; -+ nopoll_log (ctx, NOPOLL_LEVEL_INFO, "Nopoll, Outbound Interface %s",outbound_interface); + if(outbound_interface != NULL) { -+ result = setsockopt(socket, SOL_SOCKET, SO_BINDTODEVICE, -+ outbound_interface, strlen(outbound_interface)+1); -+ } -+ nopoll_log (ctx, NOPOLL_LEVEL_INFO, " setsockopt result: %d",result); -+ if (result < 0) { -+ nopoll_log (ctx, NOPOLL_LEVEL_CRITICAL, "Error inside nopoll set socket opt"); -+ return nopoll_false; ++ /* local variables */ ++ int result = nopoll_false; ++ nopoll_log (ctx, NOPOLL_LEVEL_INFO, "Nopoll, Outbound Interface %s",outbound_interface); ++ ++ result = setsockopt(socket, SOL_SOCKET, SO_BINDTODEVICE, ++ outbound_interface, strlen(outbound_interface)+1); ++ ++ nopoll_log (ctx, NOPOLL_LEVEL_INFO, " setsockopt result: %d",result); ++ if (result < 0) { ++ nopoll_log (ctx, NOPOLL_LEVEL_CRITICAL, "Error inside nopoll set socket opt"); ++ return nopoll_false; ++ } + } + + /* properly configured */ @@ -39,7 +49,7 @@ index 8612bfd..c2965b2 100644 /** * @internal Allows to create a plain socket connection against the * host and port provided. -@@ -207,69 +237,140 @@ nopoll_bool nopoll_conn_set_sock_tcp_nodelay (NOPOLL_SOCKET so +@@ -207,69 +238,151 @@ nopoll_bool nopoll_conn_set_sock_tcp_nodelay (NOPOLL_SOCKET so */ NOPOLL_SOCKET nopoll_conn_sock_connect (noPollCtx * ctx, const char * host, @@ -48,101 +58,142 @@ index 8612bfd..c2965b2 100644 + const char * outbound_interface) { - struct hostent * hostent; - struct sockaddr_in saddr; +- struct sockaddr_in saddr; NOPOLL_SOCKET session; +- +- /* resolve hosting name */ +- hostent = gethostbyname (host); +- if (hostent == NULL) { +- nopoll_log (ctx, NOPOLL_LEVEL_DEBUG, "unable to resolve host name %s", host); +- return -1; +- } /* end if */ +- +- /* create the socket and check if it */ +- session = socket (AF_INET, SOCK_STREAM, 0); +- if (session == NOPOLL_INVALID_SOCKET) { +- nopoll_log (ctx, NOPOLL_LEVEL_CRITICAL, "unable to create socket"); + int retVal; + char addrstr[100]; + void *ptr = NULL; + char *localIp = "10.0.0.1"; -+ struct addrinfo *res, *result; ++ struct addrinfo *result, *rp; + struct addrinfo hints = {}; + + memset(&hints,0,sizeof(hints)); -+ hints.ai_family = AF_INET; ++ hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; -+ hints.ai_protocol = 0; - - /* resolve hosting name */ -- hostent = gethostbyname (host); -- if (hostent == NULL) { -- nopoll_log (ctx, NOPOLL_LEVEL_DEBUG, "unable to resolve host name %s", host); -+ retVal = getaddrinfo(host, "http", &hints, &result); ++ hints.ai_protocol = 0; ++ hints.ai_flags = AI_ADDRCONFIG; ++ /* resolving host name */ ++ retVal = getaddrinfo(host, port, &hints, &result); + if (retVal != 0){ + nopoll_log (ctx, NOPOLL_LEVEL_CRITICAL, "unable to resolve host name %s, error: %s", host, gai_strerror(retVal)); return -1; - } /* end if */ -+ } -+ else -+ { -+ res = result; -+ if(res) -+ { -+ inet_ntop (res->ai_family, res->ai_addr->sa_data, addrstr, 100); -+ ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr; -+ inet_ntop (res->ai_family, ptr, addrstr, 100); -+ nopoll_log (ctx, NOPOLL_LEVEL_INFO, "ptr->s_addr %d", ((struct in_addr *) ptr)->s_addr); -+ -+ nopoll_log (ctx, NOPOLL_LEVEL_INFO, "IPv4 address of %s is %s \n", host, addrstr); -+ if (strcmp(localIp,addrstr) == 0) -+ { -+ /* If Host DNS is resolved to 10.0.0.1 which means there is problem and client should not connect to this address */ -+ nopoll_log (ctx, NOPOLL_LEVEL_INFO, "Host Ip resolved to 10.0.0.1"); -+ nopoll_log (ctx, NOPOLL_LEVEL_CRITICAL, "unable to connect to remote host %s:%s as IP resolved to 10.0.0.1", host, port); -+ freeaddrinfo(result); -+ return -1; -+ } -+ else -+ { -+ nopoll_log (ctx, NOPOLL_LEVEL_INFO, "Host Ip resolved correctly, proceeding with the connection"); -+ } -+ } -+ } - - /* create the socket and check if it */ - session = socket (AF_INET, SOCK_STREAM, 0); - if (session == NOPOLL_INVALID_SOCKET) { - nopoll_log (ctx, NOPOLL_LEVEL_CRITICAL, "unable to create socket"); -+ freeaddrinfo(result); - return -1; - } /* end if */ - - /* disable nagle */ - nopoll_conn_set_sock_tcp_nodelay (session, nopoll_true); - -+ nopoll_conn_set_outbound_interface(ctx,session, outbound_interface); - /* prepare socket configuration to operate using TCP/IP - * socket */ +- +- /* disable nagle */ +- nopoll_conn_set_sock_tcp_nodelay (session, nopoll_true); +- +- /* prepare socket configuration to operate using TCP/IP +- * socket */ - memset(&saddr, 0, sizeof(saddr)); - saddr.sin_addr.s_addr = ((struct in_addr *)(hostent->h_addr))->s_addr; - saddr.sin_family = AF_INET; - saddr.sin_port = htons((uint16_t) strtod (port, NULL)); -+ memset(&saddr, 0, sizeof(saddr)); -+ saddr.sin_addr.s_addr = ((struct in_addr *) ptr)->s_addr; -+ saddr.sin_family = AF_INET; -+ saddr.sin_port = htons((uint16_t) strtod (port, NULL)); - - /* set non blocking status */ - nopoll_conn_set_sock_block (session, nopoll_false); - - /* do a tcp connect */ +- +- /* set non blocking status */ +- nopoll_conn_set_sock_block (session, nopoll_false); +- +- /* do a tcp connect */ - if (connect (session, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { -+ if (connect (session, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { - if(errno != NOPOLL_EINPROGRESS && errno != NOPOLL_EWOULDBLOCK && errno != NOPOLL_ENOTCONN) { +- if(errno != NOPOLL_EINPROGRESS && errno != NOPOLL_EWOULDBLOCK && errno != NOPOLL_ENOTCONN) { - shutdown (session, SHUT_RDWR); - nopoll_close_socket (session); -+ shutdown (session, SHUT_RDWR); -+ nopoll_close_socket (session); - - nopoll_log (ctx, NOPOLL_LEVEL_WARNING, "unable to connect to remote host %s:%s errno=%d", - host, port, errno); -+ freeaddrinfo(result); - return -1; - } /* end if */ - } /* end if */ - -+ freeaddrinfo(result); - /* return socket created */ - return session; +- nopoll_log (ctx, NOPOLL_LEVEL_WARNING, "unable to connect to remote host %s:%s errno=%d", +- host, port, errno); +- return -1; +- } /* end if */ +- } /* end if */ +- +- /* return socket created */ +- return session; ++ } ++ else ++ { ++ for (rp = result; rp != NULL; rp = rp->ai_next) ++ { ++ nopoll_log (ctx, NOPOLL_LEVEL_DEBUG, "rp->ai_family %d ", rp->ai_family); ++ nopoll_log (ctx, NOPOLL_LEVEL_DEBUG, "rp->ai_socktype %d", rp->ai_socktype); ++ nopoll_log (ctx, NOPOLL_LEVEL_DEBUG, "rp->ai_protocol %d", rp->ai_protocol); ++ ++ if(rp->ai_family == AF_INET) ++ { ++ ptr = &((struct sockaddr_in *) rp->ai_addr)->sin_addr; ++ inet_ntop (rp->ai_family, ptr, addrstr, 100); ++ nopoll_log (ctx, NOPOLL_LEVEL_INFO, "IPv4 address of %s is %s \n", host, addrstr); ++ ++ if (strcmp(localIp,addrstr) == 0) ++ { ++ /* If Host DNS is resolved to 10.0.0.1 which means there is problem and client should not connect to this address */ ++ nopoll_log (ctx, NOPOLL_LEVEL_DEBUG, "Host Ip resolved to 10.0.0.1"); ++ nopoll_log (ctx, NOPOLL_LEVEL_CRITICAL, "unable to connect to remote host %s:%s as IP resolved to 10.0.0.1", host, port); ++ freeaddrinfo(result); ++ return -1; ++ ++ } ++ } ++ else if(rp->ai_family == AF_INET6) ++ { ++ ptr = &((struct sockaddr_in6 *) rp->ai_addr)->sin6_addr; ++ inet_ntop (rp->ai_family, ptr, addrstr, 100); ++ nopoll_log (ctx, NOPOLL_LEVEL_INFO, "IPv6 address of %s is %s \n", host, addrstr); ++ } ++ ++ session = socket(rp->ai_family, rp->ai_socktype, 0); ++ if (session == NOPOLL_INVALID_SOCKET) ++ { ++ nopoll_log (ctx, NOPOLL_LEVEL_CRITICAL, "unable to create socket"); ++ continue; ++ } ++ else ++ { ++ nopoll_log (ctx, NOPOLL_LEVEL_DEBUG, "Socket Creation Successful"); ++ } ++ ++ nopoll_conn_set_sock_tcp_nodelay (session, nopoll_true); ++ ++ nopoll_conn_set_outbound_interface(ctx,session, outbound_interface); ++ ++ if (connect(session, rp->ai_addr, rp->ai_addrlen) < 0) ++ { ++ if(errno != NOPOLL_EINPROGRESS && errno != NOPOLL_EWOULDBLOCK && errno != NOPOLL_ENOTCONN && errno != NOPOLL_ETIMEDOUT) ++ { ++ shutdown (session, SHUT_RDWR); ++ nopoll_close_socket (session); ++ ++ nopoll_log (ctx, NOPOLL_LEVEL_WARNING, "unable to connect to remote host %s:%s errno=%d", ++ host, port, errno); ++ freeaddrinfo(result); ++ return -1; ++ } /* end if */ ++ ++ } ++ else ++ { ++ nopoll_log (ctx, NOPOLL_LEVEL_DEBUG, "Socket Connect successful"); ++ break; ++ } ++ close(session); ++ } ++ ++ if (rp == NULL) { /* No address succeeded */ ++ nopoll_log (ctx, NOPOLL_LEVEL_CRITICAL, "Could not connect. No valid IP resolved, Returning -1"); ++ return -1; ++ } ++ freeaddrinfo(result); ++ return session; ++ } } @@ -195,7 +246,7 @@ index 8612bfd..c2965b2 100644 /* get the nonce */ if (! nopoll_nonce (nonce, 16)) { nopoll_log (conn->ctx, NOPOLL_LEVEL_CRITICAL, "Failed to get nonce, unable to produce Sec-WebSocket-Key."); -@@ -287,9 +388,15 @@ char * __nopoll_conn_get_client_init (noPollConn * conn, noPollConnOpts * opts) +@@ -287,9 +400,15 @@ char * __nopoll_conn_get_client_init (noPollConn * conn, noPollConnOpts * opts) /* create accept and store */ conn->handshake = nopoll_new (noPollHandShake, 1); conn->handshake->expected_accept = nopoll_strdup (key); @@ -214,7 +265,7 @@ index 8612bfd..c2965b2 100644 conn->get_url, conn->host_name, /* sec-websocket-key */ key, -@@ -305,7 +412,15 @@ char * __nopoll_conn_get_client_init (noPollConn * conn, noPollConnOpts * opts) +@@ -305,7 +424,15 @@ char * __nopoll_conn_get_client_init (noPollConn * conn, noPollConnOpts * opts) conn->protocols ? ": " : "", conn->protocols ? conn->protocols : "", conn->protocols ? "\r\n" : "", @@ -231,7 +282,46 @@ index 8612bfd..c2965b2 100644 } -@@ -478,6 +593,9 @@ SSL_CTX * __nopoll_conn_get_ssl_context (noPollCtx * ctx, noPollConn * conn, noP +@@ -438,10 +565,17 @@ int nopoll_conn_tls_send (noPollConn * conn, char * buffer, int buffer_size) + int res; + nopoll_bool needs_retry; + int tries = 0; +- ++ int ret = 0; ++ static pthread_mutex_t mut = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; ++ ++ ret = pthread_mutex_lock (&mut); ++ if(ret != 0) ++ { ++ nopoll_log (conn->ctx, NOPOLL_LEVEL_CRITICAL, "mutex failed to lock ( ret = %d) ( errno = %d)",ret, errno); ++ } + /* call to read content */ + while (tries < 50) { +- res = SSL_write (conn->ssl, buffer, buffer_size); ++ res = SSL_write (conn->ssl, buffer, buffer_size); + nopoll_log (conn->ctx, NOPOLL_LEVEL_DEBUG, "SSL: sent %d bytes (requested: %d)..", res, buffer_size); + + /* call to handle error */ +@@ -449,12 +583,17 @@ int nopoll_conn_tls_send (noPollConn * conn, char * buffer, int buffer_size) + /* nopoll_log (conn->ctx, NOPOLL_LEVEL_DEBUG, " SSL: after processing error, sent %d bytes (requested: %d)..", res, buffer_size); */ + + if (! needs_retry) +- break; ++ break; + + /* next operation */ + nopoll_sleep (tries * 10000); + tries++; + } ++ ret = pthread_mutex_unlock (&mut); ++ if(ret != 0) ++ { ++ nopoll_log (conn->ctx, NOPOLL_LEVEL_CRITICAL, "mutex failed to unlock ( ret = %d) ( errno = %d)",ret, errno); ++ } + return res; + } + +@@ -478,6 +617,9 @@ SSL_CTX * __nopoll_conn_get_ssl_context (noPollCtx * ctx, noPollConn * conn, noP /* printf ("**** REPORTING TLSv1.1 ****\n"); */ return SSL_CTX_new (is_client ? TLSv1_1_client_method () : TLSv1_1_server_method ()); #endif @@ -241,7 +331,7 @@ index 8612bfd..c2965b2 100644 case NOPOLL_METHOD_SSLV3: /* printf ("**** REPORTING SSLv3 ****\n"); */ return SSL_CTX_new (is_client ? SSLv3_client_method () : SSLv3_server_method ()); -@@ -598,7 +716,11 @@ noPollConn * __nopoll_conn_new_common (noPollCtx * ctx, +@@ -598,7 +740,11 @@ noPollConn * __nopoll_conn_new_common (noPollCtx * ctx, const char * host_name, const char * get_url, const char * protocols, @@ -254,7 +344,7 @@ index 8612bfd..c2965b2 100644 { noPollConn * conn; NOPOLL_SOCKET session; -@@ -620,7 +742,8 @@ noPollConn * __nopoll_conn_new_common (noPollCtx * ctx, +@@ -620,11 +766,12 @@ noPollConn * __nopoll_conn_new_common (noPollCtx * ctx, host_port = "80"; /* create socket connection in a non block manner */ @@ -264,7 +354,12 @@ index 8612bfd..c2965b2 100644 if (session == NOPOLL_INVALID_SOCKET) { /* release connection options */ __nopoll_conn_opts_release_if_needed (options); -@@ -691,7 +814,7 @@ noPollConn * __nopoll_conn_new_common (noPollCtx * ctx, +- nopoll_log (ctx, NOPOLL_LEVEL_CRITICAL, "Failed to connect to remote host %s:%s", host_ip, host_port); ++ nopoll_log (ctx, NOPOLL_LEVEL_DEBUG, "Failed to connect to remote host %s:%s", host_ip, host_port); + return NULL; + } /* end if */ + +@@ -691,7 +838,7 @@ noPollConn * __nopoll_conn_new_common (noPollCtx * ctx, /* get client init payload */ @@ -273,7 +368,7 @@ index 8612bfd..c2965b2 100644 if (content == NULL) { nopoll_log (ctx, NOPOLL_LEVEL_CRITICAL, "Failed to build client init message, unable to connect"); -@@ -905,12 +1028,16 @@ noPollConn * nopoll_conn_new (noPollCtx * ctx, +@@ -905,12 +1052,16 @@ noPollConn * nopoll_conn_new (noPollCtx * ctx, const char * host_name, const char * get_url, const char * protocols, @@ -292,7 +387,7 @@ index 8612bfd..c2965b2 100644 } /** -@@ -961,12 +1088,16 @@ noPollConn * nopoll_conn_new_opts (noPollCtx * ctx, +@@ -961,12 +1112,16 @@ noPollConn * nopoll_conn_new_opts (noPollCtx * ctx, const char * host_name, const char * get_url, const char * protocols, @@ -311,7 +406,7 @@ index 8612bfd..c2965b2 100644 } nopoll_bool __nopoll_tls_was_init = nopoll_false; -@@ -1021,7 +1152,11 @@ noPollConn * nopoll_conn_tls_new (noPollCtx * ctx, +@@ -1021,7 +1176,11 @@ noPollConn * nopoll_conn_tls_new (noPollCtx * ctx, const char * host_name, const char * get_url, const char * protocols, @@ -324,7 +419,7 @@ index 8612bfd..c2965b2 100644 { /* init ssl ciphers and engines */ if (! __nopoll_tls_was_init) { -@@ -1032,7 +1167,7 @@ noPollConn * nopoll_conn_tls_new (noPollCtx * ctx, +@@ -1032,7 +1191,7 @@ noPollConn * nopoll_conn_tls_new (noPollCtx * ctx, /* call common implementation */ return __nopoll_conn_new_common (ctx, options, nopoll_true, host_ip, host_port, host_name, @@ -333,7 +428,7 @@ index 8612bfd..c2965b2 100644 } /** -@@ -1128,7 +1263,9 @@ nopoll_bool nopoll_conn_is_ready (noPollConn * conn) +@@ -1128,7 +1287,9 @@ nopoll_bool nopoll_conn_is_ready (noPollConn * conn) return nopoll_false; if (conn->session == NOPOLL_INVALID_SOCKET) return nopoll_false; @@ -344,7 +439,7 @@ index 8612bfd..c2965b2 100644 /* acquire here handshake mutex */ nopoll_mutex_lock (conn->ref_mutex); -@@ -1138,6 +1275,11 @@ nopoll_bool nopoll_conn_is_ready (noPollConn * conn) +@@ -1138,6 +1299,11 @@ nopoll_bool nopoll_conn_is_ready (noPollConn * conn) /* release here handshake mutex */ nopoll_mutex_unlock (conn->ref_mutex); } @@ -356,7 +451,7 @@ index 8612bfd..c2965b2 100644 return conn->handshake_ok; } -@@ -1202,6 +1344,22 @@ int nopoll_conn_get_id (noPollConn * conn) +@@ -1202,6 +1368,22 @@ int nopoll_conn_get_id (noPollConn * conn) return conn->id; } @@ -379,7 +474,21 @@ index 8612bfd..c2965b2 100644 /** * @brief Allows to get the noPollCtx context object associated to the * connection (or where the connection is working). -@@ -1819,6 +1977,32 @@ void __nopoll_pack_content (char * buffer, int start, int bytes) +@@ -1440,6 +1622,13 @@ void nopoll_conn_shutdown (noPollConn * conn) + if (conn->session != NOPOLL_INVALID_SOCKET && conn->on_close) + conn->on_close (conn->ctx, conn, conn->on_close_data); + ++ if(conn->on_close_data != NULL) ++ { ++ nopoll_log(conn->ctx, NOPOLL_LEVEL_DEBUG,"freeing conn->on_close_data from shutdown...\n"); ++ nopoll_free(conn->on_close_data); ++ conn->on_close_data = NULL; ++ } ++ + /* shutdown connection here */ + if (conn->session != NOPOLL_INVALID_SOCKET) { + shutdown (conn->session, SHUT_RDWR); +@@ -1819,6 +2008,32 @@ void __nopoll_pack_content (char * buffer, int start, int bytes) return; } @@ -412,7 +521,7 @@ index 8612bfd..c2965b2 100644 /** * @internal Function used to read bytes from the wire. * -@@ -1828,6 +2012,7 @@ void __nopoll_pack_content (char * buffer, int start, int bytes) +@@ -1828,6 +2043,7 @@ void __nopoll_pack_content (char * buffer, int start, int bytes) int __nopoll_conn_receive (noPollConn * conn, char * buffer, int maxlen) { int nread; @@ -420,7 +529,7 @@ index 8612bfd..c2965b2 100644 if (conn->pending_buf_bytes > 0) { nopoll_log (conn->ctx, NOPOLL_LEVEL_DEBUG, "Calling with bytes we can reuse (%d), requested: %d", -@@ -1864,14 +2049,21 @@ int __nopoll_conn_receive (noPollConn * conn, char * buffer, int maxl +@@ -1864,14 +2080,21 @@ int __nopoll_conn_receive (noPollConn * conn, char * buffer, int maxl #if defined(NOPOLL_OS_UNIX) errno = 0; #endif @@ -448,7 +557,7 @@ index 8612bfd..c2965b2 100644 nopoll_log (conn->ctx, NOPOLL_LEVEL_CRITICAL, "unable to readn=%d, error code was: %d (%s) (shutting down connection)", maxlen, errno, strerror (errno)); nopoll_conn_shutdown (conn); -@@ -1881,6 +2073,12 @@ int __nopoll_conn_receive (noPollConn * conn, char * buffer, int maxl +@@ -1881,6 +2104,12 @@ int __nopoll_conn_receive (noPollConn * conn, char * buffer, int maxl /* nopoll_log (conn->ctx, NOPOLL_LEVEL_DEBUG, " returning bytes read = %d", nread); */ if (nread == 0) { /* check for blocking operations */ @@ -461,7 +570,12 @@ index 8612bfd..c2965b2 100644 if (errno == NOPOLL_EAGAIN || errno == NOPOLL_EWOULDBLOCK) { nopoll_log (conn->ctx, NOPOLL_LEVEL_WARNING, "unable to read from conn-id=%d (%s:%s), connection is not ready (errno: %d : %s)", conn->id, conn->host, conn->port, errno, strerror (errno)); -@@ -1894,8 +2092,10 @@ int __nopoll_conn_receive (noPollConn * conn, char * buffer, int maxl +@@ -1890,12 +2119,15 @@ int __nopoll_conn_receive (noPollConn * conn, char * buffer, int maxl + nopoll_log (conn->ctx, NOPOLL_LEVEL_CRITICAL, "received connection close while reading from conn id %d (errno=%d : %s) (%d, %d, %d), shutting down connection..", + conn->id, errno, strerror (errno), + NOPOLL_EAGAIN, NOPOLL_EWOULDBLOCK, NOPOLL_EINTR); ++ conn->on_close_data = nopoll_strdup ("SSL_Socket_Close:received connection close while reading from conn: shutting down connection"); + nopoll_conn_shutdown (conn); } /* end if */ /* ensure we don't access outside the array */ @@ -473,7 +587,7 @@ index 8612bfd..c2965b2 100644 buffer[nread] = 0; return nread; -@@ -2350,6 +2550,13 @@ int nopoll_conn_complete_handshake_client (noPollCtx * ctx, noPollConn * conn, c +@@ -2350,6 +2582,13 @@ int nopoll_conn_complete_handshake_client (noPollCtx * ctx, noPollConn * conn, c iterator++; if (! nopoll_ncmp (buffer + iterator, "101", 3)) { nopoll_log (ctx, NOPOLL_LEVEL_CRITICAL, "websocket server denied connection with: %s", buffer + iterator); @@ -487,7 +601,7 @@ index 8612bfd..c2965b2 100644 return 0; /* do not continue */ } /* end if */ -@@ -2387,7 +2594,14 @@ int nopoll_conn_complete_handshake_client (noPollCtx * ctx, noPollConn * conn, c +@@ -2387,7 +2626,14 @@ int nopoll_conn_complete_handshake_client (noPollCtx * ctx, noPollConn * conn, c } else if (strcasecmp (header, "Connection") == 0) { conn->handshake->connection_upgrade = 1; nopoll_free (value); @@ -503,7 +617,7 @@ index 8612bfd..c2965b2 100644 /* release value, no body claimed it */ nopoll_free (value); } /* end if */ -@@ -2606,7 +2820,7 @@ noPollMsg * nopoll_conn_get_msg (noPollConn * conn) +@@ -2606,7 +2852,7 @@ noPollMsg * nopoll_conn_get_msg (noPollConn * conn) if (conn->previous_msg) { nopoll_log (conn->ctx, NOPOLL_LEVEL_WARNING, "Reading bytes (previously read %d) from a previous unfinished frame (pending: %d) over conn-id=%d", conn->previous_msg->payload_size, conn->previous_msg->remain_bytes, conn->id); @@ -512,7 +626,7 @@ index 8612bfd..c2965b2 100644 /* build next message holder to continue with this content */ if (conn->previous_msg->payload_size > 0) { msg = nopoll_msg_new (); -@@ -2702,7 +2916,7 @@ noPollMsg * nopoll_conn_get_msg (noPollConn * conn) +@@ -2702,7 +2948,7 @@ noPollMsg * nopoll_conn_get_msg (noPollConn * conn) memcpy (conn->pending_buf + conn->pending_buf_bytes, buffer, bytes); conn->pending_buf_bytes += bytes; @@ -521,7 +635,7 @@ index 8612bfd..c2965b2 100644 "Expected to receive complete websocket frame header but found only %d bytes over conn-id=%d, saving to reuse later", bytes, conn->id); return NULL; -@@ -2810,7 +3024,7 @@ noPollMsg * nopoll_conn_get_msg (noPollConn * conn) +@@ -2810,7 +3056,7 @@ noPollMsg * nopoll_conn_get_msg (noPollConn * conn) /* nothing more to add here, close frame without content received, so we have no reason to keep on reading */ @@ -530,7 +644,7 @@ index 8612bfd..c2965b2 100644 nopoll_msg_unref (msg); nopoll_conn_shutdown (conn); return NULL; -@@ -2823,12 +3037,12 @@ noPollMsg * nopoll_conn_get_msg (noPollConn * conn) +@@ -2823,12 +3069,12 @@ noPollMsg * nopoll_conn_get_msg (noPollConn * conn) if (msg->op_code == NOPOLL_PING_FRAME) { nopoll_log (conn->ctx, NOPOLL_LEVEL_DEBUG, "PING received over connection id=%d, replying PONG", conn->id); @@ -547,7 +661,7 @@ index 8612bfd..c2965b2 100644 } /* end if */ /* get more bytes */ -@@ -2930,6 +3144,8 @@ read_payload: +@@ -2930,6 +3176,8 @@ read_payload: /* update was a fragment */ conn->previous_was_fragment = msg->is_fragment && msg->has_fin == 0; @@ -556,7 +670,7 @@ index 8612bfd..c2965b2 100644 /* do not notify any frame since no content was found */ if (bytes == 0 && msg == conn->previous_msg) { nopoll_log (conn->ctx, NOPOLL_LEVEL_DEBUG, "bytes == %d, msg (%p) == conn->previous_msg (%p)", -@@ -3370,6 +3586,20 @@ void nopoll_conn_set_on_msg (noPollConn * conn, +@@ -3370,6 +3618,20 @@ void nopoll_conn_set_on_msg (noPollConn * conn, return; } @@ -577,7 +691,7 @@ index 8612bfd..c2965b2 100644 /** * @brief Allows to configure a handler that is called when the -@@ -4129,14 +4359,18 @@ nopoll_bool nopoll_conn_accept_complete (noPollCtx * ctx, noPollConn * listener, +@@ -4129,14 +4391,18 @@ nopoll_bool nopoll_conn_accept_complete (noPollCtx * ctx, noPollConn * listener, * @param timeout The timeout operation to limit the wait * operation. Timeout is provided in seconds. * @@ -597,7 +711,7 @@ index 8612bfd..c2965b2 100644 /* check if the connection already finished its connection handshake */ -@@ -4153,8 +4387,31 @@ nopoll_bool nopoll_conn_wait_until_connection_ready (noPollConn * conn, +@@ -4153,8 +4419,31 @@ nopoll_bool nopoll_conn_wait_until_connection_ready (noPollConn * conn, total_timeout = total_timeout - 500; } /* end if */ @@ -631,7 +745,7 @@ index 8612bfd..c2965b2 100644 /* @} */ diff --git a/src/nopoll_conn.h b/src/nopoll_conn.h -index aff440f..b518acd 100644 +index aff440f..8beeb32 100644 --- a/src/nopoll_conn.h +++ b/src/nopoll_conn.h @@ -49,7 +49,11 @@ noPollConn * nopoll_conn_new (noPollCtx * ctx, @@ -662,7 +776,7 @@ index aff440f..b518acd 100644 noPollConn * nopoll_conn_tls_new (noPollCtx * ctx, noPollConnOpts * options, const char * host_ip, -@@ -67,7 +75,11 @@ noPollConn * nopoll_conn_tls_new (noPollCtx * ctx, +@@ -67,12 +75,18 @@ noPollConn * nopoll_conn_tls_new (noPollCtx * ctx, const char * host_name, const char * get_url, const char * protocols, @@ -675,7 +789,14 @@ index aff440f..b518acd 100644 noPollConn * nopoll_conn_accept (noPollCtx * ctx, noPollConn * listener); -@@ -97,6 +109,8 @@ void nopoll_conn_set_socket (noPollConn * conn, NOPOLL_SOCKET _socket) + noPollConn * nopoll_conn_accept_socket (noPollCtx * ctx, noPollConn * listener, NOPOLL_SOCKET session); + ++void nopoll_conn_set_on_ping_msg (noPollConn * conn, noPollOnMessageHandler on_ping_msg, noPollPtr user_data); ++ + nopoll_bool nopoll_conn_accept_complete (noPollCtx * ctx, + noPollConn * listener, + noPollConn * conn, +@@ -97,6 +111,8 @@ void nopoll_conn_set_socket (noPollConn * conn, NOPOLL_SOCKET _socket) int nopoll_conn_get_id (noPollConn * conn); @@ -684,7 +805,7 @@ index aff440f..b518acd 100644 noPollCtx * nopoll_conn_ctx (noPollConn * conn); noPollRole nopoll_conn_role (noPollConn * conn); -@@ -182,7 +196,7 @@ int __nopoll_conn_send_common (noPollConn * conn, +@@ -182,7 +198,7 @@ int __nopoll_conn_send_common (noPollConn * conn, noPollOpCode frame_type); nopoll_bool nopoll_conn_wait_until_connection_ready (noPollConn * conn, @@ -744,10 +865,18 @@ index a9e4154..0ef8e42 100644 noPollSslContextCreator context_creator, noPollPtr user_data); diff --git a/src/nopoll_decl.h b/src/nopoll_decl.h -index 72fe194..7151d90 100644 +index 72fe194..0b7be76 100644 --- a/src/nopoll_decl.h +++ b/src/nopoll_decl.h -@@ -255,7 +255,12 @@ typedef enum { +@@ -95,6 +95,7 @@ + * @brief Portable definition for EWOULDBLOCK errno code. + */ + #define NOPOLL_EWOULDBLOCK EWOULDBLOCK ++#define NOPOLL_ETIMEDOUT ETIMEDOUT + #define NOPOLL_EINPROGRESS EINPROGRESS + #define NOPOLL_ENOTCONN ENOTCONN + #define NOPOLL_EAGAIN EAGAIN +@@ -255,7 +256,12 @@ typedef enum { * @brief Debug level. Only used to report common * circumstances that represent the proper functionality. */ @@ -761,7 +890,7 @@ index 72fe194..7151d90 100644 /** * @brief Warning level. Only used to report that an internal * issue have happend that could be interesting while -@@ -447,6 +452,13 @@ typedef enum { +@@ -447,6 +453,13 @@ typedef enum { */ NOPOLL_METHOD_TLSV1_1 = 5 #endif @@ -1364,6 +1493,3 @@ index bd68694..ad47c3b 100644 /* send a message to request connection close with a particular message */ if (nopoll_conn_send_text (conn, "close with message", 18) != 18) { --- -1.9.1 - diff --git a/src/nopoll_helpers.c b/src/nopoll_helpers.c index 2a2fb2e..b969e4a 100644 --- a/src/nopoll_helpers.c +++ b/src/nopoll_helpers.c @@ -22,7 +22,7 @@ void handleUpstreamMessage(noPollConn *conn, void *msg, size_t len) int bytesWritten = 0; printf("handleUpstreamMessage length %zu\n", len); - printf("conn object is %s \n", conn); + //printf("conn object is %s \n", conn); if(nopoll_conn_is_ok(conn) && nopoll_conn_is_ready(conn)) { bytesWritten = nopoll_conn_send_binary(conn, msg, len); diff --git a/src/wss_mgr.c b/src/wss_mgr.c index 3979208..c5e987d 100644 --- a/src/wss_mgr.c +++ b/src/wss_mgr.c @@ -10,12 +10,14 @@ #include #include #include -#include +#include #include #include #include #include "wss_mgr.h" #include +#include +#include #include #include @@ -51,6 +53,8 @@ #define HARVESTER "harvester" #define GET_SET "get_set" +#define UNUSED(x) (void)(x) + /*----------------------------------------------------------------------------*/ /* Data Structures */ /*----------------------------------------------------------------------------*/ @@ -116,8 +120,11 @@ pthread_cond_t nano_con=PTHREAD_COND_INITIALIZER; /*----------------------------------------------------------------------------*/ static char createNopollConnection(); + static void listenerOnPingMessage (noPollCtx * ctx, noPollConn * conn, noPollMsg * msg, noPollPtr user_data); + static void listenerOnCloseMessage (noPollCtx * ctx, noPollConn * conn, noPollPtr user_data); + void getCurrentTime(struct timespec *timer); uint64_t getCurrentTimeInMicroSeconds(struct timespec *timer); long timeValDiff(struct timespec *starttime, struct timespec *finishtime); @@ -128,7 +135,6 @@ static void initMessageHandler(); static void *messageHandlerTask(); static void __report_log (noPollCtx * ctx, noPollDebugLevel level, const char * log_msg, noPollPtr user_data); - static void initUpStreamTask(); static void *handle_upstream(); static void processUpStreamTask(); @@ -142,6 +148,9 @@ static void handleUpStreamEvents(); */ static void __report_log (noPollCtx * ctx, noPollDebugLevel level, const char * log_msg, noPollPtr user_data) { + + UNUSED(ctx); + UNUSED(user_data); if (level == NOPOLL_LEVEL_DEBUG) { // printf("Debug: %s\n", log_msg); @@ -431,9 +440,10 @@ static char createNopollConnection() fclose(fp); } - struct timespec start,end,connErr_start,connErr_end,*startPtr,*endPtr,*connErr_startPtr,*connErr_endPtr; - startPtr = &start; - endPtr = &end; + //struct timespec start,end,connErr_start,connErr_end,*startPtr,*endPtr,*connErr_startPtr,*connErr_endPtr; + struct timespec connErr_start,connErr_end,*connErr_startPtr,*connErr_endPtr; + //startPtr = &start; + //endPtr = &end; connErr_startPtr = &connErr_start; connErr_endPtr = &connErr_end; strcpy(deviceMAC, parodusCfg.hw_mac); @@ -1124,7 +1134,7 @@ static void *messageHandlerTask() if (!terminated) { - listenerOnMessage(message->payload, message->len, &numOfClients, &clients); + listenerOnMessage(message->payload, message->len, &numOfClients, clients); } nopoll_msg_unref(message->msg); @@ -1159,6 +1169,11 @@ static void *messageHandlerTask() static void listenerOnMessage_queue(noPollCtx * ctx, noPollConn * conn, noPollMsg * msg,noPollPtr user_data) { + + UNUSED(ctx); + UNUSED(conn); + UNUSED(user_data); + ParodusMsg *message; if (terminated) @@ -1222,6 +1237,10 @@ static void listenerOnMessage_queue(noPollCtx * ctx, noPollConn * conn, noPollMs */ static 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); @@ -1239,7 +1258,11 @@ static void listenerOnPingMessage (noPollCtx * ctx, noPollConn * conn, noPollMsg static void listenerOnCloseMessage (noPollCtx * ctx, noPollConn * conn, noPollPtr user_data) { - + + + UNUSED(ctx); + UNUSED(conn); + printf("listenerOnCloseMessage(): mutex lock in producer thread\n"); if((user_data != NULL) && (strstr(user_data, "SSL_Socket_Close") != NULL) && !LastReasonStatus) diff --git a/tests/simple.c b/tests/simple.c index 109ec4b..a5797ff 100644 --- a/tests/simple.c +++ b/tests/simple.c @@ -35,8 +35,8 @@ #define CLIENT2_URL "tcp://127.0.0.1:6668" #define CLIENT3_URL "tcp://127.0.0.1:6669" -static void send_nanomsg_upstream(char **buf, int size); -int handle_testsuites(); +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() @@ -51,8 +51,8 @@ void test_nanomsg_client_registration1() void *bytes; int size =0; - int rv, rv1; - wrp_msg_t *message, *msg1; + int rv1; + wrp_msg_t *msg1; int sock; int byte =0; int t=25000; @@ -86,7 +86,7 @@ void test_nanomsg_client_registration1() int sock1 = nn_socket (AF_SP, NN_PULL); byte = 0; - int bind = nn_bind(sock1, reg.u.reg.url); + nn_bind(sock1, reg.u.reg.url); void *buf = NULL; nn_setsockopt(sock1, NN_SOL_SOCKET, NN_RCVTIMEO, &t, sizeof(t)); @@ -126,8 +126,8 @@ void test_nanomsg_client_registration2() void *bytes; int size; - int rv, rv1; - wrp_msg_t *message, *msg1; + int rv1; + wrp_msg_t *msg1; int sock; int byte =0; int t=28000; @@ -161,7 +161,7 @@ void test_nanomsg_client_registration2() int sock1 = nn_socket (AF_SP, NN_PULL); byte = 0; - int bind = nn_bind(sock1, reg.u.reg.url); + nn_bind(sock1, reg.u.reg.url); void *buf1 = NULL; @@ -201,8 +201,8 @@ void test_nanomsg_client_registration3() .u.reg.url = CLIENT3_URL}; void *bytes; int size; - int rv, rv1; - wrp_msg_t *message, *msg1; + int rv1; + wrp_msg_t *msg1; int sock; int byte =0; int t=35000; @@ -274,12 +274,12 @@ void test_nanomsg_downstream_success() int sock; int bit=0; - int rv =0; wrp_msg_t *message; void *buf =NULL; char* destVal = NULL; - char dest[32] = {'\0'}; - char *temp_ptr; +// 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, @@ -303,9 +303,11 @@ void test_nanomsg_downstream_success() //Decode and verify downstream request has received by correct registered client - rv = wrp_to_struct(buf, bit, WRP_BYTES, &message); + wrp_to_struct(buf, bit, WRP_BYTES, &message); destVal = message->u.req.dest; - temp_ptr = strtok(destVal , "/"); + dest = strtok(destVal , "/"); + //temp_ptr = strtok(destVal , "/"); +// printf("temp_ptr = %s \n", temp_ptr); strcpy(dest,strtok(NULL , "/")); printf("------>decoded dest:%s\n", dest); CU_ASSERT_STRING_EQUAL( msg.u.reg.service_name, dest ); @@ -383,7 +385,7 @@ void test_handleUpstreamMessage() 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", + 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) { @@ -440,7 +442,8 @@ void test_loadParodusCfg() { printf("Calling test_loadParodusCfg \n"); - ParodusCfg parodusCfg, tmpcfg; + //ParodusCfg parodusCfg, tmpcfg; + ParodusCfg tmpcfg; ParodusCfg *Cfg; @@ -497,21 +500,26 @@ void add_suites( CU_pSuite *suite ) /*----------------------------------------------------------------------------*/ /* External Functions */ /*----------------------------------------------------------------------------*/ -void main( void ) +int main( void ) { pid_t pid, pid1; char value[512] = {'\0'}; char* data =NULL; - int nbytes =0; 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}; - printf("command is:%s\n", command); - - printf("Starting parodus process \n"); + + + int size = sizeof(command)/sizeof(command[0]); + int i; + printf("commad: "); + for(i=0;i