From fe22c4bdb9c72e8fc107f6f16d074df62ccda5f6 Mon Sep 17 00:00:00 2001 From: Alexandre Huff Date: Tue, 17 Nov 2020 11:11:21 -0300 Subject: [PATCH] Fixed bug on building RTE groups with no endpoint When building a route table entry (rte) with several groups, a given group can be added contiguously to the rte even if it has no endpoint. Endpoints that reference to any of "our" local "address:port" are not added to the rte. Thus, in some cases, groups that only reference to local endpoints (nil) are added contiguously to the rte, causing the round-robin group selection mechanism to stop sending messages to the next groups after finding a nil-one. This might happen, for instance, when a multicast routing rule is required in which only one endpoint is added to each group, and one of these groups references to one of the local "address:port" being used. In this case, only the endpoints in the groups prior the nil-one will receive a copy of the multicast message. This change fixes this issue by adding contiguously only groups that have at least one endpoint that does not refer to a local "address:port". Some extra bytes are wasted in the rte by referencing to a group that does not have an endpoint, but this is minor compared to spending time on recreating a new rte and adding only the groups that do have endpoints. Those nil groups don't cause any harm since the function that does the round-robin selection assumes that the groups are contiguous and stops selecting endpoints when a nil group is found. Issue-ID: RIC-695 Signed-off-by: Alexandre Huff Change-Id: I13c7576ce0de82b7814c81c1a0da24172371a897 --- src/rmr/common/src/rt_generic_static.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/rmr/common/src/rt_generic_static.c b/src/rmr/common/src/rt_generic_static.c index 116b17f..1d8d9ca 100644 --- a/src/rmr/common/src/rt_generic_static.c +++ b/src/rmr/common/src/rt_generic_static.c @@ -488,6 +488,8 @@ static void build_entry( uta_ctx_t* ctx, char* ts_field, uint32_t subid, char* r int i; int ngtoks; // number of tokens in the group list int grp; // index into group list + int cgidx; // contiguous group index (prevents the addition of a contiguous group without ep) + int has_ep = FALSE; // indicates if an endpoint was added in a given round robin group ts_field = clip( ts_field ); // ditch extra whitespace and trailing comments rr_field = clip( rr_field ); @@ -507,14 +509,19 @@ static void build_entry( uta_ctx_t* ctx, char* ts_field, uint32_t subid, char* r rte = uta_add_rte( ctx->new_rtable, key, ngtoks ); // get/create entry for this key rte->mtype = atoi( ts_field ); // capture mtype for debugging - for( grp = 0; grp < ngtoks; grp++ ) { - if( (ntoks = uta_rmip_tokenise( gtokens[grp], ctx->ip_list, tokens, 64, ',' )) > 0 ) { // remove any referneces to our ip addrs + for( grp = 0, cgidx = 0; grp < ngtoks; grp++ ) { + if( (ntoks = uta_rmip_tokenise( gtokens[grp], ctx->ip_list, tokens, 64, ',' )) > 0 ) { // remove any references to our ip addrs for( i = 0; i < ntoks; i++ ) { if( strcmp( tokens[i], ctx->my_name ) != 0 ) { // don't add if it is us -- cannot send to ourself if( DEBUG > 1 || (vlevel > 1)) rmr_vlog_force( RMR_VL_DEBUG, "add endpoint ts=%s %s\n", ts_field, tokens[i] ); - uta_add_ep( ctx->new_rtable, rte, tokens[i], grp ); + uta_add_ep( ctx->new_rtable, rte, tokens[i], cgidx ); + has_ep = TRUE; } } + if( has_ep ) { + cgidx++; // only increment to the next contiguous group if the current one has at least one endpoint + has_ep = FALSE; + } } } } -- 2.16.6