Fix potential race in route table load
[ric-plt/lib/rmr.git] / src / rmr / common / src / tools_static.c
index b4245cd..a69db35 100644 (file)
@@ -1,8 +1,8 @@
 // :vi sw=4 ts=4 noet:
 /*
 ==================================================================================
 // :vi sw=4 ts=4 noet:
 /*
 ==================================================================================
-       Copyright (c) 2019 Nokia
-       Copyright (c) 2018-2019 AT&T Intellectual Property.
+       Copyright (c) 2019-2020 Nokia
+       Copyright (c) 2018-2020 AT&T Intellectual Property.
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
@@ -29,6 +29,9 @@
 
                                        uta_link2       -- establish a nanomsg connection to a host
 
 
                                        uta_link2       -- establish a nanomsg connection to a host
 
+                                       uta_dump_env -- dump the environment variables to stdout that are
+                                                               of importance to RMR.
+
        Author:         E. Scott Daniels
        Date:           30 November 2018
 */
        Author:         E. Scott Daniels
        Date:           30 November 2018
 */
 #include <netdb.h>
 
 // --- some protos needed for better organisation --------
 #include <netdb.h>
 
 // --- some protos needed for better organisation --------
-int is_this_myip( if_addrs_t* l, char* addr );
+static int is_this_myip( if_addrs_t* l, char* addr );
 
 
 // ----------------------------------------------------------------------------------
 
 
 
 // ----------------------------------------------------------------------------------
 
+
+/*
+       A strncpy() replacement that ensures the resulting dest buffer has
+       a zero (nil) terminator even if the source is longer than the dest
+       length.
+       A max of len-1 bytes are copied from src to dest. The copy stops when
+       a zero (nil) is encountered in the src, or len-1 bytes are copied.
+       The string is always nil terminated.
+       The string length is returned.
+
+       It is the responsiblity of the caller to ensure that dest is at
+       least len bytes in length.
+
+       If either src/dest is invalid (nil) a value of -1 is returned.
+*/
+static inline int zt_buf_fill( char* dest, char const* src, int len ) {
+       char*           dp;
+       char const*     sp;
+       int                     n;              // num moved
+
+       if( dest == NULL && src == NULL ) {
+               return -1;
+       }
+
+       dp = dest;
+       sp = src;
+       n = 0;
+       while(  *sp && n < len-1 ) {
+               *(dp++) = *(sp++);
+               n++;
+       }
+
+       *dp = 0;
+       return n;
+}
+
 /*
        Simple tokeniser. Split a null terminated string into tokens recording the
        pointers in the tokens array provided.  Tokens MUST be large enough. Max is
 /*
        Simple tokeniser. Split a null terminated string into tokens recording the
        pointers in the tokens array provided.  Tokens MUST be large enough. Max is
@@ -88,9 +127,9 @@ static int uta_tokenise( char* buf, char** tokens, int max, char sep ) {
        Given a buffer of 'sep' separated tokens, and a list of things,
        return up to max tokens with any tokens that matched things in
        the list. Toks is the user supplied array of char* which we will
        Given a buffer of 'sep' separated tokens, and a list of things,
        return up to max tokens with any tokens that matched things in
        the list. Toks is the user supplied array of char* which we will
-       fill in (up to max) with pointers to tokens from buf.  This 
-       damages buf, so the caller must dup the string if it must be 
-       preserved for later, original, use.  The pointers returned in 
+       fill in (up to max) with pointers to tokens from buf.  This
+       damages buf, so the caller must dup the string if it must be
+       preserved for later, original, use.  The pointers returned in
        toks will reference portions of bufs.
 
        Returns the number of tokens referenced by toks.
        toks will reference portions of bufs.
 
        Returns the number of tokens referenced by toks.
@@ -102,7 +141,7 @@ static int uta_rmip_tokenise( char* buf, if_addrs_t* iplist, char** toks, int ma
        int i;
        int j;
 
        int i;
        int j;
 
-       
+
        all_toks = malloc( sizeof( char * ) * max );                                    // refernce to all tokens; we'll prune
        pcount = ntoks = uta_tokenise( buf, all_toks, max, sep );               // split them up
        j = 0;
        all_toks = malloc( sizeof( char * ) * max );                                    // refernce to all tokens; we'll prune
        pcount = ntoks = uta_tokenise( buf, all_toks, max, sep );               // split them up
        j = 0;
@@ -172,6 +211,7 @@ static char* uta_h2ip( char const* hname ) {
 }
 
 
 }
 
 
+#ifdef RTG_PUB
 /*
        Looks for the environment variable RMR_RTG_SVC which we assume to be name[:port], and
        does a dns lookup on the name. If the env does not have such a variable, we default to
 /*
        Looks for the environment variable RMR_RTG_SVC which we assume to be name[:port], and
        does a dns lookup on the name. If the env does not have such a variable, we default to
@@ -220,6 +260,7 @@ static int uta_lookup_rtg( uta_ctx_t* ctx ) {
 
        return ctx->rtg_addr != NULL;
 }
 
        return ctx->rtg_addr != NULL;
 }
+#endif
 
 
 /*
 
 
 /*
@@ -284,10 +325,10 @@ static int uta_has_str( char const* buf, char const* str, char sep, int max ) {
        to the list so that we don't pick up entries from the rtable that are for other
        processes listening on different interfaces.
 
        to the list so that we don't pick up entries from the rtable that are for other
        processes listening on different interfaces.
 
-       The ENV_BIN_IF environment variable may be either an IP address (v6 must be in 
+       The ENV_BIN_IF environment variable may be either an IP address (v6 must be in
        square braces), or an interface name (e.g. eth0).
 */
        square braces), or an interface name (e.g. eth0).
 */
-if_addrs_t*  mk_ip_list( char* port ) {
+static if_addrs_t*  mk_ip_list( char* port ) {
        if_addrs_t* l;
        struct  ifaddrs *ifs;           // pointer to head
        struct  ifaddrs *ele;           // pointer into the list
        if_addrs_t* l;
        struct  ifaddrs *ifs;           // pointer to head
        struct  ifaddrs *ele;           // pointer into the list
@@ -337,18 +378,18 @@ if_addrs_t*  mk_ip_list( char* port ) {
                                                fmt = "[%s]:%s";
                                        }
                                }
                                                fmt = "[%s]:%s";
                                        }
                                }
-                       }
 
 
-                       if( *octs ) {
-                               if( (tok = strchr( octs, '%' )) != NULL ) {                     // for unknown reasons some ip6 addrs have %if-name appended; truncate
-                                       *tok = 0;
-                               }
-                               if( l->naddrs < 128 ) {
-                                       if( DEBUG ) rmr_vlog( RMR_VL_DEBUG, "capture address: %s: %s\n", ele->ifa_name, octs );
+                               if( *octs ) {
+                                       if( (tok = strchr( octs, '%' )) != NULL ) {                     // for unknown reasons some ip6 addrs have %if-name appended; truncate
+                                               *tok = 0;
+                                       }
+                                       if( l->naddrs < 128 ) {
+                                               if( DEBUG ) rmr_vlog( RMR_VL_DEBUG, "capture address: %s: %s\n", ele->ifa_name, octs );
 
 
-                                       snprintf( wbuf, sizeof( wbuf ), fmt, octs, port );              // smash port onto the addr
-                                       l->addrs[l->naddrs] = strdup( wbuf );
-                                       l->naddrs++;
+                                               snprintf( wbuf, sizeof( wbuf ), fmt, octs, port );              // smash port onto the addr
+                                               l->addrs[l->naddrs] = strdup( wbuf );
+                                               l->naddrs++;
+                                       }
                                }
                        }
                }
                                }
                        }
                }
@@ -368,7 +409,7 @@ if_addrs_t*  mk_ip_list( char* port ) {
        do a straight search through the list. We don't expect this to
        ever be a higly driven functions so not bothering to optimise.
 */
        do a straight search through the list. We don't expect this to
        ever be a higly driven functions so not bothering to optimise.
 */
-int is_this_myip( if_addrs_t* l, char* addr ) {
+static int is_this_myip( if_addrs_t* l, char* addr ) {
        int i;
 
        if( l == NULL ) {
        int i;
 
        if( l == NULL ) {
@@ -460,4 +501,37 @@ static char* get_default_ip( if_addrs_t* iplist ) {
        return NULL;
 }
 
        return NULL;
 }
 
+/*
+       Write all environment variables that we consider to be important to stderr.
+*/
+static void uta_dump_env( ) {
+       char* token;
+       char* elist[] = {
+                       ENV_BIND_IF,
+                       ENV_RTG_PORT,
+                       ENV_RTG_ADDR,
+                       ENV_SEED_RT,
+                       ENV_SEED_MEMAP,
+                       ENV_RTG_RAW,
+                       ENV_VERBOSE_FILE,
+                       ENV_NAME_ONLY,
+                       ENV_WARNINGS,
+                       ENV_SRC_ID,
+                       ENV_LOG_HR,
+                       ENV_LOG_VLEVEL,
+                       ENV_CTL_PORT,
+                       ENV_RTREQ_FREA
+       };
+       int i;
+
+       for( i = 0; i < sizeof( elist ) / sizeof( char *); i ++ ) {
+               token = getenv( elist[i] );
+               if( token != NULL ) {
+                       rmr_vlog( RMR_VL_INFO, "dump_env: %s = '%s'\n", elist[i], token );
+               } else {
+                       rmr_vlog( RMR_VL_INFO, "dump_env: %s = <unset>\n", elist[i] );
+               }
+       }
+}
+
 #endif
 #endif