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