1 /* $NetBSD: event_tagging.c,v 1.3 2015/01/29 07:26:02 spz Exp $ */
2 /*
3 * Copyright (c) 2003-2009 Niels Provos <provos@citi.umich.edu>
4 * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "event2/event-config.h"
30 #include <sys/cdefs.h>
31 __RCSID("$NetBSD: event_tagging.c,v 1.3 2015/01/29 07:26:02 spz Exp $");
32
33 #ifdef _EVENT_HAVE_SYS_TYPES_H
34 #include <sys/types.h>
35 #endif
36 #ifdef _EVENT_HAVE_SYS_PARAM_H
37 #include <sys/param.h>
38 #endif
39
40 #ifdef WIN32
41 #define WIN32_LEAN_AND_MEAN
42 #include <winsock2.h>
43 #include <windows.h>
44 #undef WIN32_LEAN_AND_MEAN
45 #else
46 #include <sys/ioctl.h>
47 #endif
48
49 #include <sys/queue.h>
50 #ifdef _EVENT_HAVE_SYS_TIME_H
51 #include <sys/time.h>
52 #endif
53
54 #include <errno.h>
55 #include <stdio.h>
56 #include <stdlib.h>
57 #include <string.h>
58 #ifndef WIN32
59 #include <syslog.h>
60 #endif
61 #ifdef _EVENT_HAVE_UNISTD_H
62 #include <unistd.h>
63 #endif
64 #include <limits.h>
65
66 #include "event2/event.h"
67 #include "event2/tag.h"
68 #include "event2/buffer.h"
69 #include "log-internal.h"
70 #include "mm-internal.h"
71 #include "util-internal.h"
72
73 /*
74 Here's our wire format:
75
76 Stream = TaggedData*
77
78 TaggedData = Tag Length Data
79 where the integer value of 'Length' is the length of 'data'.
80
81 Tag = HByte* LByte
82 where HByte is a byte with the high bit set, and LByte is a byte
83 with the high bit clear. The integer value of the tag is taken
84 by concatenating the lower 7 bits from all the tags. So for example,
85 the tag 0x66 is encoded as [66], whereas the tag 0x166 is encoded as
86 [82 66]
87
88 Length = Integer
89
90 Integer = NNibbles Nibble* Padding?
91 where NNibbles is a 4-bit value encoding the number of nibbles-1,
92 and each Nibble is 4 bits worth of encoded integer, in big-endian
93 order. If the total encoded integer size is an odd number of nibbles,
94 a final padding nibble with value 0 is appended.
95 */
96
97 int evtag_decode_int(ev_uint32_t *pnumber, struct evbuffer *evbuf);
98 int evtag_decode_int64(ev_uint64_t *pnumber, struct evbuffer *evbuf);
99 int evtag_encode_tag(struct evbuffer *evbuf, ev_uint32_t tag);
100 int evtag_decode_tag(ev_uint32_t *ptag, struct evbuffer *evbuf);
101
102 void
evtag_init(void)103 evtag_init(void)
104 {
105 }
106
107 /*
108 * We encode integers by nibbles; the first nibble contains the number
109 * of significant nibbles - 1; this allows us to encode up to 64-bit
110 * integers. This function is byte-order independent.
111 *
112 * @param number a 32-bit unsigned integer to encode
113 * @param data a pointer to where the data should be written. Must
114 * have at least 5 bytes free.
115 * @return the number of bytes written into data.
116 */
117
118 #define ENCODE_INT_INTERNAL(data, number) do { \
119 int off = 1, nibbles = 0; \
120 \
121 memset(data, 0, sizeof(number)+1); \
122 while (number) { \
123 if (off & 0x1) \
124 data[off/2] = (data[off/2] & 0xf0) | (number & 0x0f); \
125 else \
126 data[off/2] = (data[off/2] & 0x0f) | \
127 ((number & 0x0f) << 4); \
128 number >>= 4; \
129 off++; \
130 } \
131 \
132 if (off > 2) \
133 nibbles = off - 2; \
134 \
135 /* Off - 1 is the number of encoded nibbles */ \
136 data[0] = (data[0] & 0x0f) | ((nibbles & 0x0f) << 4); \
137 \
138 return ((off + 1) / 2); \
139 } while (/*CONSTCOND*/0)
140
141 static inline int
encode_int_internal(ev_uint8_t * data,ev_uint32_t number)142 encode_int_internal(ev_uint8_t *data, ev_uint32_t number)
143 {
144 ENCODE_INT_INTERNAL(data, number);
145 }
146
147 static inline int
encode_int64_internal(ev_uint8_t * data,ev_uint64_t number)148 encode_int64_internal(ev_uint8_t *data, ev_uint64_t number)
149 {
150 ENCODE_INT_INTERNAL(data, number);
151 }
152
153 void
evtag_encode_int(struct evbuffer * evbuf,ev_uint32_t number)154 evtag_encode_int(struct evbuffer *evbuf, ev_uint32_t number)
155 {
156 ev_uint8_t data[5];
157 int len = encode_int_internal(data, number);
158 evbuffer_add(evbuf, data, len);
159 }
160
161 void
evtag_encode_int64(struct evbuffer * evbuf,ev_uint64_t number)162 evtag_encode_int64(struct evbuffer *evbuf, ev_uint64_t number)
163 {
164 ev_uint8_t data[9];
165 int len = encode_int64_internal(data, number);
166 evbuffer_add(evbuf, data, len);
167 }
168
169 /*
170 * Support variable length encoding of tags; we use the high bit in each
171 * octet as a continuation signal.
172 */
173
174 int
evtag_encode_tag(struct evbuffer * evbuf,ev_uint32_t tag)175 evtag_encode_tag(struct evbuffer *evbuf, ev_uint32_t tag)
176 {
177 int bytes = 0;
178 ev_uint8_t data[5];
179
180 memset(data, 0, sizeof(data));
181 do {
182 ev_uint8_t lower = tag & 0x7f;
183 tag >>= 7;
184
185 if (tag)
186 lower |= 0x80;
187
188 data[bytes++] = lower;
189 } while (tag);
190
191 if (evbuf != NULL)
192 evbuffer_add(evbuf, data, bytes);
193
194 return (bytes);
195 }
196
197 static int
decode_tag_internal(ev_uint32_t * ptag,struct evbuffer * evbuf,int dodrain)198 decode_tag_internal(ev_uint32_t *ptag, struct evbuffer *evbuf, int dodrain)
199 {
200 ev_uint32_t number = 0;
201 size_t len = evbuffer_get_length(evbuf);
202 ev_uint8_t *data;
203 size_t count = 0;
204 int shift = 0, done = 0;
205
206 /*
207 * the encoding of a number is at most one byte more than its
208 * storage size. however, it may also be much smaller.
209 */
210 data = evbuffer_pullup(
211 evbuf, len < sizeof(number) + 1 ? len : sizeof(number) + 1);
212 if (!data)
213 return (-1);
214
215 while (count++ < len) {
216 ev_uint8_t lower = *data++;
217 number |= (lower & 0x7f) << shift;
218 shift += 7;
219
220 if (!(lower & 0x80)) {
221 done = 1;
222 break;
223 }
224 }
225
226 if (!done)
227 return (-1);
228
229 if (dodrain)
230 evbuffer_drain(evbuf, count);
231
232 if (ptag != NULL)
233 *ptag = number;
234
235 return count > INT_MAX ? INT_MAX : (int)(count);
236 }
237
238 int
evtag_decode_tag(ev_uint32_t * ptag,struct evbuffer * evbuf)239 evtag_decode_tag(ev_uint32_t *ptag, struct evbuffer *evbuf)
240 {
241 return (decode_tag_internal(ptag, evbuf, 1 /* dodrain */));
242 }
243
244 /*
245 * Marshal a data type, the general format is as follows:
246 *
247 * tag number: one byte; length: var bytes; payload: var bytes
248 */
249
250 void
evtag_marshal(struct evbuffer * evbuf,ev_uint32_t tag,const void * data,ev_uint32_t len)251 evtag_marshal(struct evbuffer *evbuf, ev_uint32_t tag,
252 const void *data, ev_uint32_t len)
253 {
254 evtag_encode_tag(evbuf, tag);
255 evtag_encode_int(evbuf, len);
256 evbuffer_add(evbuf, __UNCONST(data), len);
257 }
258
259 void
evtag_marshal_buffer(struct evbuffer * evbuf,ev_uint32_t tag,struct evbuffer * data)260 evtag_marshal_buffer(struct evbuffer *evbuf, ev_uint32_t tag,
261 struct evbuffer *data)
262 {
263 evtag_encode_tag(evbuf, tag);
264 /* XXX support more than UINT32_MAX data */
265 evtag_encode_int(evbuf, (ev_uint32_t)evbuffer_get_length(data));
266 evbuffer_add_buffer(evbuf, data);
267 }
268
269 /* Marshaling for integers */
270 void
evtag_marshal_int(struct evbuffer * evbuf,ev_uint32_t tag,ev_uint32_t integer)271 evtag_marshal_int(struct evbuffer *evbuf, ev_uint32_t tag, ev_uint32_t integer)
272 {
273 ev_uint8_t data[5];
274 int len = encode_int_internal(data, integer);
275
276 evtag_encode_tag(evbuf, tag);
277 evtag_encode_int(evbuf, len);
278 evbuffer_add(evbuf, data, len);
279 }
280
281 void
evtag_marshal_int64(struct evbuffer * evbuf,ev_uint32_t tag,ev_uint64_t integer)282 evtag_marshal_int64(struct evbuffer *evbuf, ev_uint32_t tag,
283 ev_uint64_t integer)
284 {
285 ev_uint8_t data[9];
286 int len = encode_int64_internal(data, integer);
287
288 evtag_encode_tag(evbuf, tag);
289 evtag_encode_int(evbuf, len);
290 evbuffer_add(evbuf, data, len);
291 }
292
293 void
evtag_marshal_string(struct evbuffer * buf,ev_uint32_t tag,const char * string)294 evtag_marshal_string(struct evbuffer *buf, ev_uint32_t tag, const char *string)
295 {
296 /* TODO support strings longer than UINT32_MAX ? */
297 evtag_marshal(buf, tag, string, (ev_uint32_t)strlen(string));
298 }
299
300 void
evtag_marshal_timeval(struct evbuffer * evbuf,ev_uint32_t tag,struct timeval * tv)301 evtag_marshal_timeval(struct evbuffer *evbuf, ev_uint32_t tag, struct timeval *tv)
302 {
303 ev_uint8_t data[10];
304 int len = encode_int_internal(data, tv->tv_sec);
305 len += encode_int_internal(data + len, tv->tv_usec);
306 evtag_marshal(evbuf, tag, data, len);
307 }
308
309 #define DECODE_INT_INTERNAL(number, maxnibbles, pnumber, evbuf, offset) \
310 do { \
311 ev_uint8_t *data; \
312 ev_ssize_t len = evbuffer_get_length(evbuf) - offset; \
313 int nibbles = 0; \
314 \
315 if (len <= 0) \
316 return (-1); \
317 \
318 /* XXX(niels): faster? */ \
319 data = evbuffer_pullup(evbuf, offset + 1) + offset; \
320 if (!data) \
321 return (-1); \
322 \
323 nibbles = ((data[0] & 0xf0) >> 4) + 1; \
324 if (nibbles > maxnibbles || (nibbles >> 1) + 1 > len) \
325 return (-1); \
326 len = (nibbles >> 1) + 1; \
327 \
328 data = evbuffer_pullup(evbuf, offset + len) + offset; \
329 if (!data) \
330 return (-1); \
331 \
332 while (nibbles > 0) { \
333 number <<= 4; \
334 if (nibbles & 0x1) \
335 number |= data[nibbles >> 1] & 0x0f; \
336 else \
337 number |= (data[nibbles >> 1] & 0xf0) >> 4; \
338 nibbles--; \
339 } \
340 \
341 *pnumber = number; \
342 \
343 return (int)(len); \
344 } while (/*CONSTCOND*/0)
345
346 /* Internal: decode an integer from an evbuffer, without draining it.
347 * Only integers up to 32-bits are supported.
348 *
349 * @param evbuf the buffer to read from
350 * @param offset an index into the buffer at which we should start reading.
351 * @param pnumber a pointer to receive the integer.
352 * @return The length of the number as encoded, or -1 on error.
353 */
354
355 static int
decode_int_internal(ev_uint32_t * pnumber,struct evbuffer * evbuf,int offset)356 decode_int_internal(ev_uint32_t *pnumber, struct evbuffer *evbuf, int offset)
357 {
358 ev_uint32_t number = 0;
359 DECODE_INT_INTERNAL(number, 8, pnumber, evbuf, offset);
360 }
361
362 static int
decode_int64_internal(ev_uint64_t * pnumber,struct evbuffer * evbuf,int offset)363 decode_int64_internal(ev_uint64_t *pnumber, struct evbuffer *evbuf, int offset)
364 {
365 ev_uint64_t number = 0;
366 DECODE_INT_INTERNAL(number, 16, pnumber, evbuf, offset);
367 }
368
369 int
evtag_decode_int(ev_uint32_t * pnumber,struct evbuffer * evbuf)370 evtag_decode_int(ev_uint32_t *pnumber, struct evbuffer *evbuf)
371 {
372 int res = decode_int_internal(pnumber, evbuf, 0);
373 if (res != -1)
374 evbuffer_drain(evbuf, res);
375
376 return (res == -1 ? -1 : 0);
377 }
378
379 int
evtag_decode_int64(ev_uint64_t * pnumber,struct evbuffer * evbuf)380 evtag_decode_int64(ev_uint64_t *pnumber, struct evbuffer *evbuf)
381 {
382 int res = decode_int64_internal(pnumber, evbuf, 0);
383 if (res != -1)
384 evbuffer_drain(evbuf, res);
385
386 return (res == -1 ? -1 : 0);
387 }
388
389 int
evtag_peek(struct evbuffer * evbuf,ev_uint32_t * ptag)390 evtag_peek(struct evbuffer *evbuf, ev_uint32_t *ptag)
391 {
392 return (decode_tag_internal(ptag, evbuf, 0 /* dodrain */));
393 }
394
395 int
evtag_peek_length(struct evbuffer * evbuf,ev_uint32_t * plength)396 evtag_peek_length(struct evbuffer *evbuf, ev_uint32_t *plength)
397 {
398 int res, len;
399
400 len = decode_tag_internal(NULL, evbuf, 0 /* dodrain */);
401 if (len == -1)
402 return (-1);
403
404 res = decode_int_internal(plength, evbuf, len);
405 if (res == -1)
406 return (-1);
407
408 *plength += res + len;
409
410 return (0);
411 }
412
413 int
evtag_payload_length(struct evbuffer * evbuf,ev_uint32_t * plength)414 evtag_payload_length(struct evbuffer *evbuf, ev_uint32_t *plength)
415 {
416 int res, len;
417
418 len = decode_tag_internal(NULL, evbuf, 0 /* dodrain */);
419 if (len == -1)
420 return (-1);
421
422 res = decode_int_internal(plength, evbuf, len);
423 if (res == -1)
424 return (-1);
425
426 return (0);
427 }
428
429 /* just unmarshals the header and returns the length of the remaining data */
430
431 int
evtag_unmarshal_header(struct evbuffer * evbuf,ev_uint32_t * ptag)432 evtag_unmarshal_header(struct evbuffer *evbuf, ev_uint32_t *ptag)
433 {
434 ev_uint32_t len;
435
436 if (decode_tag_internal(ptag, evbuf, 1 /* dodrain */) == -1)
437 return (-1);
438 if (evtag_decode_int(&len, evbuf) == -1)
439 return (-1);
440
441 if (evbuffer_get_length(evbuf) < len)
442 return (-1);
443
444 return (len);
445 }
446
447 int
evtag_consume(struct evbuffer * evbuf)448 evtag_consume(struct evbuffer *evbuf)
449 {
450 int len;
451 if ((len = evtag_unmarshal_header(evbuf, NULL)) == -1)
452 return (-1);
453 evbuffer_drain(evbuf, len);
454
455 return (0);
456 }
457
458 /* Reads the data type from an event buffer */
459
460 int
evtag_unmarshal(struct evbuffer * src,ev_uint32_t * ptag,struct evbuffer * dst)461 evtag_unmarshal(struct evbuffer *src, ev_uint32_t *ptag, struct evbuffer *dst)
462 {
463 int len;
464
465 if ((len = evtag_unmarshal_header(src, ptag)) == -1)
466 return (-1);
467
468 if (evbuffer_add(dst, evbuffer_pullup(src, len), len) == -1)
469 return (-1);
470
471 evbuffer_drain(src, len);
472
473 return (len);
474 }
475
476 /* Marshaling for integers */
477
478 int
evtag_unmarshal_int(struct evbuffer * evbuf,ev_uint32_t need_tag,ev_uint32_t * pinteger)479 evtag_unmarshal_int(struct evbuffer *evbuf, ev_uint32_t need_tag,
480 ev_uint32_t *pinteger)
481 {
482 ev_uint32_t tag;
483 ev_uint32_t len;
484 int result;
485
486 if (decode_tag_internal(&tag, evbuf, 1 /* dodrain */) == -1)
487 return (-1);
488 if (need_tag != tag)
489 return (-1);
490 if (evtag_decode_int(&len, evbuf) == -1)
491 return (-1);
492
493 if (evbuffer_get_length(evbuf) < len)
494 return (-1);
495
496 result = decode_int_internal(pinteger, evbuf, 0);
497 evbuffer_drain(evbuf, len);
498 if (result < 0 || (size_t)result > len) /* XXX Should this be != rather than > ?*/
499 return (-1);
500 else
501 return result;
502 }
503
504 int
evtag_unmarshal_int64(struct evbuffer * evbuf,ev_uint32_t need_tag,ev_uint64_t * pinteger)505 evtag_unmarshal_int64(struct evbuffer *evbuf, ev_uint32_t need_tag,
506 ev_uint64_t *pinteger)
507 {
508 ev_uint32_t tag;
509 ev_uint32_t len;
510 int result;
511
512 if (decode_tag_internal(&tag, evbuf, 1 /* dodrain */) == -1)
513 return (-1);
514 if (need_tag != tag)
515 return (-1);
516 if (evtag_decode_int(&len, evbuf) == -1)
517 return (-1);
518
519 if (evbuffer_get_length(evbuf) < len)
520 return (-1);
521
522 result = decode_int64_internal(pinteger, evbuf, 0);
523 evbuffer_drain(evbuf, len);
524 if (result < 0 || (size_t)result > len) /* XXX Should this be != rather than > ?*/
525 return (-1);
526 else
527 return result;
528 }
529
530 /* Unmarshal a fixed length tag */
531
532 int
evtag_unmarshal_fixed(struct evbuffer * src,ev_uint32_t need_tag,void * data,size_t len)533 evtag_unmarshal_fixed(struct evbuffer *src, ev_uint32_t need_tag, void *data,
534 size_t len)
535 {
536 ev_uint32_t tag;
537 int tag_len;
538
539 /* Now unmarshal a tag and check that it matches the tag we want */
540 if ((tag_len = evtag_unmarshal_header(src, &tag)) < 0 ||
541 tag != need_tag)
542 return (-1);
543
544 if ((size_t)tag_len != len)
545 return (-1);
546
547 evbuffer_remove(src, data, len);
548 return (0);
549 }
550
551 int
evtag_unmarshal_string(struct evbuffer * evbuf,ev_uint32_t need_tag,char ** pstring)552 evtag_unmarshal_string(struct evbuffer *evbuf, ev_uint32_t need_tag,
553 char **pstring)
554 {
555 ev_uint32_t tag;
556 int tag_len;
557
558 if ((tag_len = evtag_unmarshal_header(evbuf, &tag)) == -1 ||
559 tag != need_tag)
560 return (-1);
561
562 *pstring = mm_malloc(tag_len + 1);
563 if (*pstring == NULL) {
564 event_warn("%s: malloc", __func__);
565 return -1;
566 }
567 evbuffer_remove(evbuf, *pstring, tag_len);
568 (*pstring)[tag_len] = '\0';
569
570 return (0);
571 }
572
573 int
evtag_unmarshal_timeval(struct evbuffer * evbuf,ev_uint32_t need_tag,struct timeval * ptv)574 evtag_unmarshal_timeval(struct evbuffer *evbuf, ev_uint32_t need_tag,
575 struct timeval *ptv)
576 {
577 ev_uint32_t tag;
578 ev_uint32_t integer;
579 int len, offset, offset2;
580 int result = -1;
581
582 if ((len = evtag_unmarshal_header(evbuf, &tag)) == -1)
583 return (-1);
584 if (tag != need_tag)
585 goto done;
586 if ((offset = decode_int_internal(&integer, evbuf, 0)) == -1)
587 goto done;
588 ptv->tv_sec = integer;
589 if ((offset2 = decode_int_internal(&integer, evbuf, offset)) == -1)
590 goto done;
591 ptv->tv_usec = integer;
592 if (offset + offset2 > len) /* XXX Should this be != instead of > ? */
593 goto done;
594
595 result = 0;
596 done:
597 evbuffer_drain(evbuf, len);
598 return result;
599 }
600