1 // : vi ts=4 sw=4 noet :
3 ==================================================================================
4 Copyright (c) 2019 Nokia
5 Copyright (c) 2018-2019 AT&T Intellectual Property.
7 Licensed under the Apache License, Version 2.0 (the "License");
8 you may not use this file except in compliance with the License.
9 You may obtain a copy of the License at
11 http://www.apache.org/licenses/LICENSE-2.0
13 Unless required by applicable law or agreed to in writing, software
14 distributed under the License is distributed on an "AS IS" BASIS,
15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 See the License for the specific language governing permissions and
17 limitations under the License.
18 ==================================================================================
23 Abstract: These are common functions which work only on the mbuf and
24 thus (because they do not touch an endpoint or context)
25 can be agnostic to the underlying transport, or the transport
26 layer provides a transport specific function (e.g. payload
29 Author: E. Scott Daniels
34 #include <netdb.h> // uint* types
39 #include <semaphore.h>
41 #include "rmr.h" // things the users see
42 #include "rmr_agnostic.h" // agnostic things (must be included before private)
45 // ---------- some wrappers need explicit copy-in functions, also header field setters -----
48 Allow the user programme to set the meid in the header. The meid is a fixed
49 length buffer in the header and thus we must ensure it is not overrun. If
50 the user gives a source buffer that is too large, we truncate. The return
51 value is the number of bytes copied, or -1 for absolute failure (bad pointer
53 EINVAL id poitner, buf or buf header are bad.
54 EOVERFLOW if the bytes given would have overrun
57 extern int rmr_bytes2meid( rmr_mbuf_t* mbuf, unsigned char const* src, int len ) {
60 if( src == NULL || mbuf == NULL || mbuf->header == NULL ) {
66 if( len > RMR_MAX_MEID ) {
71 hdr = (uta_mhdr_t *) mbuf->header;
72 memcpy( hdr->meid, src, len );
78 Allows the user programme to set the meid from a string. The end of string
79 (nil) will be included UNLESS the total length including the end of string
80 would exceed the size of the space in the header for the meid. The return
81 value is RMR_OK for success and !RMR_OK on failure. Errno will be set
84 extern int rmr_str2meid( rmr_mbuf_t* mbuf, unsigned char const* str ) {
85 int len; // len moved -- we do validate
87 if( str == NULL || mbuf == NULL || mbuf->header == NULL ) {
89 return RMR_ERR_BADARG;
93 if( (len = strlen( (char *) str )) > RMR_MAX_MEID-1 ) {
95 return RMR_ERR_OVERFLOW;
98 rmr_bytes2meid( mbuf, str, len+1 );
105 This will copy n bytes from source into the payload. If len is larger than
106 the payload only the bytes which will fit are copied, The user should
107 check errno on return to determine success or failure.
109 extern void rmr_bytes2payload( rmr_mbuf_t* mbuf, unsigned char const* src, int len ) {
110 if( src == NULL || mbuf == NULL || mbuf->payload == NULL ) {
116 mbuf->state = RMR_OK;
117 if( len > mbuf->alloc_len - sizeof( uta_mhdr_t ) ) {
118 mbuf->state = RMR_ERR_OVERFLOW;
120 len = mbuf->alloc_len - sizeof( uta_mhdr_t );
124 memcpy( mbuf->payload, src, len );
128 This will copy a nil terminated string to the mbuf payload. The buffer length
129 is set to the string length.
131 extern void rmr_str2payload( rmr_mbuf_t* mbuf, unsigned char const* str ) {
132 rmr_bytes2payload( mbuf, str, strlen( (char *) str ) + 1 );
137 Allow the user programme to set the xaction field in the header. The xaction
138 is a fixed length buffer in the header and thus we must ensure it is not overrun.
139 If the user gives a source buffer that is too large, we truncate. The return
140 value is the number of bytes copied, or -1 for absolute failure (bad pointer
142 EINVAL id poitner, buf or buf header are bad.
143 EOVERFLOW if the bytes given would have overrun
146 extern int rmr_bytes2xact( rmr_mbuf_t* mbuf, unsigned char const* src, int len ) {
149 if( src == NULL || mbuf == NULL || mbuf->header == NULL ) {
155 if( len > RMR_MAX_XID ) {
160 hdr = (uta_mhdr_t *) mbuf->header;
161 memcpy( hdr->xid, src, len );
169 Allows the user programme to set the xaction (xid) field from a string. The end
170 of string (nil) will be included UNLESS the total length including the end of string
171 would exceed the size of the space in the header for the xaction. The return
172 value is RMR_OK for success and !RMR_OK on failure. Errno will be set
175 extern int rmr_str2xact( rmr_mbuf_t* mbuf, unsigned char const* str ) {
176 int len; // len moved -- we do validate
178 if( str == NULL || mbuf == NULL || mbuf->header == NULL ) {
180 return RMR_ERR_BADARG;
184 if( (len = strlen( (char *) str )) > RMR_MAX_XID-1 ) {
186 return RMR_ERR_OVERFLOW;
189 rmr_bytes2xact( mbuf, str, len+1 );
194 Extracts the transaction bytes from the header and places into a
195 user supplied buffer (dest). The buffer must be at least RMR_MAX_XID
196 bytes in length as this function will copy the entire field (even if
197 the sender saved a shorter "string." If the user supplies a nil poniter
198 as the destination, a buffer is allocated; the caller must free when
199 finished. The buffer will be exactly RMR_MAX_XID bytes long.
201 The return value is a pointer to the buffer that was filled (to
202 the dest buffer provided, or the buffer we allocated). If there is an
203 error, a nil pointer is returned, and errno should suggest the root
204 cause of the issue (invalid message or no memory).
206 extern unsigned char* rmr_get_xact( rmr_mbuf_t* mbuf, unsigned char* dest ) {
209 if( mbuf == NULL || mbuf->xaction == NULL ) {
215 if( (dest = (unsigned char *) malloc( sizeof( unsigned char ) * RMR_MAX_XID )) == NULL ) {
221 memcpy( dest, mbuf->xaction, RMR_MAX_XID );
227 Extracts the meid (managed equipment) from the header and copies the bytes
228 to the user supplied area. If the user supplied pointer is nil, then
229 a buffer will be allocated and it is the user's responsibilty to free.
230 A pointer is returned to the destination memory (allocated or not)
231 for consistency. If the user programme supplies a destination it is
232 the responsibility of the programme to ensure that the space is large
235 extern unsigned char* rmr_get_meid( rmr_mbuf_t* mbuf, unsigned char* dest ) {
240 if( mbuf == NULL || mbuf->header == NULL ) {
246 if( (dest = (unsigned char *) malloc( sizeof( unsigned char ) * RMR_MAX_MEID )) == NULL ) {
252 hdr = (uta_mhdr_t *) mbuf->header;
253 memcpy( dest, hdr->meid, RMR_MAX_MEID );
258 // ------------------- trace related access functions --------------------------------------
260 The set_trace function will copy the supplied data for size bytes into the
261 header. If the header trace area is not large enough, a new one will be allocated
262 which will cause a payload copy based on the msg->len value (if 0 no payload
265 The return value is the number of bytes actually coppied. If 0 bytes are coppied
266 errno should indicate the reason. If 0 is returned and errno is 0, then size
267 passed was 0. The state in the message is left UNCHANGED.
269 extern int rmr_set_trace( rmr_mbuf_t* msg, unsigned const char* data, int size ) {
271 rmr_mbuf_t* nm; // new message if larger is needed
273 void* old_tp_buf; // if we need to realloc, must hold old to free
286 hdr = (uta_mhdr_t *) msg->header;
292 len = RMR_TR_LEN( hdr );
294 if( len != size ) { // different sized trace data, must realloc the buffer
295 nm = rmr_realloc_msg( msg, size ); // realloc with changed trace size
296 old_tp_buf = msg->tp_buf;
297 old_hdr = msg->header;
299 msg->tp_buf = nm->tp_buf; // reference the reallocated buffer
300 msg->header = nm->header;
301 msg->id = NULL; // currently unused
302 msg->xaction = nm->xaction;
303 msg->payload = nm->payload;
305 nm->tp_buf = old_tp_buf; // set to free
306 nm->header = old_hdr; // nano frees on hdr, so must set both
309 hdr = (uta_mhdr_t *) msg->header; // header WILL be different
310 len = RMR_TR_LEN( hdr );
313 memcpy( TRACE_ADDR( hdr ), data, size );
320 Returns a pointer (reference) to the trace data in the message. If sizeptr
321 is supplied, then the trace data size is assigned to the referenced
322 integer so that the caller doesn't need to make a second call to get the
325 CAUTION: user programmes should avoid writing to the referenced trace
326 area (use rmr_set_trace() to avoid possible data overruns. This
327 function is a convenience, and it is expected that users will
328 use the trace data as read-only so as a copy is not necessary.
330 extern void* rmr_trace_ref( rmr_mbuf_t* msg, int* sizeptr ) {
331 uta_mhdr_t* hdr = NULL;
334 if( sizeptr != NULL ) {
335 *sizeptr = 0; // ensure reset if we bail
343 if( (size = RMR_TR_LEN( hdr )) <= 0 ) {
347 if( sizeptr != NULL ) {
351 return (void *) TRACE_ADDR( hdr );
355 Copies the trace bytes from the message header into the buffer provided by
356 the user. If the trace data in the header is less than size, then only
357 that number of bytes are copied, else exactly size bytes are copied. The
358 number actually copied is returned.
360 extern int rmr_get_trace( rmr_mbuf_t* msg, unsigned char* dest, int size ) {
361 uta_mhdr_t* hdr = NULL;
368 if( size <= 0 || dest == NULL ) {
373 if( (n2copy = size < RMR_TR_LEN( hdr ) ? size : RMR_TR_LEN( hdr )) <= 0 ) {
377 memcpy( dest, TRACE_ADDR( hdr ), n2copy );
383 Returns the number of bytes currently allocated for trace data in the message
386 extern int rmr_get_trlen( rmr_mbuf_t* msg ) {
395 return RMR_TR_LEN( hdr );
399 Returns the string in the source portion of the header. This is assumed to be
400 something that can be used for direct sends (hostname:port). Regardless, it
401 will be a nil terminated, ascii string with max of 64 characters including
402 the final nil. So, the user must ensure that dest is at least 64 bytes.
404 As a convenience, the pointer to dest is returned on success; nil on failure
407 extern unsigned char* rmr_get_src( rmr_mbuf_t* msg, unsigned char* dest ) {
408 uta_mhdr_t* hdr = NULL;
417 strcpy( dest, hdr->src );
424 Returns the string with the IP address as reported by the sender. This is
425 the IP address that the sender has sussed off of one of the interfaces
426 and cannot be guarenteed to be the acutal IP address which was used to
427 establish the connection. The caller must provide a buffer of at least
428 64 bytes; the string will be nil terminated. A pointer to the user's buffer
429 is returned on success, nil on failure.
431 extern unsigned char* rmr_get_srcip( rmr_mbuf_t* msg, unsigned char* dest ) {
432 uta_mhdr_t* hdr = NULL;
437 if( dest != NULL && msg != NULL ) {
439 if( HDR_VERSION( msg->header ) > 2 ) { // src ip was not present in hdr until ver 3
441 strcpy( dest, hdr->srcip );
445 strcpy( dest, hdr->src ); // reutrn the name:port for old messages