X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=src%2Frmr%2Fcommon%2Fsrc%2Fmbuf_api.c;h=6abcf8bee2510c45a29aac9108c44fba7f2dfef4;hb=fa454008020483ac35e1d20300cddfe877d8dd6d;hp=1074e371f12ea568620aa3e415765b83e2e1b697;hpb=a7610c690a3976e296ca768977e38ceb9aafa5ff;p=ric-plt%2Flib%2Frmr.git diff --git a/src/rmr/common/src/mbuf_api.c b/src/rmr/common/src/mbuf_api.c index 1074e37..6abcf8b 100644 --- a/src/rmr/common/src/mbuf_api.c +++ b/src/rmr/common/src/mbuf_api.c @@ -22,7 +22,9 @@ Mnemonic: mbuf_api.c 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. + can be agnostic to the underlying transport, or the transport + layer provides a transport specific function (e.g. payload + reallocation). Author: E. Scott Daniels Date: 8 February 2019 @@ -38,6 +40,10 @@ #include "rmr.h" // things the users see #include "rmr_agnostic.h" // agnostic things (must be included before private) +#include "rmr_logging.h" + +//#define BUF_TOOLS_ONLY 1 +#include "tools_static.c" // ---------- some wrappers need explicit copy-in functions, also header field setters ----- @@ -51,6 +57,12 @@ EINVAL id poitner, buf or buf header are bad. EOVERFLOW if the bytes given would have overrun + We have been told that the meid will be a string, so we enforce that even if + the user is copying in bytes. We will add a 0 byte at len+1 when len is less + than the field size, or as the last byte (doing damage to their string) if + the caller didn't play by the rules. If they pass a non-nil terminated set + of bytes which are the field length, we'll indicate truncation. + */ extern int rmr_bytes2meid( rmr_mbuf_t* mbuf, unsigned char const* src, int len ) { uta_mhdr_t* hdr; @@ -69,6 +81,15 @@ extern int rmr_bytes2meid( rmr_mbuf_t* mbuf, unsigned char const* src, int len ) hdr = (uta_mhdr_t *) mbuf->header; memcpy( hdr->meid, src, len ); + if( len == RMR_MAX_MEID ) { + if( *(hdr->meid+len-1) != 0 ) { + *(hdr->meid+len-1) = 0; + errno = EOVERFLOW; + } + } else { + *(hdr->meid+len) = 0; + } + return len; } @@ -88,7 +109,7 @@ extern int rmr_str2meid( rmr_mbuf_t* mbuf, unsigned char const* str ) { } errno = 0; - if( (len = strlen( (char *) str )) > RMR_MAX_MEID-1 ) { + if( (len = strlen( (char const *) str )) > (size_t) (RMR_MAX_MEID-1) ) { // cast keep sonar from twisting its knickers errno = EOVERFLOW; return RMR_ERR_OVERFLOW; } @@ -127,7 +148,7 @@ extern void rmr_bytes2payload( rmr_mbuf_t* mbuf, unsigned char const* src, int l is set to the string length. */ extern void rmr_str2payload( rmr_mbuf_t* mbuf, unsigned char const* str ) { - rmr_bytes2payload( mbuf, str, strlen( (char *) str ) + 1 ); + rmr_bytes2payload( mbuf, str, strlen( (char const *) str ) + 1 ); } @@ -179,7 +200,7 @@ extern int rmr_str2xact( rmr_mbuf_t* mbuf, unsigned char const* str ) { } errno = 0; - if( (len = strlen( (char *) str )) > RMR_MAX_XID-1 ) { + if( (len = strlen( (char const *) str )) > RMR_MAX_XID-1 ) { errno = EOVERFLOW; return RMR_ERR_OVERFLOW; } @@ -189,7 +210,40 @@ extern int rmr_str2xact( rmr_mbuf_t* mbuf, unsigned char const* str ) { } /* - Extracts the meid (managed equipment) from the header and copies the bytes + Extracts the transaction bytes from the header and places into a + user supplied buffer (dest). The buffer must be at least RMR_MAX_XID + bytes in length as this function will copy the entire field (even if + the sender saved a shorter "string." If the user supplies a nil poniter + as the destination, a buffer is allocated; the caller must free when + finished. The buffer will be exactly RMR_MAX_XID bytes long. + + The return value is a pointer to the buffer that was filled (to + the dest buffer provided, or the buffer we allocated). If there is an + error, a nil pointer is returned, and errno should suggest the root + cause of the issue (invalid message or no memory). +*/ +extern unsigned char* rmr_get_xact( rmr_mbuf_t* mbuf, unsigned char* dest ) { + errno = 0; + + if( mbuf == NULL || mbuf->xaction == NULL ) { + errno = EINVAL; + return NULL; + } + + if( ! dest ) { + if( (dest = (unsigned char *) malloc( sizeof( unsigned char ) * RMR_MAX_XID )) == NULL ) { + errno = ENOMEM; + return NULL; + } + } + + memcpy( dest, mbuf->xaction, RMR_MAX_XID ); + + return dest; +} + +/* + Extracts the meid (managed entity) from the header and copies the bytes to the user supplied area. If the user supplied pointer is nil, then a buffer will be allocated and it is the user's responsibilty to free. A pointer is returned to the destination memory (allocated or not) @@ -200,6 +254,8 @@ extern int rmr_str2xact( rmr_mbuf_t* mbuf, unsigned char const* str ) { extern unsigned char* rmr_get_meid( rmr_mbuf_t* mbuf, unsigned char* dest ) { uta_mhdr_t* hdr; + errno = 0; + if( mbuf == NULL || mbuf->header == NULL ) { errno = EINVAL; return NULL; @@ -213,7 +269,7 @@ extern unsigned char* rmr_get_meid( rmr_mbuf_t* mbuf, unsigned char* dest ) { } hdr = (uta_mhdr_t *) mbuf->header; - memcpy( dest, hdr->meid, RMR_MAX_XID ); + memcpy( dest, hdr->meid, RMR_MAX_MEID ); return dest; } @@ -228,6 +284,10 @@ extern unsigned char* rmr_get_meid( rmr_mbuf_t* mbuf, unsigned char* dest ) { The return value is the number of bytes actually coppied. If 0 bytes are coppied errno should indicate the reason. If 0 is returned and errno is 0, then size passed was 0. The state in the message is left UNCHANGED. + + Regardless of action taken (actual realloc or not) the caller's reference to mbuf + is still valid follwing the call and will point to the correct spot (same tp + buffer if no realloc needed, or the new one if there was). */ extern int rmr_set_trace( rmr_mbuf_t* msg, unsigned const char* data, int size ) { uta_mhdr_t* hdr; @@ -256,7 +316,7 @@ extern int rmr_set_trace( rmr_mbuf_t* msg, unsigned const char* data, int size ) if( len != size ) { // different sized trace data, must realloc the buffer nm = rmr_realloc_msg( msg, size ); // realloc with changed trace size - old_tp_buf = msg->tp_buf; + old_tp_buf = msg->tp_buf; // hold to repoint new mbuf at small buffer old_hdr = msg->header; msg->tp_buf = nm->tp_buf; // reference the reallocated buffer @@ -265,7 +325,7 @@ extern int rmr_set_trace( rmr_mbuf_t* msg, unsigned const char* data, int size ) msg->xaction = nm->xaction; msg->payload = nm->payload; - nm->tp_buf = old_tp_buf; // set to free + nm->tp_buf = old_tp_buf; // set to free; point to the small buffer nm->header = old_hdr; // nano frees on hdr, so must set both rmr_free_msg( nm ); @@ -377,7 +437,7 @@ extern unsigned char* rmr_get_src( rmr_mbuf_t* msg, unsigned char* dest ) { if( dest != NULL ) { hdr = msg->header; - strcpy( dest, hdr->src ); + zt_buf_fill( dest, hdr->src, RMR_MAX_SRC ); } return dest; @@ -401,14 +461,15 @@ 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 ); + zt_buf_fill( dest, hdr->srcip, RMR_MAX_SRC ); rstr = dest; } else { errno = 0; - strcpy( dest, hdr->src ); // reutrn the name:port for old messages + zt_buf_fill( dest, hdr->src, RMR_MAX_SRC ); // reutrn the name:port for old messages rstr = dest; } } return rstr; } +