E. Scott Daniels | 06e85b7 | 2019-08-06 16:29:00 -0400 | [diff] [blame] | 1 | |
| 2 | .if false |
| 3 | ================================================================================== |
| 4 | Copyright (c) 2019 Nokia |
| 5 | Copyright (c) 2018-2019 AT&T Intellectual Property. |
| 6 | |
| 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 |
| 10 | |
| 11 | http://www.apache.org/licenses/LICENSE-2.0 |
| 12 | |
| 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 | ================================================================================== |
| 19 | .fi |
| 20 | |
| 21 | &h1(Appendix &mbuf_appendix -- Message Buffer Details) |
| 22 | |
Lott, Christopher (cl778h) | fe6a856 | 2020-04-06 15:05:22 -0400 | [diff] [blame] | 23 | The RMR message buffer is a C structure which is exposed in the |
| 24 | &cw(rmr.h) header file. It is used to manage a message received from |
| 25 | a peer endpoint, or a message that is being sent to a peer. Fields |
| 26 | include payload length, amount of payload actually used, status, and a |
| 27 | reference to the payload. There are also fields which the application |
| 28 | should ignore, and could be hidden in the header file, but we chose |
| 29 | not to. These fields include a reference to the RMR header |
| 30 | information, and to the underlying transport mechanism message struct |
| 31 | which may or may not be the same as the RMR header reference. |
E. Scott Daniels | 06e85b7 | 2019-08-06 16:29:00 -0400 | [diff] [blame] | 32 | |
| 33 | &h2(The Structure) |
Lott, Christopher (cl778h) | fe6a856 | 2020-04-06 15:05:22 -0400 | [diff] [blame] | 34 | The following is the C structure. Readers are cautioned to examine |
| 35 | the &cw(rmr.h) header file directly; the information here may be out |
| 36 | of date (old document in some cache), and thus it may be incorrect. |
E. Scott Daniels | 06e85b7 | 2019-08-06 16:29:00 -0400 | [diff] [blame] | 37 | |
| 38 | &space |
| 39 | &indent |
| 40 | &ex_start |
| 41 | |
| 42 | typedef struct { |
| 43 | int state; // state of processing |
| 44 | int mtype; // message type |
| 45 | int len; // length of data in the payload (send or received) |
| 46 | unsigned char* payload; // transported data |
| 47 | unsigned char* xaction; // pointer to fixed length transaction id bytes |
| 48 | int sub_id; // subscription id |
| 49 | int tp_state; // transport state (errno) |
| 50 | |
| 51 | // these things are off limits to the user application |
| 52 | void* tp_buf; // underlying transport allocated pointer (e.g. nng message) |
| 53 | void* header; // internal message header (whole buffer: header+payload) |
| 54 | unsigned char* id; // if we need an ID in the message separate from the xaction id |
| 55 | int flags; // various MFL_ (private) flags as needed |
| 56 | int alloc_len; // the length of the allocated space (hdr+payload) |
Lott, Christopher (cl778h) | fe6a856 | 2020-04-06 15:05:22 -0400 | [diff] [blame] | 57 | void* ring; // ring this buffer should be queued back to |
| 58 | int rts_fd; // SI fd for return to sender |
| 59 | int cookie; // cookie to detect user misuse of free'd msg |
E. Scott Daniels | 06e85b7 | 2019-08-06 16:29:00 -0400 | [diff] [blame] | 60 | } rmr_mbuf_t; |
| 61 | &ex_end |
| 62 | &uindent |
| 63 | &space |
| 64 | |
| 65 | &h2(State vs Transport State) |
Lott, Christopher (cl778h) | fe6a856 | 2020-04-06 15:05:22 -0400 | [diff] [blame] | 66 | The state field reflects the state at the time the message buffer is |
| 67 | returned to the calling application. For a send operation, if the |
| 68 | state is not &cw(RMR_OK) then the message buffer references the |
| 69 | payload that could not be sent, and when the state is &cw(RMR_OK) the |
| 70 | buffer references a &ital(fresh) payload that the application may fill |
| 71 | in. |
E. Scott Daniels | 06e85b7 | 2019-08-06 16:29:00 -0400 | [diff] [blame] | 72 | |
| 73 | &space |
Lott, Christopher (cl778h) | fe6a856 | 2020-04-06 15:05:22 -0400 | [diff] [blame] | 74 | When the state is not &cw(RMR_OK,) C programmes may examine the global |
| 75 | &cw(errno) value which RMR will have left set, if it was set, by the |
| 76 | underlying transport mechanism. In some cases, wrapper modules are |
| 77 | not able to directly access the C-library &cw(errno) value, and to |
| 78 | assist with possible transport error details, the send and receive |
E. Scott Daniels | 06e85b7 | 2019-08-06 16:29:00 -0400 | [diff] [blame] | 79 | operations populate &cw(tp_state) with the value of &cw(errno.) |
| 80 | |
| 81 | &space |
Lott, Christopher (cl778h) | fe6a856 | 2020-04-06 15:05:22 -0400 | [diff] [blame] | 82 | Regardless of whether the application makes use of the &cw(tp_state,) |
| 83 | or the &cw(errno) value, it should be noted that the underlying |
| 84 | transport mechanism may not actually update the errno value; in other |
| 85 | words: it might not be accurate. In addition, RMR populates the |
| 86 | &cw(tp_state) value in the message buffer &bold(only) when the state |
| 87 | is not &cw(RMR_OK.) |
E. Scott Daniels | 06e85b7 | 2019-08-06 16:29:00 -0400 | [diff] [blame] | 88 | |
| 89 | &h2(Field References) |
Lott, Christopher (cl778h) | fe6a856 | 2020-04-06 15:05:22 -0400 | [diff] [blame] | 90 | The transaction field was exposed in the first version of RMR, and in |
| 91 | hindsight this shouldn't have been done. Rather than break any |
| 92 | existing code the reference was left, but additional fields such as |
| 93 | trace data, were not directly exposed to the application. The |
| 94 | application developer is strongly encouraged to use the functions |
| 95 | which get and set the transaction ID rather than using the pointer |
| 96 | directly; any data overruns will not be detected if the reference is |
| 97 | used directly. |
E. Scott Daniels | 06e85b7 | 2019-08-06 16:29:00 -0400 | [diff] [blame] | 98 | |
| 99 | &space |
Lott, Christopher (cl778h) | fe6a856 | 2020-04-06 15:05:22 -0400 | [diff] [blame] | 100 | In contrast, the payload reference should be used directly by the |
| 101 | application in the interest of speed and ease of programming. The |
| 102 | same care to prevent writing more bytes to the payload buffer than it |
| 103 | can hold must be taken by the application. By the nature of the |
| 104 | allocation of the payload in transport space, RMR is unable to add |
| 105 | guard bytes and/or test for data overrun. |
E. Scott Daniels | 06e85b7 | 2019-08-06 16:29:00 -0400 | [diff] [blame] | 106 | |
| 107 | &h2(Actual Transmission) |
Lott, Christopher (cl778h) | fe6a856 | 2020-04-06 15:05:22 -0400 | [diff] [blame] | 108 | When RMR sends the application's message, the message buffer is |
| 109 | &bold(not) transmitted. The transport buffer (tp_buf) which contains |
| 110 | the RMR header and application payload is the only set of bytes which |
| 111 | are transmitted. While it may seem to the caller like the function |
| 112 | &func(rmr_send_msg) is returning a new message buffer, the same struct |
| 113 | is reused and only a new transport buffer is allocated. The intent is |
| 114 | to keep the alloc/free cycles to a minimum. |