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