diff --git a/CMakeLists.txt b/CMakeLists.txt index ba2b282..6db2272 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,8 +44,8 @@ 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 -Wno-missing-field-initializers") -#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 @@ -70,39 +70,13 @@ add_dependencies(libtrower-base64 trower-base64) ExternalProject_Add(lws PREFIX ${CMAKE_CURRENT_BINARY_DIR}/_prefix/lws GIT_REPOSITORY https://github.com/warmcat/libwebsockets.git - GIT_TAG "master" + GIT_TAG "ed92b6dfe75ad65a78dadfa4dc96da4568d95d69" CMAKE_ARGS += -DCMAKE_INSTALL_PREFIX=${INSTALL_DIR} -DCMAKE_BUILD_TYPE=DEBUG ) add_library(libwebsockets STATIC SHARED IMPORTED) add_dependencies(libwebsockets lws) - -# nopoll external dependency -#------------------------------------------------------------------------------- -set(PATCHES_DIR ${CMAKE_CURRENT_SOURCE_DIR}/patches) -set(NOPOLL_LOG_SRC ${PREFIX_DIR}/nopoll/src/nopoll/src/nopoll_log.c) -ExternalProject_Add(nopoll - PREFIX ${PREFIX_DIR}/nopoll - GIT_REPOSITORY https://github.com/ASPLes/nopoll.git - GIT_TAG "b18aacc06b4dc9700e0a261efc201a8e125e4328" - PATCH_COMMAND patch -p1 < ${PATCHES_DIR}/nopoll.patch - COMMAND touch NEWS README AUTHORS ChangeLog - COMMAND libtoolize --force - COMMAND aclocal - COMMAND autoheader --warnings=error - COMMAND automake --add-missing -Werror - COMMAND autoconf --force --warnings=error - CONFIGURE_COMMAND COMMAND /configure --prefix=${PREFIX} - --includedir=${INCLUDE_DIR} - --libdir=${LIBRARY_DIR} - ${CUSTOM_HOST} - BUILD_IN_SOURCE 1 -) -add_library(libnopoll STATIC SHARED IMPORTED) -add_dependencies(libnopoll nopoll) - - # nanoMsg external dependency #------------------------------------------------------------------------------- ExternalProject_Add(nanomsg diff --git a/patches/nopoll.patch b/patches/nopoll.patch deleted file mode 100644 index 3ff5224..0000000 --- a/patches/nopoll.patch +++ /dev/null @@ -1,1495 +0,0 @@ -diff --git a/src/nopoll_conn.c b/src/nopoll_conn.c -index 8612bfd..cd6f9da 100644 ---- a/src/nopoll_conn.c -+++ b/src/nopoll_conn.c -@@ -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 */ - -+/** -+ * @brief Allows to bind device -+ * -+ * @param socket The socket to be configured. -+ * -+ * @param outbound_interface The bind device name value to be configured -+ * -+ * @return nopoll_true if the operation is completed. -+ */ -+nopoll_bool nopoll_conn_set_outbound_interface (noPollCtx * ctx, NOPOLL_SOCKET socket, -+ const char * outbound_interface) -+{ -+ if(outbound_interface != NULL) { -+ /* 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 */ -+ return nopoll_true; -+} /* end */ -+ - /** - * @internal Allows to create a plain socket connection against the - * host and port provided. -@@ -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, -- const char * port) -+ const char * port, -+ const char * outbound_interface) - { -- struct hostent * hostent; -- 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 *result, *rp; -+ struct addrinfo hints = {}; -+ -+ memset(&hints,0,sizeof(hints)); -+ hints.ai_family = AF_UNSPEC; -+ hints.ai_socktype = SOCK_STREAM; -+ 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 */ -- -- /* 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)); -- -- /* 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(errno != NOPOLL_EINPROGRESS && errno != NOPOLL_EWOULDBLOCK && errno != NOPOLL_ENOTCONN) { -- 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); -- 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; -+ } - } - - -+/** -+ * @internal Function that builds the header string with multiple header -+ * header names and values passed as input. -+ */ -+char * getHeaderString(const char *headerNames[], const char *headerValues[], const int headerCount) -+{ -+ int index=0; -+ char *tempString = NULL; -+ char *headerString = NULL; -+ int size = 0; -+ for(index=0; index < headerCount; index++) -+ { -+ size = 4 + strlen(headerNames[index]) + strlen(headerValues[index]) + 1; /* "\r\n: " + headername + headervalue + '\0' */ -+ tempString = (char *)malloc(sizeof(char) * size); -+ sprintf(tempString, "\r\n%s: %s", headerNames[index],headerValues[index]); -+ -+ if(headerString) -+ { -+ headerString = (char *) realloc(headerString, sizeof(char) * (strlen(headerString) + size)); -+ headerString = strcat(headerString,tempString); -+ } -+ else -+ { -+ headerString = (char *) malloc(sizeof(char) * size); -+ strcpy(headerString,tempString); -+ } -+ free(tempString); -+ } -+ return headerString; -+} - - - /** - * @internal Function that builds the client init greetings that will - * be send to the server according to registered implementation. - */ --char * __nopoll_conn_get_client_init (noPollConn * conn, noPollConnOpts * opts) -+char * __nopoll_conn_get_client_init (noPollConn * conn,noPollConnOpts * opts, const char * headerNames[], const char * headerValues[], const int headerCount) - { - /* build sec-websocket-key */ - char key[50]; - int key_size = 50; - char nonce[17]; -+ char *request; - -+ char *headerString = NULL; - /* 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 +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); -- -- /* send initial handshake |cookie |prot | */ -- return nopoll_strdup_printf ("GET %s HTTP/1.1\r\nHost: %s\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Key: %s\r\nOrigin: %s\r\n%s%s%s%s%s%s%s%sSec-WebSocket-Version: %d\r\n\r\n", -+ -+ if(headerNames != NULL && headerValues != NULL && headerCount > 0) -+ { -+ headerString = getHeaderString(headerNames, headerValues, headerCount); -+ } -+ -+ /* send initial handshake */ -+ -+ request = nopoll_strdup_printf ("GET %s HTTP/1.1\r\nHost: %s\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Key: %s\r\nOrigin: %s\r\n%s%s%s%s%s%s%s%sSec-WebSocket-Version: %d%s\r\n\r\n", - conn->get_url, conn->host_name, - /* sec-websocket-key */ - key, -@@ -305,7 +424,15 @@ char * __nopoll_conn_get_client_init (noPollConn * conn, noPollConnOpts * opts) - conn->protocols ? ": " : "", - conn->protocols ? conn->protocols : "", - conn->protocols ? "\r\n" : "", -- conn->ctx->protocol_version); -+ conn->ctx->protocol_version, (headerString != NULL) ? headerString : ""); -+ -+ if(headerString != NULL) -+ { -+ free(headerString); -+ headerString = NULL; -+ } -+ -+ return request; - } - - -@@ -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 -+ case NOPOLL_METHOD_TLSV1_2: -+ nopoll_log (conn->ctx, NOPOLL_LEVEL_DEBUG, "**** REPORTING TLSv1.2 ****\n"); -+ return SSL_CTX_new (is_client ? TLSv1_2_client_method () : TLSv1_2_server_method ()); - case NOPOLL_METHOD_SSLV3: - /* printf ("**** REPORTING SSLv3 ****\n"); */ - return SSL_CTX_new (is_client ? SSLv3_client_method () : SSLv3_server_method ()); -@@ -598,7 +740,11 @@ noPollConn * __nopoll_conn_new_common (noPollCtx * ctx, - const char * host_name, - const char * get_url, - const char * protocols, -- const char * origin) -+ const char * origin, -+ const char * outbound_interface, -+ const char * headerNames[], -+ const char * headerValues[], -+ const int headerCount) - { - noPollConn * conn; - NOPOLL_SOCKET session; -@@ -620,11 +766,12 @@ noPollConn * __nopoll_conn_new_common (noPollCtx * ctx, - host_port = "80"; - - /* create socket connection in a non block manner */ -- session = nopoll_conn_sock_connect (ctx, host_ip, host_port); -+ session = nopoll_conn_sock_connect (ctx, host_ip, host_port, outbound_interface); -+ - if (session == NOPOLL_INVALID_SOCKET) { - /* release connection options */ - __nopoll_conn_opts_release_if_needed (options); -- 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 */ -- content = __nopoll_conn_get_client_init (conn, options); -+ content = __nopoll_conn_get_client_init (conn, options,headerNames, headerValues, headerCount); - - if (content == NULL) { - nopoll_log (ctx, NOPOLL_LEVEL_CRITICAL, "Failed to build client init message, unable to connect"); -@@ -905,12 +1052,16 @@ noPollConn * nopoll_conn_new (noPollCtx * ctx, - const char * host_name, - const char * get_url, - const char * protocols, -- const char * origin) -+ const char * origin, -+ const char * outbound_interface, -+ const char * headerNames[], -+ const char * headerValues[], -+ const int headerCount) - { - /* call common implementation */ - return __nopoll_conn_new_common (ctx, NULL, nopoll_false, - host_ip, host_port, host_name, -- get_url, protocols, origin); -+ get_url, protocols, origin, outbound_interface, headerNames, headerValues, headerCount); - } - - /** -@@ -961,12 +1112,16 @@ noPollConn * nopoll_conn_new_opts (noPollCtx * ctx, - const char * host_name, - const char * get_url, - const char * protocols, -- const char * origin) -+ const char * origin, -+ const char * outbound_interface, -+ const char * headerNames[], -+ const char * headerValues[], -+ const int headerCount) - { - /* call common implementation */ - return __nopoll_conn_new_common (ctx, opts, nopoll_false, - host_ip, host_port, host_name, -- get_url, protocols, origin); -+ get_url, protocols, origin, outbound_interface, headerNames, headerValues, headerCount); - } - - nopoll_bool __nopoll_tls_was_init = nopoll_false; -@@ -1021,7 +1176,11 @@ noPollConn * nopoll_conn_tls_new (noPollCtx * ctx, - const char * host_name, - const char * get_url, - const char * protocols, -- const char * origin) -+ const char * origin, -+ const char * outbound_interface, -+ const char * headerNames[], -+ const char * headerValues[], -+ const int headerCount) - { - /* init ssl ciphers and engines */ - if (! __nopoll_tls_was_init) { -@@ -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, -- get_url, protocols, origin); -+ get_url, protocols, origin, outbound_interface, headerNames, headerValues, headerCount); - } - - /** -@@ -1128,7 +1287,9 @@ nopoll_bool nopoll_conn_is_ready (noPollConn * conn) - return nopoll_false; - if (conn->session == NOPOLL_INVALID_SOCKET) - return nopoll_false; -- if (! conn->handshake_ok) { -+ -+ /* conn->handshake->received_307 will always be false other than http redirect */ -+ if (! conn->handshake_ok && !conn->handshake->received_307) { - /* acquire here handshake mutex */ - nopoll_mutex_lock (conn->ref_mutex); - -@@ -1138,6 +1299,11 @@ nopoll_bool nopoll_conn_is_ready (noPollConn * conn) - /* release here handshake mutex */ - nopoll_mutex_unlock (conn->ref_mutex); - } -+ -+ if(conn->handshake->received_307) -+ { -+ return nopoll_true; /* in case of http redirection, conn->handshake_ok will never be true as the response buffer from the server will never have "Sec-Websocket-Accept". Consequently, we have to return true to break the loop inside nopoll_conn_wait_until_connection_ready() */ -+ } - return conn->handshake_ok; - } - -@@ -1202,6 +1368,22 @@ int nopoll_conn_get_id (noPollConn * conn) - return conn->id; - } - -+/** -+ * @brief Allows to get the get_url from the connection -+ * -+ * @param conn The websocket connection where the operation takes place. -+ * -+ * @return The get_url provided be the client -+ * -+ */ -+const char * nopoll_conn_get_requested_url (noPollConn * conn) -+{ -+ if (conn->get_url == NULL) -+ return "/"; -+ else -+ return conn->get_url; -+} -+ - /** - * @brief Allows to get the noPollCtx context object associated to the - * connection (or where the connection is working). -@@ -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; - } - -+/** -+ * @internal Function to delay -+ * @note delay goes up by factor of .125 each time -+ * @note up to 1 sec max -+*/ -+static void __nopoll_receive_delay (long *wait_usecs) -+{ -+ long rem; -+ long t = *wait_usecs; -+ -+ nopoll_sleep (t); -+ -+ if (t == 1000000) { -+ return; -+ } -+ -+ rem = t >> 3; -+ t += rem; -+ if (t > 1000000) { -+ t = 1000000; -+ } -+ -+ *wait_usecs = t; -+} -+ -+ - /** - * @internal Function used to read bytes from the wire. - * -@@ -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; -+ long wait_usecs = 500; - - if (conn->pending_buf_bytes > 0) { - nopoll_log (conn->ctx, NOPOLL_LEVEL_DEBUG, "Calling with bytes we can reuse (%d), requested: %d", -@@ -1864,14 +2080,21 @@ int __nopoll_conn_receive (noPollConn * conn, char * buffer, int maxl - #if defined(NOPOLL_OS_UNIX) - errno = 0; - #endif -- if ((nread = conn->receive (conn, buffer, maxlen)) == NOPOLL_SOCKET_ERROR) { -- /* nopoll_log (conn->ctx, NOPOLL_LEVEL_DEBUG, " returning errno=%d (%s)", errno, strerror (errno)); */ -- if (errno == NOPOLL_EAGAIN) -- return 0; -- if (errno == NOPOLL_EWOULDBLOCK) -+ /* if ((nread = conn->receive (conn, buffer, maxlen)) == NOPOLL_SOCKET_ERROR) { */ -+ if ((nread = conn->receive (conn, buffer, maxlen)) < 0) { -+ nopoll_log (conn->ctx, NOPOLL_LEVEL_CRITICAL, " conn receive nread=%d, errno=%d (%s)", nread,errno, strerror (errno)); -+ if (errno == NOPOLL_EAGAIN) { -+ __nopoll_receive_delay (&wait_usecs); -+ goto keep_reading; -+ /* return 0; */ -+ } -+ if (errno == NOPOLL_EWOULDBLOCK) { - return 0; -- if (errno == NOPOLL_EINTR) -+ } -+ if (errno == NOPOLL_EINTR) { -+ __nopoll_receive_delay (&wait_usecs); - goto keep_reading; -+ } - - 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 +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 */ -+ if (errno == NOPOLL_EAGAIN) { -+ __nopoll_receive_delay (&wait_usecs); -+ goto keep_reading; -+ /* return 0; */ -+ } -+ nopoll_log (conn->ctx, NOPOLL_LEVEL_CRITICAL, "conn receive zero bytes, errno=%d (%s)", errno, strerror (errno)); - 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)); -@@ -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 */ -- if (nread < 0) -+ if (nread < 0) { -+ nopoll_log (conn->ctx, NOPOLL_LEVEL_CRITICAL, "** nread < 0 (%d)", nread); - nread = 0; -+ } - - buffer[nread] = 0; - return nread; -@@ -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); -+ if(nopoll_ncmp (buffer + iterator, "307", 3)|| nopoll_ncmp (buffer + iterator, "302", 3) || nopoll_ncmp (buffer + iterator, "303", 3) ) -+ { -+ nopoll_log (ctx, NOPOLL_LEVEL_INFO, "Received HTTP 30x response from server"); -+ /* Mark 307 flag as true */ -+ conn->handshake->received_307 = nopoll_true; -+ return 1; /* continue to read next lines for redirect Location */ -+ } - return 0; /* do not continue */ - } /* end if */ - -@@ -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); -- } else { -+ } else if (strcasecmp (header, "Location") == 0) { -+ if(conn->handshake->received_307) -+ { -+ conn->handshake->redirectURL = value; -+ nopoll_log (ctx, NOPOLL_LEVEL_INFO, "nopoll_conn_complete_handshake_client: conn->handshake->redirectURL: %s",conn->handshake->redirectURL); -+ } -+ } -+ else { - /* release value, no body claimed it */ - nopoll_free (value); - } /* end if */ -@@ -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); -- -+ - /* build next message holder to continue with this content */ - if (conn->previous_msg->payload_size > 0) { - msg = nopoll_msg_new (); -@@ -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; - -- nopoll_log (conn->ctx, NOPOLL_LEVEL_WARNING, -+ nopoll_log (conn->ctx, NOPOLL_LEVEL_DEBUG, - "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 +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 */ -- nopoll_log (conn->ctx, NOPOLL_LEVEL_DEBUG, "Proper connection close frame received id=%d, shutting down", conn->id); -+ nopoll_log (conn->ctx, NOPOLL_LEVEL_INFO, "Proper connection close frame received id=%d, shutting down", conn->id); - nopoll_msg_unref (msg); - nopoll_conn_shutdown (conn); - return NULL; -@@ -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); -- nopoll_msg_unref (msg); -+ /*nopoll_msg_unref (msg); - -- /* call to send pong */ -- nopoll_conn_send_pong (conn); -+ call to send pong */ -+ /*nopoll_conn_send_pong (conn); - -- return NULL; -+ return NULL;*/ - } /* end if */ - - /* get more bytes */ -@@ -2930,6 +3176,8 @@ read_payload: - /* update was a fragment */ - conn->previous_was_fragment = msg->is_fragment && msg->has_fin == 0; - -+ nopoll_log(conn->ctx, NOPOLL_LEVEL_DEBUG, "bytes %d, msg->payload_size %d, msg->remain_bytes %d, msg->has_fin %d, msg->op_code %d\n",bytes,msg->payload_size,msg->remain_bytes,msg->has_fin,msg->op_code); -+ - /* 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 +3618,20 @@ void nopoll_conn_set_on_msg (noPollConn * conn, - - return; - } -+void nopoll_conn_set_on_ping_msg (noPollConn * conn, -+ noPollOnMessageHandler on_ping_msg, -+ noPollPtr user_data) -+{ -+ if (conn == NULL) -+ return; -+ -+ /* configure on message handler */ -+ conn->on_ping_msg = on_ping_msg; -+ conn->on_ping_msg_data = user_data; -+ -+ return; -+} -+ - - /** - * @brief Allows to configure a handler that is called when the -@@ -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. - * -+ * @param message in-out parameter of 64 byte. The response message string description indicating -+ * "Success", "Failure" or "Redirect: Redirect_URL". Caller needs to allocate memory for this. -+ * - * @return The function returns when the timeout was reached or the - * connection is ready. In the case the connection is ready when the - * function finished nopoll_true is returned, otherwise nopoll_false. - */ - nopoll_bool nopoll_conn_wait_until_connection_ready (noPollConn * conn, -- int timeout) -+ int timeout, char * message) - { - long int total_timeout = timeout * 1000000; -+ nopoll_bool result = nopoll_false; - - /* check if the connection already finished its connection - handshake */ -@@ -4153,8 +4419,31 @@ nopoll_bool nopoll_conn_wait_until_connection_ready (noPollConn * conn, - total_timeout = total_timeout - 500; - } /* end if */ - -+ result = nopoll_conn_is_ok (conn) && nopoll_conn_is_ready (conn); -+ -+ if(conn->handshake->received_307 == nopoll_true && (conn->handshake->redirectURL != NULL)) -+ { -+ if(message != NULL) -+ { -+ snprintf(message, strlen(conn->handshake->redirectURL) + 10, "Redirect:%s", conn->handshake->redirectURL); -+ nopoll_free (conn->handshake->redirectURL); -+ } -+ conn->handshake->received_307 = nopoll_false; -+ nopoll_log (conn->ctx, NOPOLL_LEVEL_INFO, "nopoll_conn_wait_until_connection_ready() response: message: %s" ,message ); -+ return nopoll_false; /* retry with redirection URLs */ -+ } -+ else if(result && message != NULL) -+ { -+ strncpy(message, "Success", strlen("Success")+1); -+ } -+ else if(message != NULL) -+ { -+ strncpy(message, "Failure", strlen("Failure")+1); -+ } -+ nopoll_log (conn->ctx, NOPOLL_LEVEL_INFO, "*****End nopoll_conn_wait_until_connection_ready ****"); -+ - /* report if the connection is ok */ -- return nopoll_conn_is_ok (conn) && nopoll_conn_is_ready (conn); -+ return result; - } - - /* @} */ -diff --git a/src/nopoll_conn.h b/src/nopoll_conn.h -index aff440f..8beeb32 100644 ---- a/src/nopoll_conn.h -+++ b/src/nopoll_conn.h -@@ -49,7 +49,11 @@ noPollConn * nopoll_conn_new (noPollCtx * ctx, - const char * host_name, - const char * get_url, - const char * protocols, -- const char * origin); -+ const char * origin, -+ const char * outbound_interface, -+ const char * headerNames[], -+ const char * headerValues[], -+ const int headerCount); - - noPollConn * nopoll_conn_new_opts (noPollCtx * ctx, - noPollConnOpts * opts, -@@ -58,8 +62,12 @@ noPollConn * nopoll_conn_new_opts (noPollCtx * ctx, - const char * host_name, - const char * get_url, - const char * protocols, -- const char * origin); -- -+ const char * origin, -+ const char * outbound_interface, -+ const char * headerNames[], -+ const char * headerValues[], -+ const int headerCount); -+ - noPollConn * nopoll_conn_tls_new (noPollCtx * ctx, - noPollConnOpts * options, - const char * host_ip, -@@ -67,12 +75,18 @@ noPollConn * nopoll_conn_tls_new (noPollCtx * ctx, - const char * host_name, - const char * get_url, - const char * protocols, -- const char * origin); -+ const char * origin, -+ const char * outbound_interface, -+ const char * headerNames[], -+ const char * headerValues[], -+ const int headerCount); - - noPollConn * nopoll_conn_accept (noPollCtx * ctx, noPollConn * listener); - - 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); - -+const char * nopoll_conn_get_requested_url (noPollConn * conn); -+ - noPollCtx * nopoll_conn_ctx (noPollConn * conn); - - noPollRole nopoll_conn_role (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, -- int timeout); -+ int timeout, char * message); - - /** internal api **/ - void nopoll_conn_complete_handshake (noPollConn * conn); -diff --git a/src/nopoll_ctx.c b/src/nopoll_ctx.c -index de01024..84ab438 100644 ---- a/src/nopoll_ctx.c -+++ b/src/nopoll_ctx.c -@@ -334,8 +334,8 @@ void nopoll_ctx_unregister_conn (noPollCtx * ctx, - - /* acquire a reference to the conection */ - nopoll_conn_unref (conn); -- -- break; -+ nopoll_log (ctx, NOPOLL_LEVEL_INFO, "Returning, unlock of mutex is not required "); -+ return; - } /* end if */ - - iterator++; -@@ -650,6 +650,19 @@ void nopoll_ctx_set_on_msg (noPollCtx * ctx, - return; - } - -+void nopoll_ctx_set_on_ping_msg (noPollCtx * ctx, -+ noPollOnMessageHandler on_ping_msg, -+ noPollPtr user_data) -+{ -+ nopoll_return_if_fail (ctx, ctx); -+ -+ /* set new handler */ -+ ctx->on_ping_msg = on_ping_msg; -+ ctx->on_ping_msg_data = user_data; -+ -+ return; -+} -+ - /** - * @brief Allows to configure the handler that will be used to let - * user land code to define OpenSSL SSL_CTX object. -diff --git a/src/nopoll_ctx.h b/src/nopoll_ctx.h -index a9e4154..0ef8e42 100644 ---- a/src/nopoll_ctx.h -+++ b/src/nopoll_ctx.h -@@ -87,6 +87,10 @@ void nopoll_ctx_set_on_msg (noPollCtx * ctx, - noPollOnMessageHandler on_msg, - noPollPtr user_data); - -+void nopoll_ctx_set_on_ping_msg (noPollCtx * ctx, -+ noPollOnMessageHandler on_ping_msg, -+ noPollPtr user_data); -+ - void nopoll_ctx_set_ssl_context_creator (noPollCtx * ctx, - noPollSslContextCreator context_creator, - noPollPtr user_data); -diff --git a/src/nopoll_decl.h b/src/nopoll_decl.h -index 72fe194..0b7be76 100644 ---- a/src/nopoll_decl.h -+++ b/src/nopoll_decl.h -@@ -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. - */ -- NOPOLL_LEVEL_DEBUG, -+ NOPOLL_LEVEL_DEBUG, -+ /** -+ * @brief Info level. Only used to report information for debugging, common -+ * circumstances that represent the proper functionality. -+ */ -+ NOPOLL_LEVEL_INFO, - /** - * @brief Warning level. Only used to report that an internal - * issue have happend that could be interesting while -@@ -447,6 +453,13 @@ typedef enum { - */ - NOPOLL_METHOD_TLSV1_1 = 5 - #endif -+ /** -+ * @brief Allows to define TLSv1.2 as SSL protocol used by the -+ * client or server connection. A connection/listener -+ * established with this method will only understand this -+ * method. -+ */ -+ NOPOLL_METHOD_TLSV1_2 = 6 - } noPollSslProtocol ; - - BEGIN_C_DECLS -diff --git a/src/nopoll_log.c b/src/nopoll_log.c -index d05fc5c..7f5a01c 100644 ---- a/src/nopoll_log.c -+++ b/src/nopoll_log.c -@@ -203,6 +203,9 @@ void __nopoll_log (noPollCtx * ctx, const char * function_name, const char * fil - case NOPOLL_LEVEL_DEBUG: - printf ("(\e[1;32mdebug\e[0m) "); - break; -+ case NOPOLL_LEVEL_INFO: -+ printf ("(\e[1;32minfo\e[0m) "); -+ break; - case NOPOLL_LEVEL_WARNING: - printf ("(\e[1;33mwarning\e[0m) "); - break; -@@ -215,6 +218,9 @@ void __nopoll_log (noPollCtx * ctx, const char * function_name, const char * fil - case NOPOLL_LEVEL_DEBUG: - printf ("(debug)"); - break; -+ case NOPOLL_LEVEL_INFO: -+ printf ("(info)"); -+ break; - case NOPOLL_LEVEL_WARNING: - printf ("(warning)"); - break; -diff --git a/src/nopoll_loop.c b/src/nopoll_loop.c -index fb142ff..08e44e5 100644 ---- a/src/nopoll_loop.c -+++ b/src/nopoll_loop.c -@@ -48,6 +48,12 @@ - * @{ - */ - -+/*----------------------------------------------------------------------------*/ -+/* File Scoped Variables */ -+/*----------------------------------------------------------------------------*/ -+noPollMsg * fragMsg; -+int isPreviousMsgFragment = 0; -+ - /** - * @internal Function used by nopoll_loop_wait to register all - * connections into the io waiting object. -@@ -72,6 +78,15 @@ nopoll_bool nopoll_loop_register (noPollCtx * ctx, noPollConn * conn, noPollPtr - return nopoll_false; /* keep foreach, don't stop */ - } - -+noPollMsg * __nopoll_msg_join(noPollMsg *fragMsg, noPollMsg *msg) -+{ -+ noPollMsg *tempMsg = nopoll_msg_join(fragMsg,msg); -+ nopoll_msg_unref (fragMsg); -+ nopoll_msg_unref (msg); -+ -+ return tempMsg; -+} -+ - /** - * @internal Function used to handle incoming data from from the - * connection and to notify this data on the connection. -@@ -85,11 +100,64 @@ void nopoll_loop_process_data (noPollCtx * ctx, noPollConn * conn) - if (msg == NULL) - return; - -- /* found message, notify it */ -- if (conn->on_msg) -- conn->on_msg (ctx, conn, msg, conn->on_msg_data); -- else if (ctx->on_msg) -- ctx->on_msg (ctx, conn, msg, ctx->on_msg_data); -+ if(msg->op_code == NOPOLL_PING_FRAME) -+ { -+ /* Initialized ping msg handler */ -+ if (conn->on_ping_msg) -+ conn->on_ping_msg (ctx, conn, msg, conn->on_ping_msg_data); -+ else if (ctx->on_ping_msg) -+ ctx->on_ping_msg (ctx, conn, msg, ctx->on_ping_msg_data); -+ } -+ else { -+ /* found message, notify it */ -+ /* Initialized msg handler */ -+ -+ if(msg->has_fin == 0) -+ { -+ nopoll_log(ctx, NOPOLL_LEVEL_INFO, "Received Fragment - FIN: %d, Opcode: %d, payload size: %d, Remaining bytes: %d",msg->has_fin,msg->op_code,nopoll_msg_get_payload_size(msg),msg->remain_bytes); -+ isPreviousMsgFragment = 1; -+ if(fragMsg == NULL) -+ { -+ fragMsg = msg; -+ nopoll_log(ctx, NOPOLL_LEVEL_INFO, "Received fragment, joined the message, waiting for last fragment"); -+ return; -+ } -+ else -+ { -+ if(nopoll_msg_get_payload_size(msg) == msg->remain_bytes) -+ { -+ nopoll_log(ctx, NOPOLL_LEVEL_DEBUG,"nopoll_msg_ref_count(fragMsg) %d, nopoll_msg_ref_count(msg) %d\n",nopoll_msg_ref_count(fragMsg),nopoll_msg_ref_count(msg)); -+ msg = __nopoll_msg_join(fragMsg,msg); -+ nopoll_log(ctx, NOPOLL_LEVEL_INFO,"Received all the pending bytes, hence which means the complete message is received"); -+ fragMsg = NULL; -+ isPreviousMsgFragment = 0; -+ nopoll_log(ctx, NOPOLL_LEVEL_INFO,"Received last fragment payload size %d, joined the old fragment messages",msg->payload_size); -+ } -+ else -+ { -+ nopoll_log(ctx, NOPOLL_LEVEL_DEBUG,"nopoll_msg_ref_count(fragMsg) %d, nopoll_msg_ref_count(msg) %d\n",nopoll_msg_ref_count(fragMsg),nopoll_msg_ref_count(msg)); -+ fragMsg = __nopoll_msg_join(fragMsg,msg); -+ nopoll_log(ctx, NOPOLL_LEVEL_INFO, "Received fragment, joined the message, waiting for last fragment"); -+ return; -+ } -+ -+ } -+ } -+ else if(msg->has_fin == 1 && isPreviousMsgFragment && msg->op_code == NOPOLL_CONTINUATION_FRAME) -+ { -+ nopoll_log(ctx, NOPOLL_LEVEL_INFO, "Received Fragment - FIN: %d, Opcode: %d, payload size: %d, Remaining bytes: %d",msg->has_fin,msg->op_code,nopoll_msg_get_payload_size(msg),msg->remain_bytes); -+ nopoll_log(ctx, NOPOLL_LEVEL_DEBUG,"nopoll_msg_ref_count(fragMsg) %d, nopoll_msg_ref_count(msg) %d\n",nopoll_msg_ref_count(fragMsg),nopoll_msg_ref_count(msg)); -+ msg = __nopoll_msg_join(fragMsg,msg); -+ fragMsg = NULL; -+ isPreviousMsgFragment = 0; -+ nopoll_log(ctx, NOPOLL_LEVEL_INFO,"Received last fragment payload size %d, joined the old fragment messages",msg->payload_size); -+ } -+ -+ if (conn->on_msg) -+ conn->on_msg (ctx, conn, msg, conn->on_msg_data); -+ else if (ctx->on_msg) -+ ctx->on_msg (ctx, conn, msg, ctx->on_msg_data); -+ } - - /* release message */ - nopoll_msg_unref (msg); -@@ -264,6 +332,21 @@ int nopoll_loop_wait (noPollCtx * ctx, long timeout) - return 0; - } - -+/** -+ * @brief To determine if nopoll loop wait has ended/terminated. -+ * This is to identify termination i.e. when the nopoll loop wait stops and -+ * there are no connections then this returns 1 else 0. -+ * -+ * @param ctx The context object. -+ * -+ * @return The function returns 0 nopoll loop wait is running and -+ * 1 when the nopoll loop wait has ended/terminatedss -+ */ -+int nopoll_loop_ended (noPollCtx * ctx) -+{ -+ return (NULL == ctx->io_engine); -+} -+ - /* @} */ - - -diff --git a/src/nopoll_loop.h b/src/nopoll_loop.h -index 245d973..338e71a 100644 ---- a/src/nopoll_loop.h -+++ b/src/nopoll_loop.h -@@ -47,6 +47,8 @@ int nopoll_loop_wait (noPollCtx * ctx, long timeout); - - void nopoll_loop_stop (noPollCtx * ctx); - -+int nopoll_loop_ended (noPollCtx * ctx); -+ - END_C_DECLS - - #endif -diff --git a/src/nopoll_private.h b/src/nopoll_private.h -index 847e0cf..c1bb08a 100644 ---- a/src/nopoll_private.h -+++ b/src/nopoll_private.h -@@ -123,7 +123,9 @@ struct _noPollCtx { - */ - noPollOnMessageHandler on_msg; - noPollPtr on_msg_data; -- -+ -+ noPollOnMessageHandler on_ping_msg; -+ noPollPtr on_ping_msg_data; - /** - * @internal Basic fake support for protocol version, by - * default: 13, due to RFC6455 standard -@@ -231,7 +233,9 @@ struct _noPollConn { - */ - noPollOnMessageHandler on_msg; - noPollPtr on_msg_data; -- -+ -+ noPollOnMessageHandler on_ping_msg; -+ noPollPtr on_ping_msg_data; - /** - * @internal Reference to defined on ready handling. - */ -@@ -357,6 +361,7 @@ struct _noPollHandshake { - nopoll_bool upgrade_websocket; - nopoll_bool connection_upgrade; - nopoll_bool received_101; -+ nopoll_bool received_307; - char * websocket_key; - char * websocket_version; - char * websocket_accept; -@@ -364,6 +369,8 @@ struct _noPollHandshake { - - /* reference to cookie header */ - char * cookie; -+ /* redirect Location URL */ -+ char * redirectURL; - }; - - struct _noPollConnOpts { -diff --git a/test/nopoll-regression-client.c b/test/nopoll-regression-client.c -index bd68694..ad47c3b 100644 ---- a/test/nopoll-regression-client.c -+++ b/test/nopoll-regression-client.c -@@ -286,7 +286,7 @@ nopoll_bool test_01 (void) { - ctx = create_ctx (); - - /* call to create a connection */ -- conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0); - if (! nopoll_conn_is_ok (conn)) { - printf ("ERROR: Expected to find proper client connection status, but found error (conn=%p, conn->session=%d, NOPOLL_INVALID_SOCKET=%d)..\n", - conn, (int) nopoll_conn_socket (conn), (int) NOPOLL_INVALID_SOCKET); -@@ -352,7 +352,7 @@ nopoll_bool test_02 (void) { - ctx = create_ctx (); - - /* call to create a connection */ -- conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0); - if (! nopoll_conn_is_ok (conn)) { - printf ("ERROR: Expected to find proper client connection status, but found error.. (conn=%p, conn->session=%d, NOPOLL_INVALID_SOCKET=%d, errno=%d, strerr=%s)..\n", - conn, (int) nopoll_conn_socket (conn), (int) NOPOLL_INVALID_SOCKET, errno, strerror (errno)); -@@ -424,7 +424,7 @@ nopoll_bool test_03 (void) { - ctx = create_ctx (); - - /* call to create a connection */ -- conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0); - if (! nopoll_conn_is_ok (conn)) { - printf ("ERROR: Expected to find proper client connection status, but found error..\n"); - return nopoll_false; -@@ -493,7 +493,7 @@ nopoll_bool test_04 (int chunk_size) { - ctx = create_ctx (); - - /* call to create a connection */ -- conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL,NULL, NULL,NULL,0); - if (! nopoll_conn_is_ok (conn)) { - printf ("ERROR: Expected to find proper client connection status, but found error..\n"); - return nopoll_false; -@@ -584,7 +584,7 @@ nopoll_bool test_04a (void) { - ctx = create_ctx (); - - /* call to create a connection */ -- conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL,NULL, NULL,NULL,0); - if (! nopoll_conn_is_ok (conn)) { - printf ("ERROR: Expected to find proper client connection status, but found error..\n"); - return nopoll_false; -@@ -642,14 +642,14 @@ nopoll_bool test_04b (void) { - ctx = create_ctx (); - - /* call to create a connection */ -- conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL,NULL, NULL,NULL,0); - if (! nopoll_conn_is_ok (conn)) { - printf ("ERROR: Expected to find proper client connection status, but found error..\n"); - return nopoll_false; - } - - printf ("Test 04-b: waiting until connection is ok\n"); -- nopoll_conn_wait_until_connection_ready (conn, 5); -+ nopoll_conn_wait_until_connection_ready (conn, 5, NULL); - - printf ("Test 04-b: sending was quick as possible to flood local buffers..\n"); - -@@ -709,14 +709,14 @@ nopoll_bool test_04b (void) { - nopoll_conn_close (conn); - - /* call to create a connection */ -- conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL,NULL, NULL,NULL,0); - if (! nopoll_conn_is_ok (conn)) { - printf ("ERROR: Expected to find proper client connection status, but found error..\n"); - return nopoll_false; - } - - printf ("Test 04-b: waiting until connection is ok\n"); -- nopoll_conn_wait_until_connection_ready (conn, 5); -+ nopoll_conn_wait_until_connection_ready (conn, 5, NULL); - - /* send a cleanup message */ - bytes_written = nopoll_conn_send_text (conn, "release-message", 15); -@@ -757,14 +757,14 @@ nopoll_bool test_04c (void) { - ctx = create_ctx (); - - /* call to create a connection */ -- conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL,NULL, NULL,NULL,0); - if (! nopoll_conn_is_ok (conn)) { - printf ("ERROR: Expected to find proper client connection status, but found error..\n"); - return nopoll_false; - } - - printf ("Test 04-c: waiting until connection is ok\n"); -- nopoll_conn_wait_until_connection_ready (conn, 5); -+ nopoll_conn_wait_until_connection_ready (conn, 5, NULL); - - /* remove local file */ - if (stat ("copy-test-04c.txt", &file_info) == 0) { -@@ -920,7 +920,7 @@ nopoll_bool test_05 (void) { - ctx = create_ctx (); - - /* call to create a connection */ -- conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL,NULL, NULL,NULL,0); - if (! nopoll_conn_is_ok (conn)) { - printf ("ERROR: Expected to find proper client connection status, but found error..\n"); - return nopoll_false; -@@ -972,7 +972,7 @@ nopoll_bool test_06 (void) { - nopoll_conn_opts_ssl_peer_verify (opts, nopoll_false); - - /* call to create a connection */ -- conn = nopoll_conn_tls_new (ctx, opts, "localhost", "1235", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_tls_new (ctx, opts, "localhost", "1235", NULL, NULL, NULL, NULL,NULL,NULL,NULL,0); - if (! nopoll_conn_is_ok (conn)) { - printf ("ERROR: Expected to find proper client connection status, but found error..\n"); - return nopoll_false; -@@ -1020,7 +1020,7 @@ nopoll_bool test_07 (void) { - nopoll_conn_opts_ssl_peer_verify (opts, nopoll_false); - - /* call to create a connection */ -- conn = nopoll_conn_tls_new (ctx, opts, "localhost", "1235", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_tls_new (ctx, opts, "localhost", "1235", NULL, NULL, NULL, NULL,NULL,NULL,NULL,0); - if (! nopoll_conn_is_ok (conn)) { - printf ("ERROR: Expected to find proper client connection status, but found error..\n"); - return nopoll_false; -@@ -1062,7 +1062,7 @@ nopoll_bool test_08 (void) { - ctx = create_ctx (); - - /* call to connect to TLS port expecting non-TLS protocol */ -- conn = nopoll_conn_new (ctx, "localhost", "1235", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_new (ctx, "localhost", "1235", NULL, NULL, NULL, NULL,NULL, NULL,NULL,0); - - /* wait a bit 100ms */ - nopoll_sleep (100000); -@@ -1093,7 +1093,7 @@ nopoll_bool test_09 (void) { - nopoll_ctx_set_protocol_version (ctx, 12); - - /* call to connect to TLS port expecting non-TLS protocol */ -- conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL,NULL, NULL,NULL,0); - - /* wait a bit 100ms */ - nopoll_sleep (100000); -@@ -1121,7 +1121,7 @@ nopoll_bool test_10 (void) { - ctx = create_ctx (); - - /* call to connect from an origining that shouldn't be allowed */ -- conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, "http://deny.aspl.es"); -+ conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, "http://deny.aspl.es",NULL, NULL,NULL,0); - - /* wait a bit 100ms */ - nopoll_sleep (100000); -@@ -1149,9 +1149,9 @@ nopoll_bool test_11 (void) { - ctx = create_ctx (); - - /* create a working connection */ -- conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL,NULL, NULL,NULL,0); - -- if (! nopoll_conn_wait_until_connection_ready (conn, 5)) { -+ if (! nopoll_conn_wait_until_connection_ready (conn, 5, NULL)) { - printf ("ERROR: Expected a FAILING connection status due to origing denied, but it working..\n"); - return nopoll_false; - } /* end if */ -@@ -1191,9 +1191,9 @@ nopoll_bool test_12 (void) { - iterator = 0; - while (iterator < 1000) { - /* create a working connection */ -- conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL,NULL, NULL,NULL,0); - -- if (! nopoll_conn_wait_until_connection_ready (conn, 5)) { -+ if (! nopoll_conn_wait_until_connection_ready (conn, 5, NULL)) { - printf ("ERROR: Expected NOT to find a FAILING connection status, errno is=%d..\n", errno); - return nopoll_false; - } /* end if */ -@@ -1325,7 +1325,7 @@ nopoll_bool test_14 (void) { - ctx = create_ctx (); - - /* call to create a connection */ -- conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL,NULL, NULL,NULL,0); - if (! nopoll_conn_is_ok (conn)) { - printf ("ERROR: Expected to find proper client connection status, but found error..\n"); - return nopoll_false; -@@ -1395,7 +1395,7 @@ nopoll_bool test_15 (void) { - ctx = create_ctx (); - - /* call to create a connection */ -- conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL,NULL, NULL,NULL,0); - if (! nopoll_conn_is_ok (conn)) { - printf ("ERROR: Expected to find proper client connection status, but found error..\n"); - return nopoll_false; -@@ -1469,7 +1469,7 @@ nopoll_bool test_16 (void) { - ctx = create_ctx (); - - /* call to create a connection */ -- conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL,NULL, NULL,NULL,0); - if (! nopoll_conn_is_ok (conn)) { - printf ("ERROR: Expected to find proper client connection status, but found error..\n"); - return nopoll_false; -@@ -1627,7 +1627,7 @@ nopoll_bool test_17 (void) { - } /* end if */ - - /* call to create a connection */ -- conn = nopoll_conn_new (ctx, "localhost", "22351", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_new (ctx, "localhost", "22351", NULL, NULL, NULL, NULL,NULL, NULL,NULL,0); - if (! nopoll_conn_is_ok (conn)) { - printf ("ERROR: Expected to find proper client connection status, but found error..\n"); - return nopoll_false; -@@ -1711,7 +1711,7 @@ nopoll_bool test_18 (void) { - nopoll_conn_opts_ssl_peer_verify (opts, nopoll_false); - - /* call to create a connection */ -- conn = nopoll_conn_tls_new (ctx, opts, "localhost", "1235", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_tls_new (ctx, opts, "localhost", "1235", NULL, NULL, NULL, NULL,NULL,NULL,NULL,0); - if (! nopoll_conn_is_ok (conn)) { - printf ("ERROR: Expected to find proper client connection status, but found error..\n"); - return nopoll_false; -@@ -1748,7 +1748,7 @@ nopoll_bool test_19 (void) { - nopoll_conn_opts_set_ssl_protocol (opts, NOPOLL_METHOD_SSLV23); - - /* create connection */ -- conn = nopoll_conn_tls_new (ctx, opts, "localhost", "1236", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_tls_new (ctx, opts, "localhost", "1236", NULL, NULL, NULL, NULL,NULL,NULL,NULL,0); - - /* check connection */ - if (! nopoll_conn_is_ok (conn)) { -@@ -1769,7 +1769,7 @@ nopoll_bool test_19 (void) { - nopoll_conn_opts_set_ssl_protocol (opts, NOPOLL_METHOD_SSLV23); - - /* create connection */ -- conn = nopoll_conn_tls_new (ctx, opts, "localhost", "1235", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_tls_new (ctx, opts, "localhost", "1235", NULL, NULL, NULL, NULL,NULL,NULL,NULL,0); - - /* check connection */ - if (! nopoll_conn_is_ok (conn)) { -@@ -1789,7 +1789,7 @@ nopoll_bool test_19 (void) { - - /* create connection */ - printf ("Test 19: checking SSLv3 with TLSv1..\n"); -- conn = nopoll_conn_tls_new (ctx, opts, "localhost", "1234", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_tls_new (ctx, opts, "localhost", "1234", NULL, NULL, NULL, NULL,NULL,NULL,NULL,0); - - /* check connection */ - if (nopoll_conn_is_ok (conn)) { -@@ -1850,7 +1850,7 @@ nopoll_bool test_21 (void) { - - /* call to create a connection */ - printf ("Test 21: check ssl connection (with auth certificate)..\n"); -- conn = nopoll_conn_tls_new (ctx, NULL, "localhost", "1239", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_tls_new (ctx, NULL, "localhost", "1239", NULL, NULL, NULL, NULL,NULL,NULL,NULL,0); - if (nopoll_conn_is_ok (conn)) { - printf ("ERROR: Expected to FAILURE client connection status, but ok..\n"); - return nopoll_false; -@@ -1868,7 +1868,7 @@ nopoll_bool test_21 (void) { - NULL, - /* ca certificate */ - "root.pem"); -- conn = nopoll_conn_tls_new (ctx, opts, "localhost", "1239", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_tls_new (ctx, opts, "localhost", "1239", NULL, NULL, NULL, NULL,NULL,NULL,NULL,0); - if (! test_sending_and_check_echo (conn, "Test 21", "This is a test")) { - printf ("ERROR: it should WORK, client certificate isn't working..\n"); - return nopoll_false; -@@ -1908,7 +1908,7 @@ nopoll_bool test_22 (void) { - ctx = create_ctx (); - - /* create connection */ -- conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL,NULL,NULL,NULL,0); - if (! nopoll_conn_is_ok (conn)) { - printf ("ERROR: Expected to find proper client connection status, but found error..\n"); - return nopoll_false; -@@ -1949,7 +1949,7 @@ nopoll_bool test_22 (void) { - nopoll_conn_opts_ssl_peer_verify (opts, nopoll_false); - - /* call to create a connection */ -- conn = nopoll_conn_tls_new (ctx, opts, "localhost", "1235", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_tls_new (ctx, opts, "localhost", "1235", NULL, NULL, NULL, NULL,NULL,NULL,NULL,0); - if (! nopoll_conn_is_ok (conn)) { - printf ("ERROR: Expected to find proper client connection status, but found error..\n"); - return nopoll_false; -@@ -2037,7 +2037,7 @@ nopoll_bool test_23 (void) { - ctx = create_ctx (); - - /* create connection */ -- conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL,NULL,NULL,NULL,0); - if (! nopoll_conn_is_ok (conn)) { - printf ("ERROR: Expected to find proper client connection status, but found error..\n"); - return nopoll_false; -@@ -2052,7 +2052,7 @@ nopoll_bool test_23 (void) { - nopoll_conn_close (conn); - - /* create connection */ -- conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL,NULL,NULL,NULL,0); - if (! nopoll_conn_is_ok (conn)) { - printf ("ERROR: Expected to find proper client connection status, but found error..\n"); - return nopoll_false; -@@ -2077,7 +2077,7 @@ nopoll_bool test_23 (void) { - nopoll_conn_opts_ssl_peer_verify (opts, nopoll_false); - - /* call to create a connection */ -- conn = nopoll_conn_tls_new (ctx, opts, "localhost", "1235", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_tls_new (ctx, opts, "localhost", "1235", NULL, NULL, NULL, NULL,NULL,NULL,NULL,0); - if (! nopoll_conn_is_ok (conn)) { - printf ("ERROR: Expected to find proper client connection status, but found error..\n"); - return nopoll_false; -@@ -2093,7 +2093,7 @@ nopoll_bool test_23 (void) { - /* call to create a connection second connection */ - opts = nopoll_conn_opts_new (); - nopoll_conn_opts_ssl_peer_verify (opts, nopoll_false); -- conn = nopoll_conn_tls_new (ctx, opts, "localhost", "1235", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_tls_new (ctx, opts, "localhost", "1235", NULL, NULL, NULL, NULL,NULL,NULL,NULL,0); - if (! nopoll_conn_is_ok (conn)) { - printf ("ERROR: Expected to find proper client connection status, but found error..\n"); - return nopoll_false; -@@ -2131,7 +2131,7 @@ nopoll_bool test_24 (void) { - nopoll_conn_opts_set_cookie (opts, "theme=light; sessionToken=abc123"); - - /* create connection */ -- conn = nopoll_conn_new_opts (ctx, opts, "localhost", "1234", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_new_opts (ctx, opts, "localhost", "1234", NULL, NULL, NULL, NULL,NULL,NULL,NULL,0); - if (! nopoll_conn_is_ok (conn)) { - printf ("ERROR: Expected to find proper client connection status, but found error..\n"); - return nopoll_false; -@@ -2186,7 +2186,7 @@ nopoll_bool test_25_check_cookie (noPollCtx * ctx, const char * cookie) { - nopoll_conn_opts_set_cookie (opts, cookie); - - /* create connection */ -- conn = nopoll_conn_new_opts (ctx, opts, "localhost", "1234", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_new_opts (ctx, opts, "localhost", "1234", NULL, NULL, NULL, NULL,NULL,NULL,NULL,0); - if (! nopoll_conn_is_ok (conn)) { - printf ("ERROR: Expected to find proper client connection status, but found error..\n"); - return nopoll_false; -@@ -2237,7 +2237,7 @@ nopoll_bool test_26 (void) { - ctx = create_ctx (); - - /* create connection */ -- conn = nopoll_conn_new (ctx, "echo.websocket.org", "80", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_new (ctx, "echo.websocket.org", "80", NULL, NULL, NULL, NULL,NULL,NULL,NULL,0); - if (! nopoll_conn_is_ok (conn)) { - printf ("ERROR: Expected to find proper client connection status, but found error..\n"); - return nopoll_false; -@@ -2265,7 +2265,7 @@ nopoll_bool test_27 (void) { - ctx = create_ctx (); - - /* create connection */ -- conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, "/", "chat-protocol", "http://www.aspl.es"); -+ conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, "/", "chat-protocol", "http://www.aspl.es",NULL,NULL,NULL,0); - if (! nopoll_conn_is_ok (conn)) { - printf ("ERROR: Expected to find proper client connection status, but found error..\n"); - return nopoll_false; -@@ -2288,7 +2288,7 @@ nopoll_bool test_27 (void) { - nopoll_conn_close (conn); - - /* create connection */ -- conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, "/", "hello-protocol", "http://www.aspl.es"); -+ conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, "/", "hello-protocol", "http://www.aspl.es",NULL,NULL,NULL,0); - if (! nopoll_conn_is_ok (conn)) { - printf ("ERROR: Expected to find proper client connection status, but found error..\n"); - return nopoll_false; -@@ -2328,14 +2328,14 @@ nopoll_bool test_28 (void) { - ctx = create_ctx (); - - /* create connection */ -- conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL); -+ conn = nopoll_conn_new (ctx, "localhost", "1234", NULL, NULL, NULL, NULL,NULL,NULL,NULL,0); - if (! nopoll_conn_is_ok (conn)) { - printf ("ERROR: Expected to find proper client connection status, but found error..\n"); - return nopoll_false; - } /* end if */ - - /* wait until it is connected */ -- nopoll_conn_wait_until_connection_ready (conn, 5); -+ nopoll_conn_wait_until_connection_ready (conn, 5, NULL); - - /* send a message to request connection close with a particular message */ - if (nopoll_conn_send_text (conn, "close with message", 18) != 18) { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6bc4f67..a63c266 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -11,7 +11,7 @@ # 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 mutex.c networking.c nopoll_handlers.c ParodusInternal.c +set(SOURCES main.c networking.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) add_executable(parodus ${SOURCES}) @@ -21,7 +21,6 @@ target_link_libraries (parodus -lwrp-c -lmsgpackc -ltrower-base64 - -lnopoll -llibseshat -luuid -lm diff --git a/src/ParodusInternal.c b/src/ParodusInternal.c index e594e25..fb9b8a1 100644 --- a/src/ParodusInternal.c +++ b/src/ParodusInternal.c @@ -74,8 +74,7 @@ char* getWebpaConveyHeader() buffer = cJSON_PrintUnformatted(response); ParodusInfo("X-WebPA-Convey Header: [%zd]%s\n", strlen(buffer), buffer); - /*TODO Remove nopoll related API*/ - if(nopoll_base64_encode (buffer, strlen(buffer), encodedData, &encodedDataSize) != nopoll_true) + if(lws_b64_encode_string (buffer, strlen(buffer), encodedData, encodedDataSize) < 0) { ParodusError("Base64 Encoding failed for Connection Header\n"); } diff --git a/src/ParodusInternal.h b/src/ParodusInternal.h index 0d07dfc..c92b67e 100644 --- a/src/ParodusInternal.h +++ b/src/ParodusInternal.h @@ -25,10 +25,10 @@ #include #include -#include #include #include #include +#include #include "parodus_log.h" /*----------------------------------------------------------------------------*/ diff --git a/src/conn_interface.c b/src/conn_interface.c index 54b110a..77b5589 100644 --- a/src/conn_interface.c +++ b/src/conn_interface.c @@ -13,8 +13,6 @@ #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 @@ -33,8 +31,6 @@ bool conn_retry = false; bool LastReasonStatus = false; -volatile unsigned int heartBeatTimer = 0; -pthread_mutex_t close_mut=PTHREAD_MUTEX_INITIALIZER; /*----------------------------------------------------------------------------*/ /* Function Prototypes */ @@ -67,6 +63,7 @@ void createLWSsocket(void *config_in, void (* initKeypress)()) } seshat_registered = __registerWithSeshat(); + UNUSED(seshat_registered); do { diff --git a/src/connection.c b/src/connection.c index 894ad56..8f60ab0 100644 --- a/src/connection.c +++ b/src/connection.c @@ -10,11 +10,8 @@ #include "time.h" #include "config.h" #include "upstream.h" -#include "nopoll_helpers.h" -#include "mutex.h" #include "spin_thread.h" -#include "nopoll_handlers.h" -#include +#include "lws_handlers.h" /*----------------------------------------------------------------------------*/ /* Macros */ @@ -94,9 +91,12 @@ dump_handshake_info(struct lws *wsi) char * join_fragment_msg (char *firstMsg,int firstSize,char *secondMsg,int secondSize,int * result) { *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; } @@ -106,7 +106,7 @@ parodus_callback(struct lws *wsi, enum lws_callback_reasons reason, { int n; char * payload = NULL; - char * out = NULL; + unsigned char * out = NULL; switch (reason) { case LWS_CALLBACK_CLIENT_ESTABLISHED: @@ -133,34 +133,36 @@ parodus_callback(struct lws *wsi, enum lws_callback_reasons reason, char * tmpMsg = NULL; payload = (char *)malloc(sizeof(char)*len); strcpy(payload,(char *)in); - if (lws_is_final_fragment(wsi)) - { - - if(fragmentMsg == NULL) - { - listenerOnrequest_queue(payload,len); - } - else - { - tmpMsg = join_fragment_msg(fragmentMsg,fragmentSize,payload,len,&payloadSize); - len = payloadSize; - listenerOnrequest_queue(tmpMsg,len); - fragmentMsg = NULL; - len = 0; - } - } - else - { - if(fragmentMsg == NULL) - { - fragmentMsg = payload; - fragmentSize = len; - } - else - { - fragmentMsg = join_fragment_msg(fragmentMsg,fragmentSize,payload,len,&payloadSize); - } - } + + if (lws_is_final_fragment(wsi)) + { + + if(fragmentMsg == NULL) + { + listenerOnrequest_queue(payload,len); + } + else + { + tmpMsg = join_fragment_msg(fragmentMsg,fragmentSize,payload,len,&payloadSize); + len = payloadSize; + listenerOnrequest_queue(tmpMsg,len); + fragmentMsg = NULL; + fragmentSize = 0; + payloadSize = 0; + } + } + else + { + if(fragmentMsg == NULL) + { + fragmentMsg = payload; + fragmentSize = len; + } + else + { + fragmentMsg = join_fragment_msg(fragmentMsg,fragmentSize,payload,len,&payloadSize); + } + } lws_callback_on_writable(wsi); break; @@ -176,22 +178,21 @@ parodus_callback(struct lws *wsi, enum lws_callback_reasons reason, if(ResponseMsgQ != NULL) { //Read response data from queue - pthread_mutex_lock (&res_mutex); - while(ResponseMsgQ) + while(ResponseMsgQ) { + pthread_mutex_lock (&res_mutex); UpStreamMsg *message = ResponseMsgQ; ResponseMsgQ = ResponseMsgQ->next; pthread_mutex_unlock (&res_mutex); - out = (char *)malloc(sizeof(char) * (LWS_PRE + message->len)); + out = (unsigned char *)malloc(sizeof(unsigned char) * (LWS_PRE + message->len)); memcpy (LWS_PRE + out, message->msg, message->len); - char * tmpPtr = LWS_PRE + out; - n = lws_write(wsi, tmpPtr, message->len, LWS_WRITE_BINARY); + n = lws_write(wsi, LWS_PRE + out, message->len, LWS_WRITE_BINARY); if (n < 0) { ParodusError("Failed to send to server\n"); - free(message); - message = NULL; + free(message->msg); + message->msg = NULL; return 1; } if (n < message->len) { @@ -200,8 +201,8 @@ parodus_callback(struct lws *wsi, enum lws_callback_reasons reason, } ParodusInfo("Sent %d bytes of data to server successfully \n",n); free(out); - free(message); - message = NULL; + free(message->msg); + message->msg = NULL; } } @@ -224,8 +225,7 @@ parodus_callback(struct lws *wsi, enum lws_callback_reasons reason, ((0 != strlen(get_parodus_cfg()->hw_manufacturer)) ? get_parodus_cfg()->hw_manufacturer : "unknown")); ParodusInfo("User-Agent: %s\n",user_agent); - /*TODO Implement base64 encoding, currently we are using nopoll API to encode data*/ - //conveyHeader = getWebpaConveyHeader(); + conveyHeader = getWebpaConveyHeader(); if (lws_add_http_header_by_name(wsi, (unsigned char *)"X-WebPA-Device-Name:", @@ -240,13 +240,13 @@ parodus_callback(struct lws *wsi, enum lws_callback_reasons reason, (unsigned char *)user_agent,strlen(user_agent),p,end)) return -1; - /* if(strlen(conveyHeader) > 0) + 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 */ @@ -272,7 +272,7 @@ static const struct lws_protocols protocols[] = { LWS_VISIBLE void lwsl_emit_syslog(int level, const char *line) { - ParodusInfo(" %s\n",line); + ParodusInfo(" %s",line); } void createLWSconnection() @@ -280,7 +280,6 @@ void createLWSconnection() struct lws_context_creation_info info; struct lws_client_connect_info i; struct lws_context *context; - const char *prot, *p; int port = 8080,use_ssl =0; memset(&info, 0, sizeof info); @@ -291,7 +290,7 @@ void createLWSconnection() info.protocols = protocols; info.gid = -1; info.uid = -1; - lws_set_log_level(LLL_INFO | LLL_NOTICE | LLL_WARN | LLL_LATENCY | LLL_CLIENT | LLL_COUNT,NULL); + 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; diff --git a/src/connection.h b/src/connection.h index d912021..2c55913 100644 --- a/src/connection.h +++ b/src/connection.h @@ -19,10 +19,7 @@ extern "C" { /* File Scoped Variables */ /*----------------------------------------------------------------------------*/ -extern bool close_retry; extern bool conn_retry; -extern volatile unsigned int heartBeatTimer; -extern pthread_mutex_t close_mut; /*----------------------------------------------------------------------------*/ /* Function Prototypes */ diff --git a/src/downstream.c b/src/downstream.c index cc5b14e..3b4dac7 100644 --- a/src/downstream.c +++ b/src/downstream.c @@ -145,6 +145,7 @@ void listenerOnMessage(void * msg, size_t msgSize) 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); } } diff --git a/src/nopoll_handlers.c b/src/lws_handlers.c similarity index 95% rename from src/nopoll_handlers.c rename to src/lws_handlers.c index 9d33bde..5fa30fc 100644 --- a/src/nopoll_handlers.c +++ b/src/lws_handlers.c @@ -1,13 +1,13 @@ /** - * @file nopoll_handlers.c + * @file lws_handlers.c * - * @description This describes nopoll handler functions. + * @description This describes lws handler functions. * * Copyright (c) 2015 Comcast */ #include "ParodusInternal.h" -#include "nopoll_handlers.h" +#include "lws_handlers.h" #include "connection.h" /*----------------------------------------------------------------------------*/ diff --git a/src/lws_handlers.h b/src/lws_handlers.h new file mode 100644 index 0000000..9301737 --- /dev/null +++ b/src/lws_handlers.h @@ -0,0 +1,41 @@ +/** + * @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; +extern bool close_retry; + +/*----------------------------------------------------------------------------*/ +/* 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 diff --git a/src/mutex.c b/src/mutex.c deleted file mode 100644 index 9cf2882..0000000 --- a/src/mutex.c +++ /dev/null @@ -1,159 +0,0 @@ -/** - * 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 */ diff --git a/src/mutex.h b/src/mutex.h deleted file mode 100644 index ba8f346..0000000 --- a/src/mutex.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - * 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 -#include - -#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 diff --git a/src/nopoll_handlers.h b/src/nopoll_handlers.h deleted file mode 100644 index 4898027..0000000 --- a/src/nopoll_handlers.h +++ /dev/null @@ -1,60 +0,0 @@ -/** - * @file nopoll_handlers.h - * - * @description This header defines nopoll handler functions. - * - * Copyright (c) 2015 Comcast - */ - -#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 listenerOnrequest_queue(void *requestMsg,int reqSize); - -/** - * @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 diff --git a/src/nopoll_helpers.c b/src/nopoll_helpers.c deleted file mode 100644 index 3166431..0000000 --- a/src/nopoll_helpers.c +++ /dev/null @@ -1,112 +0,0 @@ -/** - * @file nopoll_helpers.c - * - * @description This file is used to manage incomming and outgoing messages. - * - * Copyright (c) 2015 Comcast - */ - -#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; -} - diff --git a/src/nopoll_helpers.h b/src/nopoll_helpers.h deleted file mode 100644 index 9fc47ae..0000000 --- a/src/nopoll_helpers.h +++ /dev/null @@ -1,41 +0,0 @@ -/** - * @file nopoll_handlers.h - * - * @description This header defines functions to manage incomming and outgoing messages. - * - * Copyright (c) 2015 Comcast - */ - -#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 diff --git a/src/thread_tasks.c b/src/thread_tasks.c index 64b113a..244de59 100644 --- a/src/thread_tasks.c +++ b/src/thread_tasks.c @@ -37,8 +37,8 @@ void *messageHandlerTask() listenerOnMessage(message->payload, message->len); - //free(message); - //message = NULL; + free(message); + message = NULL; } else { diff --git a/src/upstream.c b/src/upstream.c index 300d1af..7136431 100644 --- a/src/upstream.c +++ b/src/upstream.c @@ -12,7 +12,6 @@ #include "partners_check.h" #include "connection.h" #include "client_list.h" -#include "nopoll_helpers.h" /*----------------------------------------------------------------------------*/ /* Macros */