]> arthur.barton.de Git - netatalk.git/blob - libevent/event_tagging.c
Writing metadata xattr on directories with sticky bit set, FR#94
[netatalk.git] / libevent / 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
210         while (count++ < len) {
211                 ev_uint8_t lower = *data++;
212                 number |= (lower & 0x7f) << shift;
213                 shift += 7;
214
215                 if (!(lower & 0x80)) {
216                         done = 1;
217                         break;
218                 }
219         }
220
221         if (!done)
222                 return (-1);
223
224         if (dodrain)
225                 evbuffer_drain(evbuf, count);
226
227         if (ptag != NULL)
228                 *ptag = number;
229
230         return count > INT_MAX ? INT_MAX : (int)(count);
231 }
232
233 int
234 evtag_decode_tag(ev_uint32_t *ptag, struct evbuffer *evbuf)
235 {
236         return (decode_tag_internal(ptag, evbuf, 1 /* dodrain */));
237 }
238
239 /*
240  * Marshal a data type, the general format is as follows:
241  *
242  * tag number: one byte; length: var bytes; payload: var bytes
243  */
244
245 void
246 evtag_marshal(struct evbuffer *evbuf, ev_uint32_t tag,
247     const void *data, ev_uint32_t len)
248 {
249         evtag_encode_tag(evbuf, tag);
250         evtag_encode_int(evbuf, len);
251         evbuffer_add(evbuf, (void *)data, len);
252 }
253
254 void
255 evtag_marshal_buffer(struct evbuffer *evbuf, ev_uint32_t tag,
256     struct evbuffer *data)
257 {
258         evtag_encode_tag(evbuf, tag);
259         /* XXX support more than UINT32_MAX data */
260         evtag_encode_int(evbuf, (ev_uint32_t)evbuffer_get_length(data));
261         evbuffer_add_buffer(evbuf, data);
262 }
263
264 /* Marshaling for integers */
265 void
266 evtag_marshal_int(struct evbuffer *evbuf, ev_uint32_t tag, ev_uint32_t integer)
267 {
268         ev_uint8_t data[5];
269         int len = encode_int_internal(data, integer);
270
271         evtag_encode_tag(evbuf, tag);
272         evtag_encode_int(evbuf, len);
273         evbuffer_add(evbuf, data, len);
274 }
275
276 void
277 evtag_marshal_int64(struct evbuffer *evbuf, ev_uint32_t tag,
278     ev_uint64_t integer)
279 {
280         ev_uint8_t data[9];
281         int len = encode_int64_internal(data, integer);
282
283         evtag_encode_tag(evbuf, tag);
284         evtag_encode_int(evbuf, len);
285         evbuffer_add(evbuf, data, len);
286 }
287
288 void
289 evtag_marshal_string(struct evbuffer *buf, ev_uint32_t tag, const char *string)
290 {
291         /* TODO support strings longer than UINT32_MAX ? */
292         evtag_marshal(buf, tag, string, (ev_uint32_t)strlen(string));
293 }
294
295 void
296 evtag_marshal_timeval(struct evbuffer *evbuf, ev_uint32_t tag, struct timeval *tv)
297 {
298         ev_uint8_t data[10];
299         int len = encode_int_internal(data, tv->tv_sec);
300         len += encode_int_internal(data + len, tv->tv_usec);
301         evtag_marshal(evbuf, tag, data, len);
302 }
303
304 #define DECODE_INT_INTERNAL(number, maxnibbles, pnumber, evbuf, offset) \
305 do {                                                                    \
306         ev_uint8_t *data;                                               \
307         ev_ssize_t len = evbuffer_get_length(evbuf) - offset;           \
308         int nibbles = 0;                                                \
309                                                                         \
310         if (len <= 0)                                                   \
311                 return (-1);                                            \
312                                                                         \
313         /* XXX(niels): faster? */                                       \
314         data = evbuffer_pullup(evbuf, offset + 1) + offset;             \
315                                                                         \
316         nibbles = ((data[0] & 0xf0) >> 4) + 1;                          \
317         if (nibbles > maxnibbles || (nibbles >> 1) + 1 > len)           \
318                 return (-1);                                            \
319         len = (nibbles >> 1) + 1;                                       \
320                                                                         \
321         data = evbuffer_pullup(evbuf, offset + len) + offset;           \
322                                                                         \
323         while (nibbles > 0) {                                           \
324                 number <<= 4;                                           \
325                 if (nibbles & 0x1)                                      \
326                         number |= data[nibbles >> 1] & 0x0f;            \
327                 else                                                    \
328                         number |= (data[nibbles >> 1] & 0xf0) >> 4;     \
329                 nibbles--;                                              \
330         }                                                               \
331                                                                         \
332         *pnumber = number;                                              \
333                                                                         \
334         return (int)(len);                                              \
335 } while (0)
336
337 /* Internal: decode an integer from an evbuffer, without draining it.
338  *  Only integers up to 32-bits are supported.
339  *
340  * @param evbuf the buffer to read from
341  * @param offset an index into the buffer at which we should start reading.
342  * @param pnumber a pointer to receive the integer.
343  * @return The length of the number as encoded, or -1 on error.
344  */
345
346 static int
347 decode_int_internal(ev_uint32_t *pnumber, struct evbuffer *evbuf, int offset)
348 {
349         ev_uint32_t number = 0;
350         DECODE_INT_INTERNAL(number, 8, pnumber, evbuf, offset);
351 }
352
353 static int
354 decode_int64_internal(ev_uint64_t *pnumber, struct evbuffer *evbuf, int offset)
355 {
356         ev_uint64_t number = 0;
357         DECODE_INT_INTERNAL(number, 16, pnumber, evbuf, offset);
358 }
359
360 int
361 evtag_decode_int(ev_uint32_t *pnumber, struct evbuffer *evbuf)
362 {
363         int res = decode_int_internal(pnumber, evbuf, 0);
364         if (res != -1)
365                 evbuffer_drain(evbuf, res);
366
367         return (res == -1 ? -1 : 0);
368 }
369
370 int
371 evtag_decode_int64(ev_uint64_t *pnumber, struct evbuffer *evbuf)
372 {
373         int res = decode_int64_internal(pnumber, evbuf, 0);
374         if (res != -1)
375                 evbuffer_drain(evbuf, res);
376
377         return (res == -1 ? -1 : 0);
378 }
379
380 int
381 evtag_peek(struct evbuffer *evbuf, ev_uint32_t *ptag)
382 {
383         return (decode_tag_internal(ptag, evbuf, 0 /* dodrain */));
384 }
385
386 int
387 evtag_peek_length(struct evbuffer *evbuf, ev_uint32_t *plength)
388 {
389         int res, len;
390
391         len = decode_tag_internal(NULL, evbuf, 0 /* dodrain */);
392         if (len == -1)
393                 return (-1);
394
395         res = decode_int_internal(plength, evbuf, len);
396         if (res == -1)
397                 return (-1);
398
399         *plength += res + len;
400
401         return (0);
402 }
403
404 int
405 evtag_payload_length(struct evbuffer *evbuf, ev_uint32_t *plength)
406 {
407         int res, len;
408
409         len = decode_tag_internal(NULL, evbuf, 0 /* dodrain */);
410         if (len == -1)
411                 return (-1);
412
413         res = decode_int_internal(plength, evbuf, len);
414         if (res == -1)
415                 return (-1);
416
417         return (0);
418 }
419
420 /* just unmarshals the header and returns the length of the remaining data */
421
422 int
423 evtag_unmarshal_header(struct evbuffer *evbuf, ev_uint32_t *ptag)
424 {
425         ev_uint32_t len;
426
427         if (decode_tag_internal(ptag, evbuf, 1 /* dodrain */) == -1)
428                 return (-1);
429         if (evtag_decode_int(&len, evbuf) == -1)
430                 return (-1);
431
432         if (evbuffer_get_length(evbuf) < len)
433                 return (-1);
434
435         return (len);
436 }
437
438 int
439 evtag_consume(struct evbuffer *evbuf)
440 {
441         int len;
442         if ((len = evtag_unmarshal_header(evbuf, NULL)) == -1)
443                 return (-1);
444         evbuffer_drain(evbuf, len);
445
446         return (0);
447 }
448
449 /* Reads the data type from an event buffer */
450
451 int
452 evtag_unmarshal(struct evbuffer *src, ev_uint32_t *ptag, struct evbuffer *dst)
453 {
454         int len;
455
456         if ((len = evtag_unmarshal_header(src, ptag)) == -1)
457                 return (-1);
458
459         if (evbuffer_add(dst, evbuffer_pullup(src, len), len) == -1)
460                 return (-1);
461
462         evbuffer_drain(src, len);
463
464         return (len);
465 }
466
467 /* Marshaling for integers */
468
469 int
470 evtag_unmarshal_int(struct evbuffer *evbuf, ev_uint32_t need_tag,
471     ev_uint32_t *pinteger)
472 {
473         ev_uint32_t tag;
474         ev_uint32_t len;
475         int result;
476
477         if (decode_tag_internal(&tag, evbuf, 1 /* dodrain */) == -1)
478                 return (-1);
479         if (need_tag != tag)
480                 return (-1);
481         if (evtag_decode_int(&len, evbuf) == -1)
482                 return (-1);
483
484         if (evbuffer_get_length(evbuf) < len)
485                 return (-1);
486
487         result = decode_int_internal(pinteger, evbuf, 0);
488         evbuffer_drain(evbuf, len);
489         if (result < 0 || (size_t)result > len) /* XXX Should this be != rather than > ?*/
490                 return (-1);
491         else
492                 return result;
493 }
494
495 int
496 evtag_unmarshal_int64(struct evbuffer *evbuf, ev_uint32_t need_tag,
497     ev_uint64_t *pinteger)
498 {
499         ev_uint32_t tag;
500         ev_uint32_t len;
501         int result;
502
503         if (decode_tag_internal(&tag, evbuf, 1 /* dodrain */) == -1)
504                 return (-1);
505         if (need_tag != tag)
506                 return (-1);
507         if (evtag_decode_int(&len, evbuf) == -1)
508                 return (-1);
509
510         if (evbuffer_get_length(evbuf) < len)
511                 return (-1);
512
513         result = decode_int64_internal(pinteger, evbuf, 0);
514         evbuffer_drain(evbuf, len);
515         if (result < 0 || (size_t)result > len) /* XXX Should this be != rather than > ?*/
516                 return (-1);
517         else
518                 return result;
519 }
520
521 /* Unmarshal a fixed length tag */
522
523 int
524 evtag_unmarshal_fixed(struct evbuffer *src, ev_uint32_t need_tag, void *data,
525     size_t len)
526 {
527         ev_uint32_t tag;
528         int tag_len;
529
530         /* Now unmarshal a tag and check that it matches the tag we want */
531         if ((tag_len = evtag_unmarshal_header(src, &tag)) < 0 ||
532             tag != need_tag)
533                 return (-1);
534
535         if ((size_t)tag_len != len)
536                 return (-1);
537
538         evbuffer_remove(src, data, len);
539         return (0);
540 }
541
542 int
543 evtag_unmarshal_string(struct evbuffer *evbuf, ev_uint32_t need_tag,
544     char **pstring)
545 {
546         ev_uint32_t tag;
547         int tag_len;
548
549         if ((tag_len = evtag_unmarshal_header(evbuf, &tag)) == -1 ||
550             tag != need_tag)
551                 return (-1);
552
553         *pstring = mm_malloc(tag_len + 1);
554         if (*pstring == NULL) {
555                 event_warn("%s: malloc", __func__);
556                 return -1;
557         }
558         evbuffer_remove(evbuf, *pstring, tag_len);
559         (*pstring)[tag_len] = '\0';
560
561         return (0);
562 }
563
564 int
565 evtag_unmarshal_timeval(struct evbuffer *evbuf, ev_uint32_t need_tag,
566     struct timeval *ptv)
567 {
568         ev_uint32_t tag;
569         ev_uint32_t integer;
570         int len, offset, offset2;
571         int result = -1;
572
573         if ((len = evtag_unmarshal_header(evbuf, &tag)) == -1)
574                 return (-1);
575         if (tag != need_tag)
576                 goto done;
577         if ((offset = decode_int_internal(&integer, evbuf, 0)) == -1)
578                 goto done;
579         ptv->tv_sec = integer;
580         if ((offset2 = decode_int_internal(&integer, evbuf, offset)) == -1)
581                 goto done;
582         ptv->tv_usec = integer;
583         if (offset + offset2 > len) /* XXX Should this be != instead of > ? */
584                 goto done;
585
586         result = 0;
587  done:
588         evbuffer_drain(evbuf, len);
589         return result;
590 }