Fix sonar flagged bugs 21/3521/3 4.0.3
authorE. Scott Daniels <daniels@research.att.com>
Tue, 28 Apr 2020 20:20:53 +0000 (16:20 -0400)
committerE. Scott Daniels <daniels@research.att.com>
Wed, 29 Apr 2020 11:59:09 +0000 (07:59 -0400)
1 bug and 9 security (buffer overrun potentials) were
corrected.

Issue-ID: RIC-78

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

CHANGES_CORE.txt
CMakeLists.txt
docs/overview.rst [changed mode: 0755->0644]
docs/rel-notes.rst
src/rmr/common/src/mbuf_api.c
src/rmr/common/src/wrapper.c
src/rmr/nng/src/sr_nng_static.c
src/rmr/si/src/si95/siaddress.c
src/rmr/si/src/si95/sigetadd.c
src/rmr/si/src/si95/sircv.c
src/rmr/si/src/sr_si_static.c

index 6299123..3d943cc 100644 (file)
@@ -5,6 +5,9 @@
 # API and build change  and fix summaries. Doc correctsions
 # and/or changes are not mentioned here; see the commit messages.
 
+2020 April 28; version 4.0.3
+       Fix sonar flagged bugs (RIC-78)
+
 2020 April 24; version 4.0.2
        Correct bug in SI95 transport header length validation (RIC-341)
 
index c7c4c95..a858a8e 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 "0" )
-set( patch_level "2" )
+set( patch_level "3" )
 
 set( install_root "${CMAKE_INSTALL_PREFIX}" )
 set( install_inc "include/rmr" )
old mode 100755 (executable)
new mode 100644 (file)
index 4997001..f4454be
@@ -47,11 +47,43 @@ The Route Table
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
  
 The library must be given a route table which maps message 
-numbers to endpoint groups such that each time a message of 
-type T is sent, the message is delivered to one member of 
-each group associated with T. For example, message type 2 
-might route to two different groups where group A consists of 
-worker1 and worker2, while group B consists only of logger1. 
+types (integers) to endpoint groups such that each time a 
+message of type T is sent, the message is delivered to one 
+member of each group associated with T. For example, message 
+type 2 might route to two different groups where group A has 
+two members, worker1 and worker2, while group B has only one 
+member, logger1. 
+The route table consists of a start record, one or more table 
+entry records, and an end record. All table records contain 
+fields separated with vertical bars (|), and allow for 
+trailing comments with the standard shell comment symbol 
+(hash, #) provided that the start of the comment is separated 
+from the last token on the record by one or more spaces. 
+Leading and trailing white space in each field is ignored. 
+The route table supports two entry types: *rte* and *mse*. 
+A *rte* entry defines a message type, an optional sender 
+application, and the endpoint(s) which accept the indicated 
+message type. However, this format is deprecated and may be 
+removed in a future version. An example record appears next. 
+:: 
+  
+     rte | 1 | app10:4560
+The second type of entry is *mse*. This entry defines a 
+message type, an optional sender application, a subscription 
+ID, and a collection of endpoints. An example record appears 
+next. 
+:: 
+  
+     mse | 1000,forwarder:43086 | 10 | app2:43086
  
 It is the responsibility of the route table generator to know 
 which endpoints belong to which groups, and which groups 
@@ -119,13 +151,14 @@ might look:
 Route Table Syntax 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
  
-The following illustrates the syntax for both the route 
-table. 
+The following illustrates the syntax for both types of route 
+table entries
  
  
 :: 
   
  newrt | start
+ rte | <message-type>[,<sender-endpoint>] | <round-robin-grp>[;<round-robin-grp>]...
  mse | <message-type>[,<sender-endpoint>] | <sub-id> | <round-robin-grp>[;<round-robin-grp>]...
  newrt | end
  
@@ -134,10 +167,10 @@ table.
 A round robin group is one or more endpoints from which one 
 will be selected to receive the message. When multiple 
 endpoints are given in a group, they must be separated with a 
-comma. An endpoint is the IP address and port (e.g. 
-192.158.4.30:8219) or DNS name and port of the application 
+comma. An endpoint is an IP address and port (e.g. 
+192.158.4.30:8219), or DNS name and port, of the application 
 that should receive the message type. If multiple round-robin 
-groups are given, they must be separated by a semicolon, and 
+groups are given, they must be separated by a semicolon. 
  
 MEID Map Syntax 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
index e8d60e4..7bffa86 100644 (file)
@@ -30,6 +30,49 @@ Core RMR Changes
 -------------------------------------------------------------------------------------------- 
  
  
+2020 April 28; version 4.0.3 
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
+Fix sonar flagged bugs (RIC-78) 
+2020 April 24; version 4.0.2 
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
+Correct bug in SI95 transport header length validation 
+(RIC-341) 
+2020 April 22; version 4.0.1 
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
+Correct message type constant for Traffic Steering 
+predication (RIC-342) 
+2020 April 21; version 4.0.0 
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
+The NNG based libraries are no longer included in the RMR 
+packages. This is considered a breaking change as NNG will 
+not be supported by default. It is still possible to build 
+with RMR-NNG libraries, but that is the exception. The API 
+between 3.8.2 and 4.0.0 is the SAME. Upgrading to 4.0.0 only 
+means that the underlying transport mechanism is limited only 
+to SI95. 
+The rmr_rcv_specific() function has been deprecated as it was 
+necessary only for NNG and Nanomsg support. Its use should be 
+discontinued. 
+2020 April 20; version 3.8.2 
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
+Fix bug which was preventing an instance receiving dynamic 
+route table updates. (RIC-336) 
 2020 April 20; version 3.8.1 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
  
index 84996ee..029dd74 100644 (file)
@@ -23,7 +23,7 @@
        Abstract:       These are common functions which work only on the mbuf and
                                thus (because they do not touch an endpoint or context)
                                can be agnostic to the underlying transport, or the transport
-                               layer provides a transport specific function (e.g. payload 
+                               layer provides a transport specific function (e.g. payload
                                reallocation).
 
        Author:         E. Scott Daniels
@@ -72,7 +72,7 @@ extern int rmr_bytes2meid( rmr_mbuf_t* mbuf, unsigned char const* src, int len )
        if( len > RMR_MAX_MEID ) {
                len = RMR_MAX_MEID;
                errno = EOVERFLOW;
-       } 
+       }
 
        hdr = (uta_mhdr_t *) mbuf->header;
        memcpy( hdr->meid, src, len );
@@ -429,7 +429,7 @@ extern unsigned char* rmr_get_src( rmr_mbuf_t* msg, unsigned char* dest ) {
 
        if( dest != NULL ) {
                hdr = msg->header;
-               strcpy( dest, hdr->src );
+               strncpy( dest, hdr->src, RMR_MAX_SRC );
        }
 
        return dest;
@@ -453,11 +453,11 @@ extern unsigned char* rmr_get_srcip( rmr_mbuf_t* msg, unsigned char* dest ) {
                hdr = msg->header;
                if( HDR_VERSION( msg->header ) > 2 ) {          // src ip was not present in hdr until ver 3
                        errno = 0;
-                       strcpy( dest, hdr->srcip );
+                       strncpy( dest, hdr->srcip, RMR_MAX_SRC );
                        rstr = dest;
                } else  {
                        errno = 0;
-                       strcpy( dest, hdr->src );                               // reutrn the name:port for old messages
+                       strncpy( dest, hdr->src, RMR_MAX_SRC );                         // reutrn the name:port for old messages
                        rstr = dest;
                }
        }
index 55cfe9e..9d3dd72 100644 (file)
@@ -32,7 +32,7 @@
 
 #include "../include/rmr.h"
 
-#define ADD_SEP        1
+#define ADD_SEP                1
 #define        NO_SEP          0
 
 /*
@@ -74,7 +74,7 @@ static int bang_on( char* target, char* src, int max ) {
        if( src && target ) {
                len = strlen( src );
                if( (rc = len <= max ? len : 0 ) > 0 ) {        // if it fits, add it.
-                       strcat( target, src );
+                       strncat( target, src, len );
                }
        }
 
@@ -155,6 +155,6 @@ extern char* rmr_get_consts( ) {
        phrase = build_ival( "RMR_ERR_INITFAILED", RMR_ERR_INITFAILED, NO_SEP );
        remain -= bang_on( wbuf, phrase, remain );
 
-       strcat( wbuf, " }" );
+       strncat( wbuf, " }", remain );
        return strdup( wbuf );                  // chop unused space and return
 }
index bb45ac6..83d07ba 100644 (file)
@@ -290,7 +290,8 @@ static inline rmr_mbuf_t* clone_msg( rmr_mbuf_t* old_msg  ) {
        v1hdr = (uta_v1mhdr_t *) old_msg->header;               // v1 will work to dig header out of any version
        switch( ntohl( v1hdr->rmr_ver ) ) {
                case 1:
-                       memcpy( v1hdr, old_msg->header, sizeof( *v1hdr ) );             // copy complete header
+                       hdr = nm->header;
+                       memcpy( hdr, old_msg->header, sizeof( *v1hdr ) );               // copy complete header
                        nm->payload = (void *) v1hdr + sizeof( *v1hdr );
                        break;
 
index e77ab4f..7cec5dd 100644 (file)
 *  Mnemonic: SIaddress
 *  Abstract: This routine will convert a sockaddr_in structure to a
 *            dotted decimal address, or visa versa.
-*            If type == AC_TOADDR the src string may be: 
+*            If type == AC_TOADDR the src string may be:
 *            xxx.xxx.xxx.xxx.portnumber or host-name.portnumber
 *            xxx.xxx.xxx.xxx.service[.protocol] or hostname;service[;protocol]
 *            if protocol is not supplied then tcp is assumed.
 *            hostname may be something like godzilla.moviemania.com
 *  Parms:    src - Pointer to source buffer
-*            dest- Pointer to dest buffer pointer 
-*            type- Type of conversion AC_TODOT converts sockaddr to human readable. AC_TOADDR 
+*            dest- Pointer to dest buffer pointer
+*            type- Type of conversion AC_TODOT converts sockaddr to human readable. AC_TOADDR
 *                              converts character buffer to sockaddr.
 *  Returns:  Nothing.
 *  Date:     19 January 1995
 *  Modified: 22 Mar 1995 - To add support for ipx addresses.
 *                      18 Oct 2020 - drop old port separator (;)
 *
-*  CAUTION: The netdb.h header file is a bit off when it sets up the 
-*           hostent structure. It claims that h_addr_list is a pointer 
-*           to character pointers, but it is really a pointer to a list 
+*  CAUTION: The netdb.h header file is a bit off when it sets up the
+*           hostent structure. It claims that h_addr_list is a pointer
+*           to character pointers, but it is really a pointer to a list
 *           of pointers to integers!!!
-*       
+*  
 ***************************************************************************
 */
-#include "sisetup.h"      //  get necessary defs and other stuff 
+#include "sisetup.h"      //  get necessary defs and other stuff
 #include <netdb.h>
 #include <stdio.h>
 #include <ctype.h>
 
-/* 
+/*
        target: buffer with address  e.g.  192.168.0.1:4444  :4444 (listen) [::1]4444
-       family: PF_INET[6]  (let it be 0 to select based on addr in buffer 
+       family: PF_INET[6]  (let it be 0 to select based on addr in buffer
        proto: IPPROTO_TCP IPPROTO_UDP
        type:   SOCK_STREAM SOCK_DGRAM
 
        returns length of struct pointed to by rap (return addr blockpointer)
 */
 extern int SIgenaddr( char *target, int proto, int family, int socktype, struct sockaddr **rap ) {
-       struct addrinfo hint;                           //  hints to give getaddrinfo 
-       struct addrinfo *list = NULL;           //  list of what comes back 
-       int     ga_flags = 0;                                   //  flags to pass to getaddrinfo in hints 
+       struct addrinfo hint;                           //  hints to give getaddrinfo
+       struct addrinfo *list = NULL;           //  list of what comes back
+       int     ga_flags = 0;                                   //  flags to pass to getaddrinfo in hints
        int     error = 0;
-       int     rlen = 0;                                               //  length of the addr that rap points to on return 
-       char    *pstr;                                          //  port string 
-       char    *dstr;                                          //  a copy of the users target that we can destroy 
+       int     rlen = 0;                                               //  length of the addr that rap points to on return
+       char    *pstr;                                          //  port string
+       char    *dstr;                                          //  a copy of the users target that we can destroy
        char*   fptr;                                           // ptr we allocated and need to free (we may adjust dstr)
 
-    fptr = dstr = strdup( (char *) target );   //  copy so we can destroy it with strtok 
-       *rap = NULL;                                            //  ensure null incase something breaks 
+    fptr = dstr = strdup( (char *) target );   //  copy so we can destroy it with strtok
+       *rap = NULL;                                            //  ensure null incase something breaks
 
        while( isspace( *dstr ) ) {
                dstr++;
        }
 
-       if( *dstr == ':' ) {            //  user passed in :port -- so we assume this is for bind 
+       if( *dstr == ':' ) {            //  user passed in :port -- so we assume this is for bind
                pstr = dstr;
                *(pstr++) = 0;
 
@@ -107,25 +107,25 @@ extern int SIgenaddr( char *target, int proto, int family, int socktype, struct
        }
 
        memset( &hint, 0, sizeof( hint  ) );
-       hint.ai_family = family;                        //  AF_INET AF_INET6...  let this be 0 to select best based on addr 
-       hint.ai_socktype = socktype;            //  SOCK_DGRAM SOCK_STREAM 
-       hint.ai_protocol = proto;                       //  IPPROTO_TCP IPPROTO_UDP 
+       hint.ai_family = family;                        //  AF_INET AF_INET6...  let this be 0 to select best based on addr
+       hint.ai_socktype = socktype;            //  SOCK_DGRAM SOCK_STREAM
+       hint.ai_protocol = proto;                       //  IPPROTO_TCP IPPROTO_UDP
        hint.ai_flags = ga_flags;
 
-       if( DEBUG ) 
+       if( DEBUG )
                rmr_vlog( RMR_VL_DEBUG, "siaddress: calling getaddrinfo flags=%x sockty=%d proto=%d family=%d target=%s host=%s port=%s\n",
                                ga_flags, socktype, proto, family, target, dstr, pstr );
 
        if( (error = getaddrinfo( dstr, pstr, &hint, &list )) ) {
-               fprintf( stderr, "sigenaddr: error from getaddrinfo: target=%s host=%s port=%s(port): error=(%d) %s\n", 
+               fprintf( stderr, "sigenaddr: error from getaddrinfo: target=%s host=%s port=%s(port): error=(%d) %s\n",
                        target, dstr, pstr, error, gai_strerror( error ) );
        } else {
-               *rap = (struct sockaddr *) malloc(  list->ai_addrlen );         //  alloc a buffer and give address to caller 
+               *rap = (struct sockaddr *) malloc(  list->ai_addrlen );         //  alloc a buffer and give address to caller
                memcpy( *rap, list->ai_addr, list->ai_addrlen  );
 
                rlen = list->ai_addrlen;
-               
-               freeaddrinfo( list );           //  ditch system allocated memory 
+
+               freeaddrinfo( list );           //  ditch system allocated memory
        }
 
        free( fptr );
@@ -133,46 +133,45 @@ extern int SIgenaddr( char *target, int proto, int family, int socktype, struct
 }
 
 
-/* 
+/*
        Given a source address convert from one form to another based on type constant.
        Type const == AC_TODOT   Convert source address structure to human readable string.
        Type const == AC_TOADDR6 Convert source string (host:port or ipv6 address [n:n...:n]:port) to an address struct
        Type const == AC_TOADDR  Convert source string (host:port or ipv4 dotted decimal address) to an address struct
 */
 extern int SIaddress( void *src, void **dest, int type ) {
-       struct sockaddr_in *addr;       //  pointer to the address 
+       struct sockaddr_in *addr;       //  pointer to the address
        struct sockaddr_in6 *addr6;             // ip6 has a different layout
-       unsigned char *num;             //  pointer at the address number 
+       unsigned char *num;             //  pointer at the address number
        uint8_t*        byte;                           //  pointer at the ipv6 address byte values
-       char wbuf[256];                 //  work buffer 
-       int i;         
+       char wbuf[256];                 //  work buffer
+       int i;
        int     rlen = 0;                                       //  return len - len of address struct or string
 
        switch( type ) {
                case AC_TODOT:                                  //  convert from a struct to human readable "dotted decimal"
-                       addr = (struct sockaddr_in *) src;
+                       addr = (struct sockaddr_in *) src;
 
                        if( addr->sin_family == AF_INET6 ) {
                                addr6 = (struct sockaddr_in6 *) src;                            // really an ip6 struct
                                byte = (uint8_t *) &addr6->sin6_addr;
-                       sprintf( wbuf, "[%u:%u:%u:%u:%u:%u]:%d", 
-                                               *(byte+0), *(byte+1), *(byte+2), 
-                                               *(byte+3), *(byte+4), *(byte+5) , 
+                       snprintf( wbuf, sizeof( wbuf ),  "[%u:%u:%u:%u:%u:%u]:%d",
+                                               *(byte+0), *(byte+1), *(byte+2),
+                                               *(byte+3), *(byte+4), *(byte+5) ,
                                                (int) ntohs( addr6->sin6_port ) );
                        } else {
-                               num = (char *) &addr->sin_addr.s_addr;    //  point at the long 
-                               sprintf( wbuf, "%u.%u.%u.%u;%d", *(num+0), *(num+1), *(num+2), *(num+3), (int) ntohs(addr->sin_port) );
+                               num = (char *) &addr->sin_addr.s_addr;    //  point at the long
+                               snprintf( wbuf, sizeof( wbuf ),  "%u.%u.%u.%u;%d", *(num+0), *(num+1), *(num+2), *(num+3), (int) ntohs(addr->sin_port) );
                        }
 
                        *dest = (void *) strdup( wbuf );
                        rlen = strlen( *dest );
                        break;
 
-               case AC_TOADDR6:                        //  from hostname:port string to address for send etc 
+               case AC_TOADDR6:                        //  from hostname:port string to address for send etc
                        return SIgenaddr( src, IPPROTO_TCP, AF_INET6, SOCK_STREAM, (struct sockaddr **) dest );
 
-               case AC_TOADDR:                         //  from dotted decimal to address struct ip4 
-                       //return SIgenaddr( src, AF_INET, IPPROTO_TCP, SOCK_STREAM, (struct sockaddr **) dest );
+               case AC_TOADDR:                         //  from dotted decimal to address struct ip4
                        return SIgenaddr( src, IPPROTO_TCP, AF_INET, SOCK_STREAM, (struct sockaddr **) dest );
        }
 
index 5cf3795..06e6e31 100644 (file)
@@ -24,7 +24,8 @@
 *  Mnemonic: SIgetaddr
 *  Abstract: This routine will get the address of the first listening
 *            block on the tp list and return it in ASCII format to the
-*            caller.
+*            caller. The dest buffer is assumed to be at least 256 bytes
+*                       long.
 *  Parms:    gptr - Pointer to the global information block
 *            buf  - Pointer to the buffer to hold the ascii string
 *  Returns:  NI_OK if block found, NI_ERROR if no listen block exists
 *
 ******************************************************************************
 */
-#include "sisetup.h"        //  get the standard include stuff 
+#include "sisetup.h"        //  get the standard include stuff
 
 extern int SIgetaddr( struct ginfo_blk *gptr, char *buf ) {
-       struct tp_blk *tpptr;       //  Pointer into tp list 
-       int status = SI_ERROR;       //  return status 
-       char    *ibuf;          //  SIaddr now points us at a string, rather than filling ours 
+       struct tp_blk *tpptr;       //  Pointer into tp list
+       int status = SI_ERROR;       //  return status
+       char    *ibuf;          //  SIaddr now points us at a string, rather than filling ours
 
-       for( tpptr = gptr->tplist; tpptr != NULL && !(tpptr->flags & TPF_LISTENFD);
-               tpptr = tpptr->next );
+       for( tpptr = gptr->tplist; tpptr != NULL && !(tpptr->flags & TPF_LISTENFD);
+               tpptr = tpptr->next );
 
-       if( tpptr != NULL )
-       {
-               SIaddress( tpptr->addr, (void *) &ibuf, AC_TODOT );   //  convert to dot fmt 
-               strcpy( buf, ibuf );                            //  copy into caller's buffer 
+       if( tpptr != NULL )
+       {
+               SIaddress( tpptr->addr, (void *) &ibuf, AC_TODOT );   //  convert to dot fmt
+               strncpy( buf, ibuf, 256 );                              //  copy into caller's buffer
                free( ibuf );
-               status = SI_OK;                               //  ok status for return 
-       }
+               status = SI_OK;                               //  ok status for return
+       }
 
-       return status;
-}          
+       return status;
+}
index d69cb61..5309dc5 100644 (file)
@@ -1,4 +1,4 @@
-// vim: noet sw=4 ts=4:
+                               // vim: noet sw=4 ts=4:
 /*
 ==================================================================================
     Copyright (c) 2020 Nokia
@@ -30,6 +30,7 @@
 *            sid  - The session id that the user wants to check
 *            buf  - Pointer to buffer to receive data in
 *            abuf - Pointer to buffer to return address of UDP sender in (!null)
+*                   must be a minimum of 64 bytes long.
 *            buflen-Length of the receive buffer
 *            delay- Value to pass to poll (time out) -1 == block until data
 *  Returns:  SI_ERROR - (SIerrno will contain reason) if failure, else the
 *
 ******************************************************************************
 */
-#include "sisetup.h"    //  get start up stuff 
+#include "sisetup.h"                                   //  get start up stuff
 #include "sitransport.h"
 
 extern int SIrcv( struct ginfo_blk *gptr, int sid, char *buf, int buflen, char *abuf, int delay ) {
- //extern int sigflags;           //  signal flags 
- int status = SI_ERROR;         //  assume the worst to return to caller 
- struct tp_blk *tpptr;          //  pointer to transport provider info 
- int flags = 0;                 //  receive flags 
- int remainder;                 //  # of bytes remaining after rcv if more 
- fd_set readfds;                //  special set of read fds for this call 
- fd_set execpfds;               //  special set of read fds for this call 
- struct timeval *tptr = NULL;   //  time info for select call 
- struct timeval time;
- struct sockaddr *uaddr;       //  pointer to udp address 
-       char    *acbuf;         //  pointer to converted address 
- int addrlen;
+       int status = SI_ERROR;                          //  assume the worst to return to caller
+       struct tp_blk *tpptr;                           //  pointer to transport provider info
+       int flags = 0;                                          //  receive flags
+       int remainder;                                          //  # of bytes remaining after rcv if more
+       fd_set readfds;                                         //  special set of read fds for this call
+       fd_set execpfds;                                        //  special set of read fds for this call
+       struct timeval *tptr = NULL;            //  time info for select call
+       struct timeval time;
+       struct sockaddr *uaddr;                         //  pointer to udp address
+       char    *acbuf;                                         //  pointer to converted address
+       int addrlen;
 
- if( gptr->magicnum != MAGICNUM )     //  if not a valid ginfo block 
-  return SI_ERROR;
+       if( gptr->magicnum != MAGICNUM ) {      //  if not a valid ginfo block
+               return SI_ERROR;
+       }
 
- for( tpptr = gptr->tplist; tpptr != NULL && tpptr->fd != sid;
-      tpptr = tpptr->next );      //  find transport block 
- if( tpptr == NULL )
-  return SI_ERROR;                      //  signal bad block 
+       for( tpptr = gptr->tplist; tpptr != NULL && tpptr->fd != sid; tpptr = tpptr->next ) {   //  find transport block
+               // no body
+       }
 
- uaddr = (struct sockaddr *) malloc( sizeof( struct sockaddr ) );
- addrlen = sizeof( *uaddr );
+       if( tpptr == NULL ) {
+               return SI_ERROR;                                //  signal bad block
+       }
 
- if( ! (gptr->flags & GIF_SHUTDOWN) )
-  {                        //  if not in shutdown and no signal flags  
-   FD_ZERO( &readfds );               //  clear select info 
-   FD_SET( tpptr->fd, &readfds );     //  set to check read status 
+       uaddr = (struct sockaddr *) malloc( sizeof( struct sockaddr ) );
+       addrlen = sizeof( *uaddr );
 
-   FD_ZERO( &execpfds );               //  clear select info 
-   FD_SET( tpptr->fd, &execpfds );     //  set to check read status 
+       if( ! (gptr->flags & GIF_SHUTDOWN) ) {                          //  if not in shutdown and no signal flags
+               FD_ZERO( &readfds );                                                    //  clear select info
+               FD_SET( tpptr->fd, &readfds );                                  //  set to check read status
 
-   if( delay >= 0 )                //  user asked for a fininte time limit 
-    {
-     tptr = &time;                 //  point at the local struct 
-     tptr->tv_sec = 0;             //  setup time for select call 
-     tptr->tv_usec = delay;
-    }
+               FD_ZERO( &execpfds );                                                   //  clear select info
+               FD_SET( tpptr->fd, &execpfds );                                 //  set to check read status
 
-   if( (select( tpptr->fd + 1, &readfds, NULL, &execpfds, tptr ) < 0 ) )
-    gptr->flags |= GIF_SHUTDOWN;     //  we must shut on error or signal 
-   else
-    {                                //  poll was successful - see if data ? 
-     if( FD_ISSET( tpptr->fd, &execpfds ) )   //  session error? 
-      {
-       SIterm( gptr, tpptr );                 //  clean up our end of things 
-      }
-     else
-      {
-       if( (FD_ISSET( tpptr->fd, &readfds )) )
-        {                                       //  process data if no signal 
-               if( tpptr->type == SOCK_DGRAM )        //  raw data received 
-               {
-                       status = RECVFROM( sid, buf, buflen, 0, uaddr, &addrlen );
-                       if( abuf )
-                       {
-                               SIaddress( uaddr, (void **) &acbuf, AC_TODOT ); //  address returns pointer to buf now rather than filling 
-                               strcpy( abuf, acbuf );                  //  must be back compat with old versions 
-                               free( acbuf );
-                       }
-                       if( status < 0 )                        //  session terminated? 
-                               SIterm( gptr, tpptr );                   //  so close our end 
-               }
-               else                                      //  cooked data received 
-               {
-                       status = RECV( sid, buf, buflen, 0 );   //  read data into user buf 
-                       if( status < 0 )                        //  session terminated? 
-                               SIterm( gptr, tpptr );                 //  so close our end 
-               }
-        }                                         //  end event was received 
-       else                                       //  no event was received  
-        status = 0;                               //  status is just ok 
-      }                       //  end else - not in shutdown mode after poll 
-    }                     //  end else pole was successful 
-  }                                 //  end if not already signal shutdown 
+               if( delay >= 0 ) {                                              //  user asked for a fininte time limit
+                       tptr = &time;                                           //  point at the local struct
+                       tptr->tv_sec = 0;                                       //  setup time for select call
+                       tptr->tv_usec = delay;
+               }
 
- if( gptr->flags & GIF_SHUTDOWN  &&  gptr->tplist != NULL )
-  {             //  shutdown received but sessions not cleaned up 
-   SIshutdown( gptr );
-   status = SI_ERROR;                //  indicate failure on return 
-  }                                  //  end if shut but not clean 
+               if( (select( tpptr->fd + 1, &readfds, NULL, &execpfds, tptr ) < 0 ) ) {
+                       gptr->flags |= GIF_SHUTDOWN;                                                            //  we must shut on error or signal
+               } else {                                //  poll was successful - see if data ?
+                       if( FD_ISSET( tpptr->fd, &execpfds ) ) {                                        //  session error?
+                               SIterm( gptr, tpptr );                                                                  //  clean up our end of things
+                       } else {
+                               if( (FD_ISSET( tpptr->fd, &readfds )) ) {                               //  process data if no signal
+                                       if( tpptr->type == SOCK_DGRAM ) {                                       //  raw data received
+                                               status = RECVFROM( sid, buf, buflen, 0, uaddr, &addrlen );
+                                               if( abuf ) {
+                                                       SIaddress( uaddr, (void **) &acbuf, AC_TODOT );         //  address returns pointer to buf now rather than filling
+                                                       strncpy( abuf, acbuf, 64 );                                                     //  must be back compat with old versions
+                                                       free( acbuf );
+                                               }
+                                               if( status < 0 ) {                                                                      //  session terminated?
+                                                       SIterm( gptr, tpptr );                                                  //  so close our end
+                                               }
+                                       } else {                                                                                                //  cooked data received
+                                               status = RECV( sid, buf, buflen, 0 );                           //  read data into user buf
+                                               if( status < 0 ) {                                                                      //  session terminated?
+                                                       SIterm( gptr, tpptr );                                                  //  so close our end
+                                               }
+                                       }
+                               } else {                                //  end event was received
+                                       status = 0;                     //  status is just ok
+                               }
+                       }                                                       //  end else - not in shutdown mode after poll
+               }                                                               //  end else pole was successful
+       }                                                                       //  end if not already signal shutdown
 
- free( uaddr );
- return status;          //  send back the status 
-}                           //  SIrcv 
+       if( gptr->flags & GIF_SHUTDOWN  &&  gptr->tplist != NULL ) {                            //  shutdown received but sessions not cleaned up
+               SIshutdown( gptr );
+               status = SI_ERROR;
+       }
+
+       free( uaddr );
+       return status;                          //  send back the status
+}
index 69e69e9..e79a3bc 100644 (file)
@@ -352,7 +352,8 @@ static inline rmr_mbuf_t* clone_msg( rmr_mbuf_t* old_msg  ) {
        v1hdr = (uta_v1mhdr_t *) old_msg->header;                               // v1 will work to dig header out of any version
        switch( ntohl( v1hdr->rmr_ver ) ) {
                case 1:
-                       memcpy( v1hdr, old_msg->header, sizeof( *v1hdr ) );             // copy complete header
+                       hdr = nm->header;
+                       memcpy( hdr, old_msg->header, sizeof( *v1hdr ) );               // copy complete header
                        nm->payload = (void *) v1hdr + sizeof( *v1hdr );
                        break;