MySQL 9.1.0
Source Code Documentation
gcs_message.h
Go to the documentation of this file.
1/* Copyright (c) 2014, 2024, Oracle and/or its affiliates.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is designed to work with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have either included with
13 the program or referenced in the documentation.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23
24#ifndef GCS_GCS_MESSAGE_INCLUDED
25#define GCS_GCS_MESSAGE_INCLUDED
26
27#include <stdint.h>
28#include <cstring>
29#include <vector>
30
35
36#define WIRE_PAYLOAD_LEN_SIZE 8
37#define WIRE_HEADER_LEN_SIZE 4
38
39/**
40 @class Gcs_message_data
41
42 This class serves as data container for information flowing in the GCS
43 ecosystem. It has been isolated in order to be used in place where a
44 full-blown Gcs_message does not make sense.
45
46 For a full usage example, check the Gcs_message documentation.
47 */
49 public:
51 /**
52 Constructor of Gcs_message_data which pre-allocates space to store
53 the header and payload and should be used when creating messages to
54 send information to remote peers.
55
56 @param header_capacity Determines the header's size.
57 @param payload_capacity Determines the payload's size.
58 */
59 explicit Gcs_message_data(const uint32_t header_capacity,
60 const uint64_t payload_capacity);
61
62 /**
63 Constructor of Gcs_message_data which pre-allocates space to store
64 a message received from a remote peer.
65
66 @param data_len Data's length.
67 */
68 explicit Gcs_message_data(const uint64_t data_len);
69
70 virtual ~Gcs_message_data();
71
72 /**
73 Appends data to the header of the message. The data MUST have been
74 previously encoded in little endian format.
75
76 If the data to be appended exceeds the pre-allocated buffer capacity
77 an error is returned.
78
79 @param[in] to_append the data to append
80 @param[in] to_append_len the length of the data to append
81
82 @return true on error, false otherwise.
83 */
84
85 bool append_to_header(const uchar *to_append, uint32_t to_append_len);
86
87 /**
88 Appends data to the payload of the message. The data MUST have been
89 previously encoded in little endian format.
90
91 If the data to be appended exceeds the pre-allocated buffer capacity
92 an error is returned.
93
94 @param[in] to_append the data to append
95 @param[in] to_append_len the length of the data to append
96
97 @return true on error, false otherwise.
98 */
99
100 bool append_to_payload(const uchar *to_append, uint64_t to_append_len);
101
102 /**
103 Release the buffer's ownership which means that this object will not
104 be responsible for deallocating its internal buffer. The caller should
105 do so.
106
107 This method should be used along with the following method:
108 encode(**buffer, *buffer_len).
109 **/
110
111 void release_ownership();
112
113 /**
114 Encodes the header and payload into an internal buffer. If NULL pointer
115 is provided or the data was not already appended to the buffer, an error
116 is returned.
117
118 The meta data is formatted in little endian format, and is structured
119 on the wire as depicted below:
120
121 -----------------------------------------------
122 | header len | payload len | header | payload |
123 -----------------------------------------------
124
125 @param[in,out] buffer Variable that will hold a pointer to the buffer
126 @param[in,out] buffer_len Variable that will hold the buffer's size.
127
128 @return true on error, false otherwise.
129 */
130
131 bool encode(uchar **buffer, uint64_t *buffer_len) const;
132
133 /**
134 Encodes the header and payload into a buffer provided by the caller.
135 If the buffer is not large enough to store the encoded data or is a
136 NULL pointer, an error is returned.
137
138 @param [in,out] buffer Buffer to store the encoded data in the message.
139 @param [in,out] buffer_len The length of the buffer where the data is to be
140 stored. It contains the length of the data dumped into the buffer once the
141 function succeeds.
142
143 @return true on error, false otherwise.
144 */
145
146 bool encode(uchar *buffer, uint64_t *buffer_len) const;
147
148 /**
149 Decodes data received via GCS and that belongs to a message. After
150 decoding, all the fields will be filled. The data MUST be in little endian
151 format.
152
153 If the buffer is not large enough to store the encoded data or is a
154 NULL pointer, an error is returned.
155
156 @param[in] data Data received via network
157 @param[in] data_len Data length received via network
158
159 @return true on error, false otherwise.
160 */
161
162 bool decode(const uchar *data, uint64_t data_len);
163
164 /**
165 @return the message header in little endian format
166 */
167
168 const uchar *get_header() const;
169
170 /**
171 @return the message header length
172 */
173
174 uint32_t get_header_length() const;
175
176 /**
177 @return the message payload in little endian format
178 */
179
180 const uchar *get_payload() const;
181
182 /**
183 @return the message payload_length
184 */
185
186 uint64_t get_payload_length() const;
187
188 /**
189 @return the size of the encoded data when put on the wire.
190 */
191
192 virtual uint64_t get_encode_size() const;
193
194 /**
195 @return the size of the encoded payload when put on the wire.
196 */
197
198 uint64_t get_encode_payload_size() const;
199
200 /**
201 @return the size of the encoded header when put on the wire.
202 */
203
204 uint64_t get_encode_header_size() const;
205
206 private:
207 /*
208 Pointer to the header's buffer.
209 */
211
212 /*
213 Pointer to the next empty position in the header's buffer.
214 */
216
217 /*
218 Length of the header's buffer in use.
219 */
220 uint32_t m_header_len;
221
222 /*
223 Capacity of the header's buffer.
224 */
226
227 /*
228 Pointer to the payload's buffer.
229 */
231
232 /*
233 Pointer to the next empty position in the payload's buffer.
234 */
236
237 /*
238 Length of the payload's buffer in use.
239 */
241
242 /*
243 Capacity of the header's buffer.
244 */
246
247 /*
248 Pointer to the beginning of the buffer that contains both the
249 header and the payload.
250 */
252
253 /*
254 Length of the buffer that contains both the header, the
255 payload and metadata information.
256 */
257 uint64_t m_buffer_len;
258
259 /*
260 Whether the current object owns the buffer and must free it
261 when deleted.
262 */
264
265 /**
266 On memory allocation this function is called, so that memory
267 consumption can be tracked.
268
269 @param[in] size memory size to be allocated
270
271 @return true on error, false otherwise.
272 */
273 bool report_allocate_memory(size_t size);
274
275 /**
276 On memory free this function is called to reduce count of allocated memory.
277
278 @param[in] size memory size to be allocated
279 */
280 void report_deallocate_memory(size_t size);
281
282 /*
283 Disabling the copy constructor and assignment operator.
284 */
287};
288
289/**
290 @class Gcs_message
291
292 Class that represents the data that is exchanged within a group. It is sent
293 by a member having the group as destination. It shall be received by all
294 members that pertain to the group in that moment.
295
296 It is built using two major blocks: the header and the payload of the
297 message. A user of Gcs_message can freely add data to the header and to the
298 payload.
299
300 Each binding implementation might use these two fields at its own
301 discretion but that data should be removed from the header/payload
302 before its delivery to the client layer.
303
304 When the message is built, none of the data is passed unto it. One has to
305 use the append_* methods in order to append data. Calling encode() at the end
306 will provide a ready-to-send message.
307
308 On the receiver side, one shall use decode() in order to have the header and
309 the payload restored in the original message fields.
310
311 A typical use case of sending a message is:
312
313 @code{.cpp}
314
315 Gcs_control_interface *gcs_ctrl_interface_instance;
316 Gcs_communication_interface *gcs_comm_interface_instance; // obtained
317 // previously
318
319 Gcs_member_identifier *myself=
320 gcs_ctrl_interface_instance->get_local_information();
321
322 Gcs_group_identifier destination("the_group");
323
324 Gcs_message *msg= new Gcs_message(&myself, new Gcs_message_data(0, 3));
325
326 uchar[] some_data= {(uchar)0x12,
327 (uchar)0x24,
328 (uchar)0x00};
329
330 msg->get_message_data()->append_to_payload(&some_data,
331 strlen(some_data));
332
333 gcs_comm_interface_instance->send_message(msg);
334 @endcode
335
336 A typical use case of receiving a message is:
337
338 @code{.cpp}
339 class my_Gcs_communication_event_listener : Gcs_communication_event_listener
340 {
341 my_Gcs_communication_event_listener(my_Message_delegator *delegator)
342 {
343 this->delegator= delegator;
344 }
345
346 void on_message_received(Gcs_message &message)
347 {
348 // Do something when message arrives...
349 delegator->process_gcs_message(message);
350 }
351
352 private:
353 my_Message_delegator *delegator;
354 }
355 @endcode
356*/
358 public:
359 /**
360 Gcs_message 1st constructor. This is used to build full messages.
361
362 Note that the Gcs_message will acquire ownership of the data, i.e.
363 Gcs_message_data, and will be responsible for deleting it.
364
365 @param[in] origin The group member that sent the message
366 @param[in] destination The group in which this message belongs
367 @param[in] message_data External message data object.
368 */
369
370 explicit Gcs_message(const Gcs_member_identifier &origin,
371 const Gcs_group_identifier &destination,
372 Gcs_message_data *message_data);
373
374 /**
375 Gcs_message 2nd constructor. This is used to send messages but with
376 an external Gcs_message_data object.
377
378 Note that the Gcs_message will acquire ownership of the data, i.e.
379 Gcs_message_data, and will be responsible for deleting it.
380
381 @param[in] origin The group member that sent the message
382 @param[in] message_data External message data object.
383 */
384
385 explicit Gcs_message(const Gcs_member_identifier &origin,
386 Gcs_message_data *message_data);
387
388 virtual ~Gcs_message();
389
390 /**
391 @return the origin of this message
392 */
393
394 const Gcs_member_identifier &get_origin() const;
395
396 /**
397 @return the destination of this message. It might be NULL.
398 */
399
401
402 /**
403 @return the message data to be filled.
404 */
405
407
408 private:
409 void init(const Gcs_member_identifier *origin,
410 const Gcs_group_identifier *destination,
411 Gcs_message_data *message_data);
412
416
417 /*
418 Disabling the copy constructor and assignment operator.
419 */
422};
423
424#endif // GCS_GCS_MESSAGE_INCLUDED
This represents the unique identification of a group.
Definition: gcs_group_identifier.h:35
It represents the identity of a group member within a certain group.
Definition: gcs_member_identifier.h:40
This class serves as data container for information flowing in the GCS ecosystem.
Definition: gcs_message.h:48
bool report_allocate_memory(size_t size)
On memory allocation this function is called, so that memory consumption can be tracked.
Definition: gcs_message.cc:97
uint64_t m_buffer_len
Definition: gcs_message.h:257
bool decode(const uchar *data, uint64_t data_len)
Decodes data received via GCS and that belongs to a message.
Definition: gcs_message.cc:266
uchar * m_payload
Definition: gcs_message.h:230
bool append_to_payload(const uchar *to_append, uint64_t to_append_len)
Appends data to the payload of the message.
Definition: gcs_message.cc:160
uint64_t m_payload_capacity
Definition: gcs_message.h:245
void report_deallocate_memory(size_t size)
On memory free this function is called to reduce count of allocated memory.
Definition: gcs_message.cc:108
virtual ~Gcs_message_data()
Definition: gcs_message.cc:90
uint32_t get_header_length() const
Definition: gcs_message.cc:117
Gcs_message_data & operator=(Gcs_message_data const &)
virtual uint64_t get_encode_size() const
Definition: gcs_message.cc:123
uint64_t get_encode_payload_size() const
Definition: gcs_message.cc:127
const uchar * get_header() const
Definition: gcs_message.cc:115
bool m_owner
Definition: gcs_message.h:263
bool encode(uchar **buffer, uint64_t *buffer_len) const
Encodes the header and payload into an internal buffer.
Definition: gcs_message.cc:181
uchar * m_payload_slider
Definition: gcs_message.h:235
const uchar * get_payload() const
Definition: gcs_message.cc:119
Gcs_message_data()
Gcs_message_data implementation.
Definition: gcs_message.cc:39
bool append_to_header(const uchar *to_append, uint32_t to_append_len)
Appends data to the header of the message.
Definition: gcs_message.cc:141
uchar * m_header_slider
Definition: gcs_message.h:215
uchar * m_header
Definition: gcs_message.h:210
uchar * m_buffer
Definition: gcs_message.h:251
uint32_t m_header_capacity
Definition: gcs_message.h:225
void release_ownership()
Release the buffer's ownership which means that this object will not be responsible for deallocating ...
Definition: gcs_message.cc:179
uint64_t get_payload_length() const
Definition: gcs_message.cc:121
Gcs_message_data(Gcs_message_data const &)
uint64_t get_encode_header_size() const
Definition: gcs_message.cc:135
uint64_t m_payload_len
Definition: gcs_message.h:240
uint32_t m_header_len
Definition: gcs_message.h:220
Class that represents the data that is exchanged within a group.
Definition: gcs_message.h:357
const Gcs_member_identifier & get_origin() const
Definition: gcs_message.cc:342
Gcs_message(Gcs_message const &)
Gcs_message & operator=(Gcs_message const &)
virtual ~Gcs_message()
Definition: gcs_message.cc:336
const Gcs_group_identifier * get_destination() const
Definition: gcs_message.cc:347
Gcs_member_identifier * m_origin
Definition: gcs_message.h:413
Gcs_message_data & get_message_data() const
Definition: gcs_message.cc:352
Gcs_group_identifier * m_destination
Definition: gcs_message.h:414
Gcs_message_data * m_data
Definition: gcs_message.h:415
void init(const Gcs_member_identifier *origin, const Gcs_group_identifier *destination, Gcs_message_data *message_data)
Definition: gcs_message.cc:354
Gcs_message(const Gcs_member_identifier &origin, const Gcs_group_identifier &destination, Gcs_message_data *message_data)
Gcs_message 1st constructor.
Definition: gcs_message.cc:323
unsigned char uchar
Definition: my_inttypes.h:52
size_t size(const char *const c)
Definition: base64.h:46
mutable_buffer buffer(void *p, size_t n) noexcept
Definition: buffer.h:418