1/*	$NetBSD: event_tagging.c,v 1.6 2020/05/25 20:47:33 christos Exp $	*/
2
3/*
4 * Copyright (c) 2003-2009 Niels Provos <provos@citi.umich.edu>
5 * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 *    derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include "event2/event-config.h"
31#include "evconfig-private.h"
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 (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		if (shift >= 28) {
218			/* Make sure it fits into 32 bits */
219			if (shift > 28)
220				return (-1);
221			if ((lower & 0x7f) > 15)
222				return (-1);
223		}
224		number |= (lower & (unsigned)0x7f) << shift;
225		shift += 7;
226
227		if (!(lower & 0x80)) {
228			done = 1;
229			break;
230		}
231	}
232
233	if (!done)
234		return (-1);
235
236	if (dodrain)
237		evbuffer_drain(evbuf, count);
238
239	if (ptag != NULL)
240		*ptag = number;
241
242	return count > INT_MAX ? INT_MAX : (int)(count);
243}
244
245int
246evtag_decode_tag(ev_uint32_t *ptag, struct evbuffer *evbuf)
247{
248	return (decode_tag_internal(ptag, evbuf, 1 /* dodrain */));
249}
250
251/*
252 * Marshal a data type, the general format is as follows:
253 *
254 * tag number: one byte; length: var bytes; payload: var bytes
255 */
256
257void
258evtag_marshal(struct evbuffer *evbuf, ev_uint32_t tag,
259    const void *data, ev_uint32_t len)
260{
261	evtag_encode_tag(evbuf, tag);
262	evtag_encode_int(evbuf, len);
263	evbuffer_add(evbuf, (void *)data, len);
264}
265
266void
267evtag_marshal_buffer(struct evbuffer *evbuf, ev_uint32_t tag,
268    struct evbuffer *data)
269{
270	evtag_encode_tag(evbuf, tag);
271	/* XXX support more than UINT32_MAX data */
272	evtag_encode_int(evbuf, (ev_uint32_t)evbuffer_get_length(data));
273	evbuffer_add_buffer(evbuf, data);
274}
275
276/* Marshaling for integers */
277void
278evtag_marshal_int(struct evbuffer *evbuf, ev_uint32_t tag, ev_uint32_t integer)
279{
280	ev_uint8_t data[5];
281	int len = encode_int_internal(data, integer);
282
283	evtag_encode_tag(evbuf, tag);
284	evtag_encode_int(evbuf, len);
285	evbuffer_add(evbuf, data, len);
286}
287
288void
289evtag_marshal_int64(struct evbuffer *evbuf, ev_uint32_t tag,
290    ev_uint64_t integer)
291{
292	ev_uint8_t data[9];
293	int len = encode_int64_internal(data, integer);
294
295	evtag_encode_tag(evbuf, tag);
296	evtag_encode_int(evbuf, len);
297	evbuffer_add(evbuf, data, len);
298}
299
300void
301evtag_marshal_string(struct evbuffer *buf, ev_uint32_t tag, const char *string)
302{
303	/* TODO support strings longer than UINT32_MAX ? */
304	evtag_marshal(buf, tag, string, (ev_uint32_t)strlen(string));
305}
306
307void
308evtag_marshal_timeval(struct evbuffer *evbuf, ev_uint32_t tag, struct timeval *tv)
309{
310	ev_uint8_t data[10];
311	int len = encode_int_internal(data, tv->tv_sec);
312	len += encode_int_internal(data + len, tv->tv_usec);
313	evtag_marshal(evbuf, tag, data, len);
314}
315
316#define DECODE_INT_INTERNAL(number, maxnibbles, pnumber, evbuf, offset) \
317do {									\
318	ev_uint8_t *data;						\
319	ev_ssize_t len = evbuffer_get_length(evbuf) - offset;		\
320	int nibbles = 0;						\
321									\
322	if (len <= 0)							\
323		return (-1);						\
324									\
325	/* XXX(niels): faster? */					\
326	data = evbuffer_pullup(evbuf, offset + 1) + offset;		\
327	if (!data)							\
328		return (-1);						\
329									\
330	nibbles = ((data[0] & 0xf0) >> 4) + 1;				\
331	if (nibbles > maxnibbles || (nibbles >> 1) + 1 > len)		\
332		return (-1);						\
333	len = (nibbles >> 1) + 1;					\
334									\
335	data = evbuffer_pullup(evbuf, offset + len) + offset;		\
336	if (!data)							\
337		return (-1);						\
338									\
339	while (nibbles > 0) {						\
340		number <<= 4;						\
341		if (nibbles & 0x1)					\
342			number |= data[nibbles >> 1] & 0x0f;		\
343		else							\
344			number |= (data[nibbles >> 1] & 0xf0) >> 4;	\
345		nibbles--;						\
346	}								\
347									\
348	*pnumber = number;						\
349									\
350	return (int)(len);						\
351} while (0)
352
353/* Internal: decode an integer from an evbuffer, without draining it.
354 *  Only integers up to 32-bits are supported.
355 *
356 * @param evbuf the buffer to read from
357 * @param offset an index into the buffer at which we should start reading.
358 * @param pnumber a pointer to receive the integer.
359 * @return The length of the number as encoded, or -1 on error.
360 */
361
362static int
363decode_int_internal(ev_uint32_t *pnumber, struct evbuffer *evbuf, int offset)
364{
365	ev_uint32_t number = 0;
366	DECODE_INT_INTERNAL(number, 8, pnumber, evbuf, offset);
367}
368
369static int
370decode_int64_internal(ev_uint64_t *pnumber, struct evbuffer *evbuf, int offset)
371{
372	ev_uint64_t number = 0;
373	DECODE_INT_INTERNAL(number, 16, pnumber, evbuf, offset);
374}
375
376int
377evtag_decode_int(ev_uint32_t *pnumber, struct evbuffer *evbuf)
378{
379	int res = decode_int_internal(pnumber, evbuf, 0);
380	if (res != -1)
381		evbuffer_drain(evbuf, res);
382
383	return (res == -1 ? -1 : 0);
384}
385
386int
387evtag_decode_int64(ev_uint64_t *pnumber, struct evbuffer *evbuf)
388{
389	int res = decode_int64_internal(pnumber, evbuf, 0);
390	if (res != -1)
391		evbuffer_drain(evbuf, res);
392
393	return (res == -1 ? -1 : 0);
394}
395
396int
397evtag_peek(struct evbuffer *evbuf, ev_uint32_t *ptag)
398{
399	return (decode_tag_internal(ptag, evbuf, 0 /* dodrain */));
400}
401
402int
403evtag_peek_length(struct evbuffer *evbuf, ev_uint32_t *plength)
404{
405	int res, len;
406
407	len = decode_tag_internal(NULL, evbuf, 0 /* dodrain */);
408	if (len == -1)
409		return (-1);
410
411	res = decode_int_internal(plength, evbuf, len);
412	if (res == -1)
413		return (-1);
414
415	*plength += res + len;
416
417	return (0);
418}
419
420int
421evtag_payload_length(struct evbuffer *evbuf, ev_uint32_t *plength)
422{
423	int res, len;
424
425	len = decode_tag_internal(NULL, evbuf, 0 /* dodrain */);
426	if (len == -1)
427		return (-1);
428
429	res = decode_int_internal(plength, evbuf, len);
430	if (res == -1)
431		return (-1);
432
433	return (0);
434}
435
436/* just unmarshals the header and returns the length of the remaining data */
437
438int
439evtag_unmarshal_header(struct evbuffer *evbuf, ev_uint32_t *ptag)
440{
441	ev_uint32_t len;
442
443	if (decode_tag_internal(ptag, evbuf, 1 /* dodrain */) == -1)
444		return (-1);
445	if (evtag_decode_int(&len, evbuf) == -1)
446		return (-1);
447
448	if (evbuffer_get_length(evbuf) < len)
449		return (-1);
450
451	return (len);
452}
453
454int
455evtag_consume(struct evbuffer *evbuf)
456{
457	int len;
458	if ((len = evtag_unmarshal_header(evbuf, NULL)) == -1)
459		return (-1);
460	evbuffer_drain(evbuf, len);
461
462	return (0);
463}
464
465/* Reads the data type from an event buffer */
466
467int
468evtag_unmarshal(struct evbuffer *src, ev_uint32_t *ptag, struct evbuffer *dst)
469{
470	int len;
471
472	if ((len = evtag_unmarshal_header(src, ptag)) == -1)
473		return (-1);
474
475	if (evbuffer_add(dst, evbuffer_pullup(src, len), len) == -1)
476		return (-1);
477
478	evbuffer_drain(src, len);
479
480	return (len);
481}
482
483/* Marshaling for integers */
484
485int
486evtag_unmarshal_int(struct evbuffer *evbuf, ev_uint32_t need_tag,
487    ev_uint32_t *pinteger)
488{
489	ev_uint32_t tag;
490	ev_uint32_t len;
491	int result;
492
493	if (decode_tag_internal(&tag, evbuf, 1 /* dodrain */) == -1)
494		return (-1);
495	if (need_tag != tag)
496		return (-1);
497	if (evtag_decode_int(&len, evbuf) == -1)
498		return (-1);
499
500	if (evbuffer_get_length(evbuf) < len)
501		return (-1);
502
503	result = decode_int_internal(pinteger, evbuf, 0);
504	evbuffer_drain(evbuf, len);
505	if (result < 0 || (size_t)result > len) /* XXX Should this be != rather than > ?*/
506		return (-1);
507	else
508		return result;
509}
510
511int
512evtag_unmarshal_int64(struct evbuffer *evbuf, ev_uint32_t need_tag,
513    ev_uint64_t *pinteger)
514{
515	ev_uint32_t tag;
516	ev_uint32_t len;
517	int result;
518
519	if (decode_tag_internal(&tag, evbuf, 1 /* dodrain */) == -1)
520		return (-1);
521	if (need_tag != tag)
522		return (-1);
523	if (evtag_decode_int(&len, evbuf) == -1)
524		return (-1);
525
526	if (evbuffer_get_length(evbuf) < len)
527		return (-1);
528
529	result = decode_int64_internal(pinteger, evbuf, 0);
530	evbuffer_drain(evbuf, len);
531	if (result < 0 || (size_t)result > len) /* XXX Should this be != rather than > ?*/
532		return (-1);
533	else
534		return result;
535}
536
537/* Unmarshal a fixed length tag */
538
539int
540evtag_unmarshal_fixed(struct evbuffer *src, ev_uint32_t need_tag, void *data,
541    size_t len)
542{
543	ev_uint32_t tag;
544	int tag_len;
545
546	/* Now unmarshal a tag and check that it matches the tag we want */
547	if ((tag_len = evtag_unmarshal_header(src, &tag)) < 0 ||
548	    tag != need_tag)
549		return (-1);
550
551	if ((size_t)tag_len != len)
552		return (-1);
553
554	evbuffer_remove(src, data, len);
555	return (0);
556}
557
558int
559evtag_unmarshal_string(struct evbuffer *evbuf, ev_uint32_t need_tag,
560    char **pstring)
561{
562	ev_uint32_t tag;
563	int tag_len;
564
565	if ((tag_len = evtag_unmarshal_header(evbuf, &tag)) == -1 ||
566	    tag != need_tag)
567		return (-1);
568
569	*pstring = mm_malloc(tag_len + 1);
570	if (*pstring == NULL) {
571		event_warn("%s: malloc", __func__);
572		return -1;
573	}
574	evbuffer_remove(evbuf, *pstring, tag_len);
575	(*pstring)[tag_len] = '\0';
576
577	return (0);
578}
579
580int
581evtag_unmarshal_timeval(struct evbuffer *evbuf, ev_uint32_t need_tag,
582    struct timeval *ptv)
583{
584	ev_uint32_t tag;
585	ev_uint32_t integer;
586	int len, offset, offset2;
587	int result = -1;
588
589	if ((len = evtag_unmarshal_header(evbuf, &tag)) == -1)
590		return (-1);
591	if (tag != need_tag)
592		goto done;
593	if ((offset = decode_int_internal(&integer, evbuf, 0)) == -1)
594		goto done;
595	ptv->tv_sec = integer;
596	if ((offset2 = decode_int_internal(&integer, evbuf, offset)) == -1)
597		goto done;
598	ptv->tv_usec = integer;
599	if (offset + offset2 > len) /* XXX Should this be != instead of > ? */
600		goto done;
601
602	result = 0;
603 done:
604	evbuffer_drain(evbuf, len);
605	return result;
606}
607