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