Allow RTS calls prior to initial route table load 54/4354/1 4.1.3
authorE. Scott Daniels <daniels@research.att.com>
Wed, 8 Jul 2020 15:28:05 +0000 (11:28 -0400)
committerE. Scott Daniels <daniels@research.att.com>
Wed, 8 Jul 2020 15:28:05 +0000 (11:28 -0400)
To better support heartbeat responses it is necessary to
allow RTS messages to be sent prior to the loading of
the initial route table. This change implements this and
has the side effect of also allowing wormhold sends prior
to a route table arrival (which is ok since no routing
is needed for wormhole traffic).

Issue-ID: RIC-589

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

CHANGES_CORE.txt
CMakeLists.txt
docs/msg_types.rst
docs/rel-notes.rst
src/rmr/common/src/rt_generic_static.c
src/rmr/nng/include/rmr_nng_private.h
src/rmr/nng/src/rmr_nng.c
src/rmr/si/include/rmr_si_private.h
src/rmr/si/src/rmr_si.c

index 8f58711..1acf21c 100644 (file)
@@ -5,6 +5,12 @@
 # API and build change  and fix summaries. Doc correctsions
 # and/or changes are not mentioned here; see the commit messages.
 
+2020 July 9; version 4.1.3
+       Allow RTS messages to be sent before the arrival of the initial
+       route table. Calls to RTS (heart beat responses) prior to the
+       initial route table load could cause a crash if a framework
+       blindly assumes that RTS is valid. (RIC-589)
+
 2020 June 22; version 4.1.2
        Fix typo in RIC Message header file.
 
index 47bc69e..ed345f4 100644 (file)
@@ -41,7 +41,7 @@ cmake_minimum_required( VERSION 3.5 )
 
 set( major_version "4" )               # should be automatically populated from git tag later, but until CI process sets a tag we use this
 set( minor_version "1" )
-set( patch_level "2" )
+set( patch_level "3" )
 
 set( install_root "${CMAKE_INSTALL_PREFIX}" )
 set( install_inc "include/rmr" )
index 9ee41af..f2e6a99 100644 (file)
@@ -18,7 +18,7 @@ type constants are defined in the RIC_msg_types.h header file
 included with the RMR development package while subscription
 IDs are generated by the subscription manager process at
 run-time. This document does not include the constant values
-to avoid incorrectly propigating a stale value through the
+to avoid incorrectly propagating a stale value through the
 reference of an outdated document.
 
 
index 2c12615..43a100b 100644 (file)
@@ -22,6 +22,16 @@ the need to leap frog versions ceased, and beginning with
 version 4.0.0, the RMR versions should no longer skip.
 
 
+2020 July 9; version 4.1.3
+--------------------------
+
+Allow RTS messages to be sent before the arrival of the
+initial route table. Calls to RTS (heart beat responses)
+prior to the initial route table load could cause a crash if
+a framework blindly assumes that RTS is valid. (RIC-589)
+
+
+
 2020 June 22; version 4.1.2
 ---------------------------
 
index 185dbb1..597347a 100644 (file)
@@ -786,6 +786,7 @@ static void parse_rt_rec( uta_ctx_t* ctx,  uta_ctx_t* pctx, char* buf, int vleve
                                                }
 
                                                send_rt_ack( pctx, mbuf, ctx->table_id, RMR_OK, NULL );
+                                               ctx->rtable_ready = 1;                                                  // route based sends can now happen
                                        } else {
                                                if( DEBUG > 1 ) rmr_vlog_force( RMR_VL_DEBUG, "end of route table noticed, but one was not started!\n" );
                                                ctx->new_rtable = NULL;
index 919b225..3c6996e 100644 (file)
@@ -78,6 +78,7 @@ struct uta_ctx {
        int d1_len;                                     // extra header data 1 length
        int d2_len;                                     // extra header data 2 length   (future)
        nng_socket      nn_sock;                // our general listen socket
+       int     rmr_ready;                              // rmr table has been loaded/recived
        route_table_t* rtable;          // the active route table
        route_table_t* old_rtable;      // the previously used rt, sits here to allow for draining
        route_table_t* new_rtable;      // route table under construction
index 8a7c6d0..45b7fc6 100644 (file)
@@ -753,9 +753,12 @@ static void* init(  char* uproto_port, int max_msg_size, int flags ) {
                return NULL;
        }
 
+       ctx->rtable = rt_clone_space( NULL, NULL, 0 );                  // allows wormhole and rts calls to work before rt is received
        if( flags & FL_NOTHREAD ) {                                                             // if no rtc thread, we still need an empty route table for wormholes
-               ctx->rtable = rt_clone_space( NULL, NULL, 0 );          // so create one
+               ctx->rmr_ready = 1;                                                                     // for a nothread instance, rmr is ready to go here
        } else {
+               ctx->rmr_ready = o;                                                                     // ensure not ready until static/dynamic table loaded
+
                if( (tok = getenv( ENV_RTG_RAW )) != NULL  && *tok == '0' ) {                   // use RMR for Rmgr comm only when specifically off
                        if( pthread_create( &ctx->rtc_th,  NULL, rtc, (void *) ctx ) ) {        // kick the rmr based rt collector thread
                                rmr_vlog( RMR_VL_WARN, "rmr_init: unable to start route table collector thread: %s", strerror( errno ) );
@@ -830,11 +833,7 @@ extern int rmr_ready( void* vctx ) {
                return FALSE;
        }
 
-       if( ctx->rtable != NULL ) {
-               return TRUE;
-       }
-
-       return FALSE;
+       return ctx->rmr_ready;
 }
 
 /*
index 6c6f74a..fb4e79f 100644 (file)
@@ -128,6 +128,7 @@ struct uta_ctx {
        int d1_len;                                     // extra header data 1 length
        int d2_len;                                     // extra header data 2 length   (future)
        int     nn_sock;                                // our general listen socket
+       int rtable_ready;                       // set to true when rt is received or loaded
        route_table_t* rtable;          // the active route table
        route_table_t* old_rtable;      // the previously used rt, sits here to allow for draining
        route_table_t* new_rtable;      // route table under construction
index c5041b3..7a2bc96 100644 (file)
@@ -702,9 +702,12 @@ static void* init(  char* uproto_port, int def_msg_size, int flags ) {
                                                                                                // finish all flag setting before threads to keep helgrind quiet
        ctx->flags |= CFL_MTC_ENABLED;                          // for SI threaded receiver is the only way
 
-       if( flags & RMRFL_NOTHREAD ) {                          // thread set to off; no route table collector started (could be called by the rtc thread itself)
-               ctx->rtable = rt_clone_space( NULL, NULL, 0 );          // creates an empty route table so that wormholes still can be used
+       ctx->rtable = rt_clone_space( NULL, NULL, 0 );          // create an empty route table so that wormhole/rts calls can be used
+       if( flags & RMRFL_NOTHREAD ) {                                          // no thread prevents the collector start for very special cases
+               ctx->rtable_ready = 1;                                                  // route based sends will always fail, but rmr is ready for the non thread case
        } else {
+               ctx->rtable_ready = 0;                                                  // no sends until a real route table is loaded in the rtc thread
+
                if( static_rtc ) {
                        rmr_vlog( RMR_VL_INFO, "rmr_init: file based route table only for context on port %s\n", uproto_port );
                        if( pthread_create( &ctx->rtc_th,  NULL, rtc_file, (void *) ctx ) ) {   // kick the rt collector thread as just file reader
@@ -777,11 +780,7 @@ extern int rmr_ready( void* vctx ) {
                return FALSE;
        }
 
-       if( ctx->rtable != NULL ) {
-               return TRUE;
-       }
-
-       return FALSE;
+       return ctx->rtable_ready;
 }
 
 /*