blob: 16ee6ff1529e85a48472cecd7f0759bef66a7300 [file] [log] [blame]
.if false
==================================================================================
Copyright (c) 2019 Nokia
Copyright (c) 2018-2019 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.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==================================================================================
.fi
&h1(Appendix &mbuf_appendix -- Message Buffer Details)
The RMR message buffer is a C structure which is exposed in the
&cw(rmr.h) header file. It is used to manage a message received from
a peer endpoint, or a message that is being sent to a peer. Fields
include payload length, amount of payload actually used, status, and a
reference to the payload. There are also fields which the application
should ignore, and could be hidden in the header file, but we chose
not to. These fields include a reference to the RMR header
information, and to the underlying transport mechanism message struct
which may or may not be the same as the RMR header reference.
&h2(The Structure)
The following is the C structure. Readers are cautioned to examine
the &cw(rmr.h) header file directly; the information here may be out
of date (old document in some cache), and thus it may be incorrect.
&space
&indent
&ex_start
typedef struct {
int state; // state of processing
int mtype; // message type
int len; // length of data in the payload (send or received)
unsigned char* payload; // transported data
unsigned char* xaction; // pointer to fixed length transaction id bytes
int sub_id; // subscription id
int tp_state; // transport state (errno)
// these things are off limits to the user application
void* tp_buf; // underlying transport allocated pointer (e.g. nng message)
void* header; // internal message header (whole buffer: header+payload)
unsigned char* id; // if we need an ID in the message separate from the xaction id
int flags; // various MFL_ (private) flags as needed
int alloc_len; // the length of the allocated space (hdr+payload)
void* ring; // ring this buffer should be queued back to
int rts_fd; // SI fd for return to sender
int cookie; // cookie to detect user misuse of free'd msg
} rmr_mbuf_t;
&ex_end
&uindent
&space
&h2(State vs Transport State)
The state field reflects the state at the time the message buffer is
returned to the calling application. For a send operation, if the
state is not &cw(RMR_OK) then the message buffer references the
payload that could not be sent, and when the state is &cw(RMR_OK) the
buffer references a &ital(fresh) payload that the application may fill
in.
&space
When the state is not &cw(RMR_OK,) C programmes may examine the global
&cw(errno) value which RMR will have left set, if it was set, by the
underlying transport mechanism. In some cases, wrapper modules are
not able to directly access the C-library &cw(errno) value, and to
assist with possible transport error details, the send and receive
operations populate &cw(tp_state) with the value of &cw(errno.)
&space
Regardless of whether the application makes use of the &cw(tp_state,)
or the &cw(errno) value, it should be noted that the underlying
transport mechanism may not actually update the errno value; in other
words: it might not be accurate. In addition, RMR populates the
&cw(tp_state) value in the message buffer &bold(only) when the state
is not &cw(RMR_OK.)
&h2(Field References)
The transaction field was exposed in the first version of RMR, and in
hindsight this shouldn't have been done. Rather than break any
existing code the reference was left, but additional fields such as
trace data, were not directly exposed to the application. The
application developer is strongly encouraged to use the functions
which get and set the transaction ID rather than using the pointer
directly; any data overruns will not be detected if the reference is
used directly.
&space
In contrast, the payload reference should be used directly by the
application in the interest of speed and ease of programming. The
same care to prevent writing more bytes to the payload buffer than it
can hold must be taken by the application. By the nature of the
allocation of the payload in transport space, RMR is unable to add
guard bytes and/or test for data overrun.
&h2(Actual Transmission)
When RMR sends the application's message, the message buffer is
&bold(not) transmitted. The transport buffer (tp_buf) which contains
the RMR header and application payload is the only set of bytes which
are transmitted. While it may seem to the caller like the function
&func(rmr_send_msg) is returning a new message buffer, the same struct
is reused and only a new transport buffer is allocated. The intent is
to keep the alloc/free cycles to a minimum.