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
#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 -----
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;
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;
}
}
/*
- 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)
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;
}
hdr = (uta_mhdr_t *) mbuf->header;
- memcpy( dest, hdr->meid, RMR_MAX_XID );
+ memcpy( dest, hdr->meid, RMR_MAX_MEID );
return dest;
}
}
+/*
+ Returns a pointer (reference) to the trace data in the message. If sizeptr
+ is supplied, then the trace data size is assigned to the referenced
+ integer so that the caller doesn't need to make a second call to get the
+ value.
+
+ CAUTION: user programmes should avoid writing to the referenced trace
+ area (use rmr_set_trace() to avoid possible data overruns. This
+ function is a convenience, and it is expected that users will
+ use the trace data as read-only so as a copy is not necessary.
+*/
+extern void* rmr_trace_ref( rmr_mbuf_t* msg, int* sizeptr ) {
+ uta_mhdr_t* hdr = NULL;
+ int size = 0;
+
+ if( sizeptr != NULL ) {
+ *sizeptr = 0; // ensure reset if we bail
+ }
+
+ if( msg == NULL ) {
+ return NULL;
+ }
+
+ hdr = msg->header;
+ if( (size = RMR_TR_LEN( hdr )) <= 0 ) {
+ return NULL;
+ }
+
+ if( sizeptr != NULL ) {
+ *sizeptr = size;
+ }
+
+ return (void *) TRACE_ADDR( hdr );
+}
+
/*
Copies the trace bytes from the message header into the buffer provided by
the user. If the trace data in the header is less than size, then only
if( dest != NULL ) {
hdr = msg->header;
- strcpy( dest, hdr->src );
+ zt_buf_fill( dest, hdr->src, RMR_MAX_SRC );
}
return dest;
/*
Returns the string with the IP address as reported by the sender. This is
the IP address that the sender has sussed off of one of the interfaces
- and cannot be guarenteed to be the acutal IP address which was used to
+ and cannot be guarenteed to be the acutal IP address which was used to
establish the connection. The caller must provide a buffer of at least
64 bytes; the string will be nil terminated. A pointer to the user's buffer
is returned on success, nil on failure.
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;
}
+