1 /* Copyright (c) 2014, 2021, 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 Foundation,
21    51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
22 
23 #include "gcs_plugin_messages.h"
24 
25 const int Plugin_gcs_message::PLUGIN_GCS_MESSAGE_VERSION= 1;
26 
27 const unsigned int Plugin_gcs_message::WIRE_VERSION_SIZE= 4;
28 const unsigned int Plugin_gcs_message::WIRE_HD_LEN_SIZE= 2;
29 const unsigned int Plugin_gcs_message::WIRE_MSG_LEN_SIZE= 8;
30 const unsigned int Plugin_gcs_message::WIRE_CARGO_TYPE_SIZE= 2;
31 
32 const unsigned int Plugin_gcs_message::WIRE_FIXED_HEADER_SIZE=
33     Plugin_gcs_message::WIRE_VERSION_SIZE +
34     Plugin_gcs_message::WIRE_HD_LEN_SIZE +
35     Plugin_gcs_message::WIRE_MSG_LEN_SIZE +
36     Plugin_gcs_message::WIRE_CARGO_TYPE_SIZE;
37 
38 const unsigned int Plugin_gcs_message::WIRE_PAYLOAD_ITEM_TYPE_SIZE= 2;
39 
40 const unsigned int Plugin_gcs_message::WIRE_PAYLOAD_ITEM_LEN_SIZE= 8;
41 
42 const unsigned int Plugin_gcs_message::WIRE_PAYLOAD_ITEM_HEADER_SIZE=
43     Plugin_gcs_message::WIRE_PAYLOAD_ITEM_TYPE_SIZE +
44     Plugin_gcs_message::WIRE_PAYLOAD_ITEM_LEN_SIZE;
45 
Plugin_gcs_message(enum_cargo_type cargo_type)46 Plugin_gcs_message::Plugin_gcs_message(enum_cargo_type cargo_type)
47   : m_version(PLUGIN_GCS_MESSAGE_VERSION),
48     m_fixed_header_len(WIRE_FIXED_HEADER_SIZE),
49     m_msg_len(WIRE_FIXED_HEADER_SIZE),
50     m_cargo_type(cargo_type)
51 {
52 }
53 
encode(std::vector<unsigned char> * buffer) const54 void Plugin_gcs_message::encode(std::vector<unsigned char>* buffer) const
55 {
56   DBUG_ENTER("Plugin_gcs_message::encode");
57   unsigned char buf[WIRE_FIXED_HEADER_SIZE];
58   unsigned char* slider= buf;
59 
60   int4store(slider, m_version);
61   slider += WIRE_VERSION_SIZE;
62 
63   int2store(slider, m_fixed_header_len);
64   slider += WIRE_HD_LEN_SIZE;
65 
66   int8store(slider, m_msg_len);
67   slider += WIRE_MSG_LEN_SIZE;
68 
69   unsigned short s_cargo_type= (unsigned short) m_cargo_type;
70   int2store(slider, s_cargo_type);
71   slider += WIRE_CARGO_TYPE_SIZE;
72 
73   buffer->insert(buffer->end(), buf, buf + WIRE_FIXED_HEADER_SIZE);
74 
75   encode_payload(buffer);
76 
77   DBUG_VOID_RETURN;
78 }
79 
decode(const unsigned char * buffer,uint64 length)80 void Plugin_gcs_message::decode(const unsigned char* buffer,
81                                 uint64 length)
82 {
83   DBUG_ENTER("Plugin_gcs_message::decode");
84   const unsigned char *slider= buffer;
85   const unsigned char *end= buffer + length;
86 
87   m_version= uint4korr(slider);
88   slider += WIRE_VERSION_SIZE;
89 
90   m_fixed_header_len= uint2korr(slider);
91   slider += WIRE_HD_LEN_SIZE;
92 
93   m_msg_len= uint8korr(slider);
94   slider += WIRE_MSG_LEN_SIZE;
95 
96   unsigned short s_cargo_type= 0;
97   s_cargo_type= uint2korr(slider);
98   // enum may have 32bit storage
99   m_cargo_type= (Plugin_gcs_message::enum_cargo_type)
100       s_cargo_type;
101   slider += WIRE_CARGO_TYPE_SIZE;
102 
103   decode_payload(slider, end);
104 
105   DBUG_VOID_RETURN;
106 }
107 
108 Plugin_gcs_message::enum_cargo_type
get_cargo_type(const unsigned char * buffer)109 Plugin_gcs_message::get_cargo_type(const unsigned char* buffer)
110 {
111   DBUG_ENTER("Plugin_gcs_message::decode");
112   const unsigned char *slider= buffer +
113                                WIRE_VERSION_SIZE +
114                                WIRE_HD_LEN_SIZE +
115                                WIRE_MSG_LEN_SIZE;
116 
117   unsigned short s_cargo_type= 0;
118   s_cargo_type= uint2korr(slider);
119   // enum may have 32bit storage
120   Plugin_gcs_message::enum_cargo_type cargo_type=
121     (Plugin_gcs_message::enum_cargo_type) s_cargo_type;
122 
123   DBUG_RETURN(cargo_type);
124 }
125 
126 void
get_first_payload_item_raw_data(const unsigned char * buffer,const unsigned char ** payload_item_data,uint64 * payload_item_length)127 Plugin_gcs_message::get_first_payload_item_raw_data(const unsigned char* buffer,
128                                                     const unsigned char** payload_item_data,
129                                                     uint64* payload_item_length)
130 {
131   DBUG_ENTER("Plugin_gcs_message::get_first_payload_item_raw_data");
132   const unsigned char *slider= buffer +
133                                WIRE_FIXED_HEADER_SIZE +
134                                WIRE_PAYLOAD_ITEM_TYPE_SIZE;
135 
136   *payload_item_length= uint8korr(slider);
137   slider += WIRE_PAYLOAD_ITEM_LEN_SIZE;
138   *payload_item_data= slider;
139 
140   DBUG_VOID_RETURN;
141 }
142 
143 void
encode_payload_item_type_and_length(std::vector<unsigned char> * buffer,uint16 payload_item_type,unsigned long long payload_item_length) const144 Plugin_gcs_message::encode_payload_item_type_and_length(std::vector<unsigned char>* buffer,
145                                                         uint16 payload_item_type,
146                                                         unsigned long long payload_item_length)
147                                                         const
148 {
149   DBUG_ENTER("Plugin_gcs_message::encode_payload_item_type_and_length");
150   unsigned char buf[WIRE_PAYLOAD_ITEM_HEADER_SIZE];
151   unsigned char* slider= buf;
152 
153   int2store(slider, payload_item_type);
154   slider += WIRE_PAYLOAD_ITEM_TYPE_SIZE;
155 
156   int8store(slider, payload_item_length);
157   slider += WIRE_PAYLOAD_ITEM_LEN_SIZE;
158 
159   buffer->insert(buffer->end(), buf, buf + WIRE_PAYLOAD_ITEM_HEADER_SIZE);
160 
161   DBUG_VOID_RETURN;
162 }
163 
164 void
decode_payload_item_type_and_length(const unsigned char ** buffer,uint16 * payload_item_type,unsigned long long * payload_item_length)165 Plugin_gcs_message::decode_payload_item_type_and_length(const unsigned char** buffer,
166                                                         uint16* payload_item_type,
167                                                         unsigned long long* payload_item_length)
168 {
169   DBUG_ENTER("Plugin_gcs_message::decode_payload_item_type_and_length");
170 
171   *payload_item_type= uint2korr(*buffer);
172   *buffer += WIRE_PAYLOAD_ITEM_TYPE_SIZE;
173 
174   *payload_item_length= uint8korr(*buffer);
175   *buffer += WIRE_PAYLOAD_ITEM_LEN_SIZE;
176 
177   DBUG_VOID_RETURN;
178 }
179 
180 void
encode_payload_item_char(std::vector<unsigned char> * buffer,uint16 type,unsigned char value) const181 Plugin_gcs_message::encode_payload_item_char(std::vector<unsigned char>* buffer,
182                                              uint16 type,
183                                              unsigned char value)
184                                              const
185 {
186   DBUG_ENTER("Plugin_gcs_message::encode_payload_item_char");
187   unsigned char buf[1];
188 
189   encode_payload_item_type_and_length(buffer, type, 1);
190   buf[0]= value;
191   buffer->insert(buffer->end(), buf, buf + 1);
192 
193   DBUG_VOID_RETURN;
194 }
195 
196 void
decode_payload_item_char(const unsigned char ** buffer,uint16 * type,unsigned char * value)197 Plugin_gcs_message::decode_payload_item_char(const unsigned char** buffer,
198                                              uint16* type,
199                                              unsigned char* value)
200 {
201   DBUG_ENTER("Plugin_gcs_message::decode_payload_item_char");
202 
203   unsigned long long length= 0;
204   decode_payload_item_type_and_length(buffer, type, &length);
205   *value= **buffer;
206   *buffer += 1;
207 
208   DBUG_VOID_RETURN;
209 }
210 
211 void
encode_payload_item_int2(std::vector<unsigned char> * buffer,uint16 type,uint16 value) const212 Plugin_gcs_message::encode_payload_item_int2(std::vector<unsigned char>* buffer,
213                                              uint16 type,
214                                              uint16 value)
215                                              const
216 {
217   DBUG_ENTER("Plugin_gcs_message::encode_payload_item_int2");
218   unsigned char buf[2];
219 
220   encode_payload_item_type_and_length(buffer, type, 2);
221   int2store(buf, value);
222   buffer->insert(buffer->end(), buf, buf + 2);
223 
224   DBUG_VOID_RETURN;
225 }
226 
227 void
decode_payload_item_int2(const unsigned char ** buffer,uint16 * type,uint16 * value)228 Plugin_gcs_message::decode_payload_item_int2(const unsigned char** buffer,
229                                              uint16* type,
230                                              uint16* value)
231 {
232   DBUG_ENTER("Plugin_gcs_message::decode_payload_item_int2");
233 
234   unsigned long long length= 0;
235   decode_payload_item_type_and_length(buffer, type, &length);
236   *value= uint2korr(*buffer);
237   *buffer += 2;
238 
239   DBUG_VOID_RETURN;
240 }
241 
242 void
encode_payload_item_int4(std::vector<unsigned char> * buffer,uint16 type,uint32 value) const243 Plugin_gcs_message::encode_payload_item_int4(std::vector<unsigned char>* buffer,
244                                              uint16 type,
245                                              uint32 value)
246                                              const
247 {
248   DBUG_ENTER("Plugin_gcs_message::encode_payload_item_int4");
249   unsigned char buf[4];
250 
251   encode_payload_item_type_and_length(buffer, type, 4);
252   int4store(buf, value);
253   buffer->insert(buffer->end(), buf, buf + 4);
254 
255   DBUG_VOID_RETURN;
256 }
257 
258 void
decode_payload_item_int4(const unsigned char ** buffer,uint16 * type,uint32 * value)259 Plugin_gcs_message::decode_payload_item_int4(const unsigned char** buffer,
260                                              uint16* type,
261                                              uint32* value)
262 {
263   DBUG_ENTER("Plugin_gcs_message::decode_payload_item_int4");
264 
265   unsigned long long length= 0;
266   decode_payload_item_type_and_length(buffer, type, &length);
267   *value= uint4korr(*buffer);
268   *buffer += 4;
269 
270   DBUG_VOID_RETURN;
271 }
272 
273 void
encode_payload_item_int8(std::vector<unsigned char> * buffer,uint16 type,ulonglong value) const274 Plugin_gcs_message::encode_payload_item_int8(std::vector<unsigned char>* buffer,
275                                              uint16 type,
276                                              ulonglong value)
277                                              const
278 {
279   DBUG_ENTER("Plugin_gcs_message::encode_payload_item_int8");
280   unsigned char buf[8];
281 
282   encode_payload_item_type_and_length(buffer, type, 8);
283   int8store(buf, value);
284   buffer->insert(buffer->end(), buf, buf + 8);
285 
286   DBUG_VOID_RETURN;
287 }
288 
289 void
decode_payload_item_int8(const unsigned char ** buffer,uint16 * type,ulonglong * value)290 Plugin_gcs_message::decode_payload_item_int8(const unsigned char** buffer,
291                                              uint16* type,
292                                              ulonglong* value)
293 {
294   DBUG_ENTER("Plugin_gcs_message::decode_payload_item_int8");
295 
296   unsigned long long length= 0;
297   decode_payload_item_type_and_length(buffer, type, &length);
298   *value= uint8korr(*buffer);
299   *buffer += 8;
300 
301   DBUG_VOID_RETURN;
302 }
303 
304 void
encode_payload_item_string(std::vector<unsigned char> * buffer,uint16 type,const char * value,unsigned long long length) const305 Plugin_gcs_message::encode_payload_item_string(std::vector<unsigned char>* buffer,
306                                                uint16 type,
307                                                const char* value,
308                                                unsigned long long length)
309                                                const
310 {
311   DBUG_ENTER("Plugin_gcs_message::encode_payload_item_string");
312 
313   encode_payload_item_type_and_length(buffer, type, length);
314   buffer->insert(buffer->end(), value, value + length);
315 
316   DBUG_VOID_RETURN;
317 }
318 
319 void
decode_payload_item_string(const unsigned char ** buffer,uint16 * type,std::string * value,unsigned long long * length)320 Plugin_gcs_message::decode_payload_item_string(const unsigned char** buffer,
321                                                uint16* type,
322                                                std::string* value,
323                                                unsigned long long* length)
324 {
325   DBUG_ENTER("Plugin_gcs_message::decode_payload_item_string");
326 
327   decode_payload_item_type_and_length(buffer, type, length);
328   value->assign(reinterpret_cast<const char*>(*buffer), (size_t)*length);
329   *buffer += *length;
330 
331   DBUG_VOID_RETURN;
332 }
333