fix: net: udp: add IP/port data to the tracepoint udp/udp_fail_queue_rcv_skb (v6.10)
[lttng-modules.git] / src / lib / msgpack / msgpack.c
1 /*
2 * msgpack.c
3 *
4 * Copyright (C) 2020 Francis Deslauriers <francis.deslauriers@efficios.com>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; only
9 * version 2.1 of the License.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #define _GNU_SOURCE
22 #define _LGPL_SOURCE
23
24 #define MSGPACK_FIXSTR_ID_MASK 0xA0
25 #define MSGPACK_FIXMAP_ID_MASK 0x80
26 #define MSGPACK_FIXARRAY_ID_MASK 0x90
27
28 #define MSGPACK_NIL_ID 0xC0
29 #define MSGPACK_FALSE_ID 0xC2
30 #define MSGPACK_TRUE_ID 0xC3
31 #define MSGPACK_MAP16_ID 0xDE
32 #define MSGPACK_ARRAY16_ID 0xDC
33
34 #define MSGPACK_UINT8_ID 0xCC
35 #define MSGPACK_UINT16_ID 0xCD
36 #define MSGPACK_UINT32_ID 0xCE
37 #define MSGPACK_UINT64_ID 0xCF
38
39 #define MSGPACK_INT8_ID 0xD0
40 #define MSGPACK_INT16_ID 0xD1
41 #define MSGPACK_INT32_ID 0xD2
42 #define MSGPACK_INT64_ID 0xD3
43
44 #define MSGPACK_FLOAT64_ID 0xCB
45 #define MSGPACK_STR16_ID 0xDA
46
47 #define MSGPACK_FIXINT_MAX ((1 << 7) - 1)
48 #define MSGPACK_FIXINT_MIN -(1 << 5)
49 #define MSGPACK_FIXMAP_MAX_COUNT 15
50 #define MSGPACK_FIXARRAY_MAX_COUNT 15
51 #define MSGPACK_FIXSTR_MAX_LENGTH 31
52
53 #ifdef __KERNEL__
54 #include <linux/bug.h>
55 #include <linux/string.h>
56 #include <linux/types.h>
57 #include <asm/byteorder.h>
58
59 #include <lttng/msgpack.h>
60 #include <lttng/probe-user.h>
61
62 #define INT8_MIN (-128)
63 #define INT16_MIN (-32767-1)
64 #define INT32_MIN (-2147483647-1)
65 #define INT8_MAX (127)
66 #define INT16_MAX (32767)
67 #define INT32_MAX (2147483647)
68 #define UINT8_MAX (255)
69 #define UINT16_MAX (65535)
70 #define UINT32_MAX (4294967295U)
71
72 #define byteswap_host_to_be16(_tmp) cpu_to_be16(_tmp)
73 #define byteswap_host_to_be32(_tmp) cpu_to_be32(_tmp)
74 #define byteswap_host_to_be64(_tmp) cpu_to_be64(_tmp)
75
76 #define lttng_msgpack_assert(cond) WARN_ON(!(cond))
77
78 #else /* __KERNEL__ */
79
80 #include <endian.h>
81 #include <stdio.h>
82 #include <string.h>
83
84 #include "msgpack.h"
85
86 #define byteswap_host_to_be16(_tmp) htobe16(_tmp)
87 #define byteswap_host_to_be32(_tmp) htobe32(_tmp)
88 #define byteswap_host_to_be64(_tmp) htobe64(_tmp)
89
90 #define lttng_msgpack_assert(cond) ({ \
91 if (!(cond)) \
92 fprintf(stderr, "Assertion failed. %s:%d\n", __FILE__, __LINE__); \
93 })
94 #endif /* __KERNEL__ */
95
96 static inline int lttng_msgpack_append_buffer(
97 struct lttng_msgpack_writer *writer,
98 const uint8_t *buf,
99 size_t length)
100 {
101 int ret = 0;
102
103 lttng_msgpack_assert(buf);
104
105 /* Ensure we are not trying to write after the end of the buffer. */
106 if (writer->write_pos + length > writer->end_write_pos) {
107 ret = -1;
108 goto end;
109 }
110
111 memcpy(writer->write_pos, buf, length);
112 writer->write_pos += length;
113 end:
114 return ret;
115 }
116
117 static inline int lttng_msgpack_append_user_buffer(
118 struct lttng_msgpack_writer *writer,
119 const uint8_t __user *ubuf,
120 size_t length)
121 {
122 int ret = 0;
123
124 lttng_msgpack_assert(ubuf);
125
126 /* Ensure we are not trying to write after the end of the buffer. */
127 if (writer->write_pos + length > writer->end_write_pos) {
128 ret = -1;
129 goto end;
130 }
131
132 if (lttng_copy_from_user_check_nofault(writer->write_pos, ubuf, length)) {
133 ret = -1;
134 goto end;
135 }
136 writer->write_pos += length;
137 end:
138 return ret;
139 }
140
141 static inline int lttng_msgpack_append_u8(
142 struct lttng_msgpack_writer *writer, uint8_t value)
143 {
144 return lttng_msgpack_append_buffer(writer, &value, sizeof(value));
145 }
146
147 static inline int lttng_msgpack_append_u16(
148 struct lttng_msgpack_writer *writer, uint16_t value)
149 {
150 value = byteswap_host_to_be16(value);
151
152 return lttng_msgpack_append_buffer(writer, (uint8_t *) &value, sizeof(value));
153 }
154
155 static inline int lttng_msgpack_append_u32(
156 struct lttng_msgpack_writer *writer, uint32_t value)
157 {
158 value = byteswap_host_to_be32(value);
159
160 return lttng_msgpack_append_buffer(writer, (uint8_t *) &value, sizeof(value));
161 }
162
163 static inline int lttng_msgpack_append_u64(
164 struct lttng_msgpack_writer *writer, uint64_t value)
165 {
166 value = byteswap_host_to_be64(value);
167
168 return lttng_msgpack_append_buffer(writer, (uint8_t *) &value, sizeof(value));
169 }
170
171 static inline int lttng_msgpack_append_i8(
172 struct lttng_msgpack_writer *writer, int8_t value)
173 {
174 return lttng_msgpack_append_u8(writer, (uint8_t) value);
175 }
176
177 static inline int lttng_msgpack_append_i16(
178 struct lttng_msgpack_writer *writer, int16_t value)
179 {
180 return lttng_msgpack_append_u16(writer, (uint16_t) value);
181 }
182
183 static inline int lttng_msgpack_append_i32(
184 struct lttng_msgpack_writer *writer, int32_t value)
185 {
186 return lttng_msgpack_append_u32(writer, (uint32_t) value);
187 }
188
189 static inline int lttng_msgpack_append_i64(
190 struct lttng_msgpack_writer *writer, int64_t value)
191 {
192 return lttng_msgpack_append_u64(writer, (uint64_t) value);
193 }
194
195 static inline int lttng_msgpack_encode_fixmap(
196 struct lttng_msgpack_writer *writer, uint8_t count)
197 {
198 int ret = 0;
199
200 lttng_msgpack_assert(count <= MSGPACK_FIXMAP_MAX_COUNT);
201
202 ret = lttng_msgpack_append_u8(writer, MSGPACK_FIXMAP_ID_MASK | count);
203 if (ret)
204 goto end;
205
206 end:
207 return ret;
208 }
209
210 static inline int lttng_msgpack_encode_map16(
211 struct lttng_msgpack_writer *writer, uint16_t count)
212 {
213 int ret;
214
215 lttng_msgpack_assert(count > MSGPACK_FIXMAP_MAX_COUNT);
216
217 ret = lttng_msgpack_append_u8(writer, MSGPACK_MAP16_ID);
218 if (ret)
219 goto end;
220
221 ret = lttng_msgpack_append_u16(writer, count);
222 if (ret)
223 goto end;
224
225 end:
226 return ret;
227 }
228
229 static inline int lttng_msgpack_encode_fixarray(
230 struct lttng_msgpack_writer *writer, uint8_t count)
231 {
232 int ret = 0;
233
234 lttng_msgpack_assert(count <= MSGPACK_FIXARRAY_MAX_COUNT);
235
236 ret = lttng_msgpack_append_u8(writer, MSGPACK_FIXARRAY_ID_MASK | count);
237 if (ret)
238 goto end;
239
240 end:
241 return ret;
242 }
243
244 static inline int lttng_msgpack_encode_array16(
245 struct lttng_msgpack_writer *writer, uint16_t count)
246 {
247 int ret;
248
249 lttng_msgpack_assert(count > MSGPACK_FIXARRAY_MAX_COUNT);
250
251 ret = lttng_msgpack_append_u8(writer, MSGPACK_ARRAY16_ID);
252 if (ret)
253 goto end;
254
255 ret = lttng_msgpack_append_u16(writer, count);
256 if (ret)
257 goto end;
258
259 end:
260 return ret;
261 }
262
263 static inline int lttng_msgpack_encode_fixstr(
264 struct lttng_msgpack_writer *writer,
265 const char *str,
266 uint8_t len)
267 {
268 int ret;
269
270 lttng_msgpack_assert(len <= MSGPACK_FIXSTR_MAX_LENGTH);
271
272 ret = lttng_msgpack_append_u8(writer, MSGPACK_FIXSTR_ID_MASK | len);
273 if (ret)
274 goto end;
275
276 ret = lttng_msgpack_append_buffer(writer, (uint8_t *) str, len);
277 if (ret)
278 goto end;
279
280 end:
281 return ret;
282 }
283
284 static inline int lttng_msgpack_encode_str16(
285 struct lttng_msgpack_writer *writer,
286 const char *str,
287 uint16_t len)
288 {
289 int ret;
290
291 lttng_msgpack_assert(len > MSGPACK_FIXSTR_MAX_LENGTH);
292
293 ret = lttng_msgpack_append_u8(writer, MSGPACK_STR16_ID);
294 if (ret)
295 goto end;
296
297 ret = lttng_msgpack_append_u16(writer, len);
298 if (ret)
299 goto end;
300
301 ret = lttng_msgpack_append_buffer(writer, (uint8_t *) str, len);
302 if (ret)
303 goto end;
304
305 end:
306 return ret;
307 }
308
309 static inline int lttng_msgpack_encode_user_fixstr(
310 struct lttng_msgpack_writer *writer,
311 const char __user *ustr,
312 uint8_t len)
313 {
314 int ret;
315
316 lttng_msgpack_assert(len <= MSGPACK_FIXSTR_MAX_LENGTH);
317
318 ret = lttng_msgpack_append_u8(writer, MSGPACK_FIXSTR_ID_MASK | len);
319 if (ret)
320 goto end;
321
322 ret = lttng_msgpack_append_user_buffer(writer, (uint8_t __user *) ustr, len);
323 if (ret)
324 goto end;
325
326 end:
327 return ret;
328 }
329
330 static inline int lttng_msgpack_encode_user_str16(
331 struct lttng_msgpack_writer *writer,
332 const char __user *ustr,
333 uint16_t len)
334 {
335 int ret;
336
337 lttng_msgpack_assert(len > MSGPACK_FIXSTR_MAX_LENGTH);
338
339 ret = lttng_msgpack_append_u8(writer, MSGPACK_STR16_ID);
340 if (ret)
341 goto end;
342
343 ret = lttng_msgpack_append_u16(writer, len);
344 if (ret)
345 goto end;
346
347 ret = lttng_msgpack_append_user_buffer(writer, (uint8_t __user *) ustr, len);
348 if (ret)
349 goto end;
350
351 end:
352 return ret;
353 }
354
355
356 int lttng_msgpack_begin_map(struct lttng_msgpack_writer *writer, size_t count)
357 {
358 int ret;
359
360 if (count >= (1 << 16)) {
361 ret = -1;
362 goto end;
363 }
364
365 if (count <= MSGPACK_FIXMAP_MAX_COUNT)
366 ret = lttng_msgpack_encode_fixmap(writer, count);
367 else
368 ret = lttng_msgpack_encode_map16(writer, count);
369
370 writer->map_nesting++;
371 end:
372 return ret;
373 }
374
375 int lttng_msgpack_end_map(struct lttng_msgpack_writer *writer)
376 {
377 lttng_msgpack_assert(writer->map_nesting > 0);
378 writer->map_nesting--;
379 return 0;
380 }
381
382 int lttng_msgpack_begin_array(
383 struct lttng_msgpack_writer *writer, size_t count)
384 {
385 int ret;
386
387 if (count >= (1 << 16)) {
388 ret = -1;
389 goto end;
390 }
391
392 if (count <= MSGPACK_FIXARRAY_MAX_COUNT)
393 ret = lttng_msgpack_encode_fixarray(writer, count);
394 else
395 ret = lttng_msgpack_encode_array16(writer, count);
396
397 writer->array_nesting++;
398 end:
399 return ret;
400 }
401
402 int lttng_msgpack_end_array(struct lttng_msgpack_writer *writer)
403 {
404 lttng_msgpack_assert(writer->array_nesting > 0);
405 writer->array_nesting--;
406 return 0;
407 }
408
409 int lttng_msgpack_write_str(struct lttng_msgpack_writer *writer,
410 const char *str)
411 {
412 int ret;
413 size_t length = strlen(str);
414
415 if (length >= (1 << 16)) {
416 ret = -1;
417 goto end;
418 }
419
420 if (length <= MSGPACK_FIXSTR_MAX_LENGTH)
421 ret = lttng_msgpack_encode_fixstr(writer, str, length);
422 else
423 ret = lttng_msgpack_encode_str16(writer, str, length);
424
425 end:
426 return ret;
427 }
428
429 /*
430 * Provide the same behavior on lttng_strlen_user_inatomic page fault as the
431 * lttng ring buffer: truncate the last string character.
432 */
433 int lttng_msgpack_write_user_str(struct lttng_msgpack_writer *writer,
434 const char __user *ustr)
435 {
436 int ret;
437 size_t length = max_t(size_t, lttng_strlen_user_inatomic(ustr), 1);
438
439 if (length >= (1 << 16)) {
440 ret = -1;
441 goto end;
442 }
443
444 if (length <= MSGPACK_FIXSTR_MAX_LENGTH)
445 ret = lttng_msgpack_encode_user_fixstr(writer, ustr, length);
446 else
447 ret = lttng_msgpack_encode_user_str16(writer, ustr, length);
448
449 end:
450 return ret;
451 }
452
453 int lttng_msgpack_write_nil(struct lttng_msgpack_writer *writer)
454 {
455 return lttng_msgpack_append_u8(writer, MSGPACK_NIL_ID);
456 }
457
458 int lttng_msgpack_write_true(struct lttng_msgpack_writer *writer)
459 {
460 return lttng_msgpack_append_u8(writer, MSGPACK_TRUE_ID);
461 }
462
463 int lttng_msgpack_write_false(struct lttng_msgpack_writer *writer)
464 {
465 return lttng_msgpack_append_u8(writer, MSGPACK_FALSE_ID);
466 }
467
468 int lttng_msgpack_write_unsigned_integer(
469 struct lttng_msgpack_writer *writer, uint64_t value)
470 {
471 int ret = 0;
472
473 if (value <= MSGPACK_FIXINT_MAX) {
474 ret = lttng_msgpack_append_u8(writer, (uint8_t) value);
475 if (ret)
476 goto end;
477 } else if (value <= UINT8_MAX) {
478 ret = lttng_msgpack_append_u8(writer, MSGPACK_UINT8_ID);
479 if (ret)
480 goto end;
481
482 ret = lttng_msgpack_append_u8(writer, (uint8_t) value);
483 if (ret)
484 goto end;
485 } else if (value <= UINT16_MAX) {
486 ret = lttng_msgpack_append_u8(writer, MSGPACK_UINT16_ID);
487 if (ret)
488 goto end;
489
490 ret = lttng_msgpack_append_u16(writer, (uint16_t) value);
491 if (ret)
492 goto end;
493 } else if (value <= UINT32_MAX) {
494 ret = lttng_msgpack_append_u8(writer, MSGPACK_UINT32_ID);
495 if (ret)
496 goto end;
497
498 ret = lttng_msgpack_append_u32(writer, (uint32_t) value);
499 if (ret)
500 goto end;
501 } else {
502 ret = lttng_msgpack_append_u8(writer, MSGPACK_UINT64_ID);
503 if (ret)
504 goto end;
505
506 ret = lttng_msgpack_append_u64(writer, value);
507 if (ret)
508 goto end;
509 }
510
511 end:
512 return ret;
513 }
514
515 int lttng_msgpack_write_signed_integer(struct lttng_msgpack_writer *writer, int64_t value)
516 {
517 int ret;
518
519 if (value >= MSGPACK_FIXINT_MIN && value <= MSGPACK_FIXINT_MAX){
520 ret = lttng_msgpack_append_i8(writer, (int8_t) value);
521 if (ret)
522 goto end;
523 } else if (value >= INT8_MIN && value <= INT8_MAX) {
524 ret = lttng_msgpack_append_u8(writer, MSGPACK_INT8_ID);
525 if (ret)
526 goto end;
527
528 ret = lttng_msgpack_append_i8(writer, (int8_t) value);
529 if (ret)
530 goto end;
531 } else if (value >= INT16_MIN && value <= INT16_MAX) {
532 ret = lttng_msgpack_append_u8(writer, MSGPACK_INT16_ID);
533 if (ret)
534 goto end;
535
536 ret = lttng_msgpack_append_i16(writer, (int16_t) value);
537 if (ret)
538 goto end;
539 } else if (value >= INT32_MIN && value <= INT32_MAX) {
540 ret = lttng_msgpack_append_u8(writer, MSGPACK_INT32_ID);
541 if (ret)
542 goto end;
543
544 ret = lttng_msgpack_append_i32(writer, (int32_t) value);
545 if (ret)
546 goto end;
547 } else {
548 ret = lttng_msgpack_append_u8(writer, MSGPACK_INT64_ID);
549 if (ret)
550 goto end;
551
552 ret = lttng_msgpack_append_i64(writer, value);
553 if (ret)
554 goto end;
555 }
556
557 end:
558 return ret;
559 }
560
561 int lttng_msgpack_save_writer_pos(struct lttng_msgpack_writer *writer, uint8_t **pos)
562 {
563 *pos = writer->write_pos;
564 return 0;
565 }
566
567 int lttng_msgpack_restore_writer_pos(struct lttng_msgpack_writer *writer, uint8_t *pos)
568 {
569 writer->write_pos = pos;
570 return 0;
571 }
572
573 void lttng_msgpack_writer_init(struct lttng_msgpack_writer *writer,
574 uint8_t *buffer, size_t size)
575 {
576 lttng_msgpack_assert(buffer);
577 lttng_msgpack_assert(size >= 0);
578
579 writer->buffer = buffer;
580 writer->write_pos = buffer;
581 writer->end_write_pos = buffer + size;
582
583 writer->array_nesting = 0;
584 writer->map_nesting = 0;
585 }
586
587 void lttng_msgpack_writer_fini(struct lttng_msgpack_writer *writer)
588 {
589 memset(writer, 0, sizeof(*writer));
590 }
This page took 0.040832 seconds and 5 git commands to generate.