event_tagging.c revision 1.3
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
97int evtag_decode_int(ev_uint32_t *pnumber, struct evbuffer *evbuf);
98int evtag_decode_int64(ev_uint64_t *pnumber, struct evbuffer *evbuf);
99int evtag_encode_tag(struct evbuffer *evbuf, ev_uint32_t tag);
100int evtag_decode_tag(ev_uint32_t *ptag, struct evbuffer *evbuf);
101
102void
103evtag_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
141static inline int
142encode_int_internal(ev_uint8_t *data, ev_uint32_t number)
143{
144	ENCODE_INT_INTERNAL(data, number);
145}
146
147static inline int
148encode_int64_internal(ev_uint8_t *data, ev_uint64_t number)
149{
150	ENCODE_INT_INTERNAL(data, number);
151}
152
153void
154evtag_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
161void
162evtag_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
174int
175evtag_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
197static int
198decode_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
238int
239evtag_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
250void
251evtag_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
259void
260evtag_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 */
270void
271evtag_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
281void
282evtag_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
293void
294evtag_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
300void
301evtag_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) \
310do {									\
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
355static int
356decode_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
362static int
363decode_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
369int
370evtag_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
379int
380evtag_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
389int
390evtag_peek(struct evbuffer *evbuf, ev_uint32_t *ptag)
391{
392	return (decode_tag_internal(ptag, evbuf, 0 /* dodrain */));
393}
394
395int
396evtag_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
413int
414evtag_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
431int
432evtag_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
447int
448evtag_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
460int
461evtag_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
478int
479evtag_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
504int
505evtag_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
532int
533evtag_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
551int
552evtag_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
573int
574evtag_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