Correct bug in timeout receive 98/1198/1 1.10.1
authorE. Scott Daniels <daniels@research.att.com>
Tue, 22 Oct 2019 20:23:36 +0000 (16:23 -0400)
committerE. Scott Daniels <daniels@research.att.com>
Tue, 22 Oct 2019 20:23:36 +0000 (16:23 -0400)
It was possible for the timeout receive function to return a
nil message buffer pointer, even if the calling function passed
a pointer in for reuse.  The exposure was limited only to when
the epoll environment could not be initialised which we believe
has never been observed.

Signed-off-by: E. Scott Daniels <daniels@research.att.com>
Change-Id: I259a5e5a0a18e53ffb03cc4c47d171e77e998835

CHANGES
CMakeLists.txt
doc/src/man/rmr_torcv_msg.3.xfm
src/rmr/nng/include/rmr_nng_private.h
src/rmr/nng/src/mt_call_nng_static.c
src/rmr/nng/src/rmr_nng.c

diff --git a/CHANGES b/CHANGES
index 6271785..aead0f9 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,7 +1,14 @@
-pic2
-API and build change  and fixe summaries. Doc correctsions
+
+API and build change  and fix summaries. Doc correctsions
 and/or changes are not mentioned here; see the commit messages.
 
+2019 October 21; version 1.10.1
+       Fix to prevent null message buffer from being returned by the timeout
+       receive function if the function is passed one to reuse.
+
+2019 October 21; version 1.10.1
+       Add periodic dump of send count info to stderr.
+
 2019 September 27; version 1.9.0
        Python bindings added receive all queued function and corrected a unit test
 
index 8bccdd4..f38565e 100644 (file)
@@ -36,7 +36,7 @@ cmake_minimum_required( VERSION 3.5 )
 
 set( major_version "1" )               # should be automatically populated from git tag later, but until CI process sets a tag we use this
 set( minor_version "10" )
-set( patch_level "0" )
+set( patch_level "1" )
 
 set( install_root "${CMAKE_INSTALL_PREFIX}" )
 set( install_inc "include/rmr" )
index b38b9ad..ffe26dc 100644 (file)
@@ -72,6 +72,12 @@ The &ital(state) field in the message buffer will be one of the following:
 &beg_dlist(.75i : ^&bold_font )
 &di(RMR_OK) The message buffer (payload) references the received data.
 
+&space
+&di(RMR_ERR_INITFAILED) The first call to this function must initialise an underlying
+       system notification mechanism. On failure, this error is returned and errno
+       will have the system error status set.  If this function fails to intialise,
+       the poll mechansim, it is likely that message receives will never be successful.
+
 &space
 &di(RMR_ERR_TIMEOUT) The timeout expired before a complete message was received.
        All other fields in the message buffer are not valid.
index efb2daa..9753931 100644 (file)
@@ -51,7 +51,7 @@ struct endpoint {
        Epoll information needed for the rmr_torcv_msg() funciton
 */
 typedef struct epoll_stuff {
-       struct epoll_event events[1];                           // wait on 10 possible events
+       struct epoll_event events[1];                           // wait on 1 possible events
        struct epoll_event epe;                                         // event definition for event to listen to
        int ep_fd;                                                                      // file des from nng
        int nng_fd;                                                                     // fd from nng
index 71106f1..7820561 100644 (file)
@@ -64,7 +64,8 @@ static inline void queue_normal( uta_ctx_t* ctx, rmr_mbuf_t* mbuf ) {
                The transaction ID in the message matches the expected ID in the chute,
                then the message is given to the chute and the chute's semaphore is tickled.
 
-               If none are true, the message is dropped.
+               If none are true, the message is queued on the normal receive queue and that
+               related semaphore is tickeled.
 */
 static void* mt_receive( void* vctx ) {
        uta_ctx_t*              ctx;
@@ -84,7 +85,7 @@ static void* mt_receive( void* vctx ) {
        while( ! ctx->shutdown ) {
                mbuf = rcv_msg( ctx, NULL );
 
-               if( mbuf != NULL && (hdr = (uta_mhdr_t *) mbuf->header) != NULL ) {
+               if( mbuf != NULL && (hdr = (uta_mhdr_t *) mbuf->header) != NULL && mbuf->payload != NULL ) {
                        if( hdr->flags & HFL_CALL_MSG ) {                                       // call generated message; ignore call-id etc and queue
                                queue_normal( ctx, mbuf );
                        } else {
index 45a0e23..d9c4c06 100644 (file)
@@ -454,7 +454,12 @@ extern rmr_mbuf_t* rmr_torcv_msg( void* vctx, rmr_mbuf_t* old_msg, int ms_to ) {
                if( (eps->ep_fd = epoll_create1( 0 )) < 0 ) {
                fprintf( stderr, "[FAIL] unable to create epoll fd: %d\n", errno );
                        free( eps );
-                       return NULL;
+                       ctx->eps = NULL;
+                       if( old_msg != NULL ) {
+                               old_msg->state = RMR_ERR_INITFAILED;
+                               old_msg->tp_state = errno;
+                       }
+                       return old_msg;
                }
 
                eps->nng_fd = rmr_get_rcvfd( ctx );
@@ -464,7 +469,12 @@ extern rmr_mbuf_t* rmr_torcv_msg( void* vctx, rmr_mbuf_t* old_msg, int ms_to ) {
                if( epoll_ctl( eps->ep_fd, EPOLL_CTL_ADD, eps->nng_fd, &eps->epe ) != 0 )  {
                fprintf( stderr, "[FAIL] epoll_ctl status not 0 : %s\n", strerror( errno ) );
                        free( eps );
-                       return NULL;
+                       ctx->eps = NULL;
+                       if( old_msg != NULL ) {
+                               old_msg->state = RMR_ERR_INITFAILED;
+                               old_msg->tp_state = errno;
+                       }
+                       return old_msg;
                }
 
                ctx->eps = eps;