From cf4413c47ce274d7fc08c3bcfc8c4de3d465ad4d Mon Sep 17 00:00:00 2001 From: "E. Scott Daniels" Date: Wed, 8 Jul 2020 11:28:05 -0400 Subject: [PATCH] Allow RTS calls prior to initial route table load 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 Change-Id: I302bdd0f274a7c5bc95f3f382e3374b21662ab8c --- CHANGES_CORE.txt | 6 ++++++ CMakeLists.txt | 2 +- docs/msg_types.rst | 2 +- docs/rel-notes.rst | 10 ++++++++++ src/rmr/common/src/rt_generic_static.c | 1 + src/rmr/nng/include/rmr_nng_private.h | 1 + src/rmr/nng/src/rmr_nng.c | 11 +++++------ src/rmr/si/include/rmr_si_private.h | 1 + src/rmr/si/src/rmr_si.c | 13 ++++++------- 9 files changed, 32 insertions(+), 15 deletions(-) diff --git a/CHANGES_CORE.txt b/CHANGES_CORE.txt index 8f58711..1acf21c 100644 --- a/CHANGES_CORE.txt +++ b/CHANGES_CORE.txt @@ -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. diff --git a/CMakeLists.txt b/CMakeLists.txt index 47bc69e..ed345f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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" ) diff --git a/docs/msg_types.rst b/docs/msg_types.rst index 9ee41af..f2e6a99 100644 --- a/docs/msg_types.rst +++ b/docs/msg_types.rst @@ -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. diff --git a/docs/rel-notes.rst b/docs/rel-notes.rst index 2c12615..43a100b 100644 --- a/docs/rel-notes.rst +++ b/docs/rel-notes.rst @@ -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 --------------------------- diff --git a/src/rmr/common/src/rt_generic_static.c b/src/rmr/common/src/rt_generic_static.c index 185dbb1..597347a 100644 --- a/src/rmr/common/src/rt_generic_static.c +++ b/src/rmr/common/src/rt_generic_static.c @@ -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; diff --git a/src/rmr/nng/include/rmr_nng_private.h b/src/rmr/nng/include/rmr_nng_private.h index 919b225..3c6996e 100644 --- a/src/rmr/nng/include/rmr_nng_private.h +++ b/src/rmr/nng/include/rmr_nng_private.h @@ -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 diff --git a/src/rmr/nng/src/rmr_nng.c b/src/rmr/nng/src/rmr_nng.c index 8a7c6d0..45b7fc6 100644 --- a/src/rmr/nng/src/rmr_nng.c +++ b/src/rmr/nng/src/rmr_nng.c @@ -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; } /* diff --git a/src/rmr/si/include/rmr_si_private.h b/src/rmr/si/include/rmr_si_private.h index 6c6f74a..fb4e79f 100644 --- a/src/rmr/si/include/rmr_si_private.h +++ b/src/rmr/si/include/rmr_si_private.h @@ -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 diff --git a/src/rmr/si/src/rmr_si.c b/src/rmr/si/src/rmr_si.c index c5041b3..7a2bc96 100644 --- a/src/rmr/si/src/rmr_si.c +++ b/src/rmr/si/src/rmr_si.c @@ -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; } /* -- 2.16.6