Line data Source code
1 : /* Copyright (c) 2009-2021, The Tor Project, Inc. */
2 : /* See LICENSE for licensing information */
3 :
4 : /**
5 : * \file compat_libevent.c
6 : * \brief Wrappers and utility functions for Libevent.
7 : */
8 :
9 : #include "orconfig.h"
10 : #define COMPAT_LIBEVENT_PRIVATE
11 : #include "lib/evloop/compat_libevent.h"
12 :
13 : #include "lib/crypt_ops/crypto_rand.h"
14 : #include "lib/log/log.h"
15 : #include "lib/log/util_bug.h"
16 : #include "lib/string/compat_string.h"
17 :
18 : #include <event2/event.h>
19 : #include <event2/thread.h>
20 : #include <string.h>
21 :
22 : /** A string which, if it appears in a libevent log, should be ignored. */
23 : static const char *suppress_msg = NULL;
24 : /** Callback function passed to event_set_log() so we can intercept
25 : * log messages from libevent. */
26 : STATIC void
27 9 : libevent_logging_callback(int severity, const char *msg)
28 : {
29 9 : char buf[1024];
30 9 : size_t n;
31 9 : if (suppress_msg && strstr(msg, suppress_msg))
32 1 : return;
33 8 : n = strlcpy(buf, msg, sizeof(buf));
34 8 : if (n && n < sizeof(buf) && buf[n-1] == '\n') {
35 1 : buf[n-1] = '\0';
36 : }
37 8 : switch (severity) {
38 : case _EVENT_LOG_DEBUG:
39 2 : log_debug(LD_NOCB|LD_NET, "Message from libevent: %s", buf);
40 2 : break;
41 2 : case _EVENT_LOG_MSG:
42 2 : log_info(LD_NOCB|LD_NET, "Message from libevent: %s", buf);
43 2 : break;
44 1 : case _EVENT_LOG_WARN:
45 1 : log_warn(LD_NOCB|LD_GENERAL, "Warning from libevent: %s", buf);
46 1 : break;
47 1 : case _EVENT_LOG_ERR:
48 1 : log_err(LD_NOCB|LD_GENERAL, "Error from libevent: %s", buf);
49 1 : break;
50 2 : default:
51 2 : log_warn(LD_NOCB|LD_GENERAL, "Message [%d] from libevent: %s",
52 : severity, buf);
53 2 : break;
54 : }
55 : }
56 : /** Set hook to intercept log messages from libevent. */
57 : void
58 5 : configure_libevent_logging(void)
59 : {
60 5 : event_set_log_callback(libevent_logging_callback);
61 5 : }
62 :
63 : /** Ignore any libevent log message that contains <b>msg</b>. */
64 : void
65 10 : suppress_libevent_log_msg(const char *msg)
66 : {
67 10 : suppress_msg = msg;
68 10 : }
69 :
70 : /* Wrapper for event_free() that tolerates tor_event_free(NULL) */
71 : void
72 1427 : tor_event_free_(struct event *ev)
73 : {
74 1427 : if (ev == NULL)
75 : return;
76 104 : event_free(ev);
77 : }
78 :
79 : /** Global event base for use by the main thread. */
80 : static struct event_base *the_event_base = NULL;
81 :
82 : /**
83 : * @defgroup postloop post-loop event helpers
84 : *
85 : * If we're not careful, Libevent can susceptible to infinite event chains:
86 : * one event can activate another, whose callback activates another, whose
87 : * callback activates another, ad infinitum. While this is happening,
88 : * Libevent won't be checking timeouts, socket-based events, signals, and so
89 : * on.
90 : *
91 : * We solve this problem by marking some events as "post-loop". A post-loop
92 : * event behaves like any ordinary event, but any events that _it_ activates
93 : * cannot run until Libevent has checked for other events at least once.
94 : *
95 : * @{ */
96 :
97 : /**
98 : * An event that stops Libevent from running any more events on the current
99 : * iteration of its loop, until it has re-checked for socket events, signal
100 : * events, timeouts, etc.
101 : */
102 : static struct event *rescan_mainloop_ev = NULL;
103 :
104 : /**
105 : * Callback to implement rescan_mainloop_ev: it simply exits the mainloop,
106 : * and relies on Tor to re-enter the mainloop since no error has occurred.
107 : */
108 : static void
109 104570 : rescan_mainloop_cb(evutil_socket_t fd, short events, void *arg)
110 : {
111 104570 : (void)fd;
112 104570 : (void)events;
113 104570 : struct event_base *the_base = arg;
114 104570 : event_base_loopbreak(the_base);
115 104570 : }
116 :
117 : /** @} */
118 :
119 : /* This is what passes for version detection on OSX. We set
120 : * MACOSX_KQUEUE_IS_BROKEN to true iff we're on a version of OSX before
121 : * 10.4.0 (aka 1040). */
122 : #ifdef __APPLE__
123 : #ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
124 : #define MACOSX_KQUEUE_IS_BROKEN \
125 : (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1040)
126 : #else
127 : #define MACOSX_KQUEUE_IS_BROKEN 0
128 : #endif /* defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) */
129 : #endif /* defined(__APPLE__) */
130 :
131 : /** Initialize the Libevent library and set up the event base. */
132 : void
133 21 : tor_libevent_initialize(tor_libevent_cfg_t *torcfg)
134 : {
135 21 : tor_assert(the_event_base == NULL);
136 : /* some paths below don't use torcfg, so avoid unused variable warnings */
137 21 : (void)torcfg;
138 :
139 : {
140 21 : int attempts = 0;
141 21 : struct event_config *cfg;
142 :
143 21 : ++attempts;
144 21 : cfg = event_config_new();
145 21 : tor_assert(cfg);
146 :
147 : /* Telling Libevent not to try to turn locking on can avoid a needless
148 : * socketpair() attempt. */
149 21 : event_config_set_flag(cfg, EVENT_BASE_FLAG_NOLOCK);
150 :
151 21 : if (torcfg->num_cpus > 0)
152 4 : event_config_set_num_cpus_hint(cfg, torcfg->num_cpus);
153 :
154 : /* We can enable changelist support with epoll, since we don't give
155 : * Libevent any dup'd fds. This lets us avoid some syscalls. */
156 21 : event_config_set_flag(cfg, EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST);
157 :
158 21 : the_event_base = event_base_new_with_config(cfg);
159 :
160 21 : event_config_free(cfg);
161 : }
162 :
163 21 : if (!the_event_base) {
164 : /* LCOV_EXCL_START */
165 : log_err(LD_GENERAL, "Unable to initialize Libevent: cannot continue.");
166 : exit(1); // exit ok: libevent is broken.
167 : /* LCOV_EXCL_STOP */
168 : }
169 :
170 21 : rescan_mainloop_ev = event_new(the_event_base, -1, 0,
171 : rescan_mainloop_cb, the_event_base);
172 21 : if (!rescan_mainloop_ev) {
173 : /* LCOV_EXCL_START */
174 : log_err(LD_GENERAL, "Unable to create rescan event: cannot continue.");
175 : exit(1); // exit ok: libevent is broken.
176 : /* LCOV_EXCL_STOP */
177 : }
178 :
179 21 : log_info(LD_GENERAL,
180 : "Initialized libevent version %s using method %s. Good.",
181 : event_get_version(), tor_libevent_get_method());
182 21 : }
183 :
184 : /**
185 : * Return true iff the libevent module has been successfully initialized,
186 : * and not subsequently shut down.
187 : **/
188 : bool
189 4 : tor_libevent_is_initialized(void)
190 : {
191 4 : return the_event_base != NULL;
192 : }
193 :
194 : /** Return the current Libevent event base that we're set up to use. */
195 106969 : MOCK_IMPL(struct event_base *,
196 : tor_libevent_get_base, (void))
197 : {
198 106969 : tor_assert(the_event_base != NULL);
199 106969 : return the_event_base;
200 : }
201 :
202 : /** Return the name of the Libevent backend we're using. */
203 : const char *
204 21 : tor_libevent_get_method(void)
205 : {
206 21 : return event_base_get_method(the_event_base);
207 : }
208 :
209 : /** Return a string representation of the version of the currently running
210 : * version of Libevent. */
211 : const char *
212 235 : tor_libevent_get_version_str(void)
213 : {
214 235 : return event_get_version();
215 : }
216 :
217 : /** Return a string representation of the version of Libevent that was used
218 : * at compilation time. */
219 : const char *
220 1 : tor_libevent_get_header_version_str(void)
221 : {
222 1 : return LIBEVENT_VERSION;
223 : }
224 :
225 : /** Represents a timer that's run every N microseconds by Libevent. */
226 : struct periodic_timer_t {
227 : /** Underlying event used to implement this periodic event. */
228 : struct event *ev;
229 : /** The callback we'll be invoking whenever the event triggers */
230 : void (*cb)(struct periodic_timer_t *, void *);
231 : /** User-supplied data for the callback */
232 : void *data;
233 : };
234 :
235 : /** Libevent callback to implement a periodic event. */
236 : static void
237 13 : periodic_timer_cb(evutil_socket_t fd, short what, void *arg)
238 : {
239 13 : periodic_timer_t *timer = arg;
240 13 : (void) what;
241 13 : (void) fd;
242 13 : timer->cb(timer, timer->data);
243 13 : }
244 :
245 : /** Create and schedule a new timer that will run every <b>tv</b> in
246 : * the event loop of <b>base</b>. When the timer fires, it will
247 : * run the timer in <b>cb</b> with the user-supplied data in <b>data</b>. */
248 : periodic_timer_t *
249 7 : periodic_timer_new(struct event_base *base,
250 : const struct timeval *tv,
251 : void (*cb)(periodic_timer_t *timer, void *data),
252 : void *data)
253 : {
254 7 : periodic_timer_t *timer;
255 7 : tor_assert(base);
256 7 : tor_assert(tv);
257 7 : tor_assert(cb);
258 7 : timer = tor_malloc_zero(sizeof(periodic_timer_t));
259 7 : if (!(timer->ev = tor_event_new(base, -1, EV_PERSIST,
260 : periodic_timer_cb, timer))) {
261 0 : tor_free(timer);
262 0 : return NULL;
263 : }
264 7 : timer->cb = cb;
265 7 : timer->data = data;
266 7 : periodic_timer_launch(timer, tv);
267 7 : return timer;
268 : }
269 :
270 : /**
271 : * Launch the timer <b>timer</b> to run at <b>tv</b> from now, and every
272 : * <b>tv</b> thereafter.
273 : *
274 : * If the timer is already enabled, this function does nothing.
275 : */
276 : void
277 7 : periodic_timer_launch(periodic_timer_t *timer, const struct timeval *tv)
278 : {
279 7 : tor_assert(timer);
280 7 : if (event_pending(timer->ev, EV_TIMEOUT, NULL))
281 : return;
282 7 : event_add(timer->ev, tv);
283 : }
284 :
285 : /**
286 : * Disable the provided <b>timer</b>, but do not free it.
287 : *
288 : * You can reenable the same timer later with periodic_timer_launch.
289 : *
290 : * If the timer is already disabled, this function does nothing.
291 : */
292 : void
293 0 : periodic_timer_disable(periodic_timer_t *timer)
294 : {
295 0 : tor_assert(timer);
296 0 : (void) event_del(timer->ev);
297 0 : }
298 :
299 : /** Stop and free a periodic timer */
300 : void
301 242 : periodic_timer_free_(periodic_timer_t *timer)
302 : {
303 242 : if (!timer)
304 : return;
305 7 : tor_event_free(timer->ev);
306 7 : tor_free(timer);
307 : }
308 :
309 : /**
310 : * Type used to represent events that run directly from the main loop,
311 : * either because they are activated from elsewhere in the code, or
312 : * because they have a simple timeout.
313 : *
314 : * We use this type to avoid exposing Libevent's API throughout the rest
315 : * of the codebase.
316 : *
317 : * This type can't be used for all events: it doesn't handle events that
318 : * are triggered by signals or by sockets.
319 : */
320 : struct mainloop_event_t {
321 : struct event *ev;
322 : void (*cb)(mainloop_event_t *, void *);
323 : void *userdata;
324 : };
325 :
326 : /**
327 : * Internal: Implements mainloop event using a libevent event.
328 : */
329 : static void
330 1764 : mainloop_event_cb(evutil_socket_t fd, short what, void *arg)
331 : {
332 1764 : (void)fd;
333 1764 : (void)what;
334 1764 : mainloop_event_t *mev = arg;
335 1764 : mev->cb(mev, mev->userdata);
336 1764 : }
337 :
338 : /**
339 : * As mainloop_event_cb, but implements a post-loop event.
340 : */
341 : static void
342 104570 : mainloop_event_postloop_cb(evutil_socket_t fd, short what, void *arg)
343 : {
344 104570 : (void)fd;
345 104570 : (void)what;
346 :
347 : /* Note that if rescan_mainloop_ev is already activated,
348 : * event_active() will do nothing: only the first post-loop event that
349 : * happens each time through the event loop will cause it to be
350 : * activated.
351 : *
352 : * Because event_active() puts events on a FIFO queue, every event
353 : * that is made active _after_ rescan_mainloop_ev will get its
354 : * callback run after rescan_mainloop_cb is called -- that is, on the
355 : * next iteration of the loop.
356 : */
357 104570 : event_active(rescan_mainloop_ev, EV_READ, 1);
358 :
359 104570 : mainloop_event_t *mev = arg;
360 104570 : mev->cb(mev, mev->userdata);
361 104570 : }
362 :
363 : /**
364 : * Helper for mainloop_event_new() and mainloop_event_postloop_new().
365 : */
366 : static mainloop_event_t *
367 215 : mainloop_event_new_impl(int postloop,
368 : void (*cb)(mainloop_event_t *, void *),
369 : void *userdata)
370 : {
371 215 : tor_assert(cb);
372 :
373 215 : struct event_base *base = tor_libevent_get_base();
374 215 : mainloop_event_t *mev = tor_malloc_zero(sizeof(mainloop_event_t));
375 387 : mev->ev = tor_event_new(base, -1, 0,
376 : postloop ? mainloop_event_postloop_cb : mainloop_event_cb,
377 : mev);
378 215 : tor_assert(mev->ev);
379 215 : mev->cb = cb;
380 215 : mev->userdata = userdata;
381 215 : return mev;
382 : }
383 :
384 : /**
385 : * Create and return a new mainloop_event_t to run the function <b>cb</b>.
386 : *
387 : * When run, the callback function will be passed the mainloop_event_t
388 : * and <b>userdata</b> as its arguments. The <b>userdata</b> pointer
389 : * must remain valid for as long as the mainloop_event_t event exists:
390 : * it is your responsibility to free it.
391 : *
392 : * The event is not scheduled by default: Use mainloop_event_activate()
393 : * or mainloop_event_schedule() to make it run.
394 : */
395 : mainloop_event_t *
396 172 : mainloop_event_new(void (*cb)(mainloop_event_t *, void *),
397 : void *userdata)
398 : {
399 172 : return mainloop_event_new_impl(0, cb, userdata);
400 : }
401 :
402 : /**
403 : * As mainloop_event_new(), but create a post-loop event.
404 : *
405 : * A post-loop event behaves like any ordinary event, but any events
406 : * that _it_ activates cannot run until Libevent has checked for other
407 : * events at least once.
408 : */
409 : mainloop_event_t *
410 43 : mainloop_event_postloop_new(void (*cb)(mainloop_event_t *, void *),
411 : void *userdata)
412 : {
413 43 : return mainloop_event_new_impl(1, cb, userdata);
414 : }
415 :
416 : /**
417 : * Schedule <b>event</b> to run in the main loop, immediately. If it is
418 : * not scheduled, it will run anyway. If it is already scheduled to run
419 : * later, it will run now instead. This function will have no effect if
420 : * the event is already scheduled to run.
421 : *
422 : * This function may only be called from the main thread.
423 : */
424 : void
425 104789 : mainloop_event_activate(mainloop_event_t *event)
426 : {
427 104789 : tor_assert(event);
428 104789 : event_active(event->ev, EV_READ, 1);
429 104789 : }
430 :
431 : /** Schedule <b>event</b> to run in the main loop, after a delay of <b>tv</b>.
432 : *
433 : * If the event is scheduled for a different time, cancel it and run
434 : * after this delay instead. If the event is currently pending to run
435 : * <b>now</b>, has no effect.
436 : *
437 : * Do not call this function with <b>tv</b> == NULL -- use
438 : * mainloop_event_activate() instead.
439 : *
440 : * This function may only be called from the main thread.
441 : */
442 : int
443 1840 : mainloop_event_schedule(mainloop_event_t *event, const struct timeval *tv)
444 : {
445 1840 : tor_assert(event);
446 1840 : if (BUG(tv == NULL)) {
447 : // LCOV_EXCL_START
448 : mainloop_event_activate(event);
449 : return 0;
450 : // LCOV_EXCL_STOP
451 : }
452 1840 : return event_add(event->ev, tv);
453 : }
454 :
455 : /** Cancel <b>event</b> if it is currently active or pending. (Do nothing if
456 : * the event is not currently active or pending.) */
457 : void
458 40 : mainloop_event_cancel(mainloop_event_t *event)
459 : {
460 40 : if (!event)
461 : return;
462 40 : (void) event_del(event->ev);
463 : }
464 :
465 : /** Cancel <b>event</b> and release all storage associated with it. */
466 : void
467 10684 : mainloop_event_free_(mainloop_event_t *event)
468 : {
469 10684 : if (!event)
470 : return;
471 78 : tor_event_free(event->ev);
472 78 : memset(event, 0xb8, sizeof(*event));
473 78 : tor_free(event);
474 : }
475 :
476 : int
477 5553 : tor_init_libevent_rng(void)
478 : {
479 5553 : int rv = 0;
480 5553 : char buf[256];
481 5553 : if (evutil_secure_rng_init() < 0) {
482 0 : rv = -1;
483 : }
484 5553 : crypto_rand(buf, 32);
485 : #ifdef HAVE_EVUTIL_SECURE_RNG_ADD_BYTES
486 5553 : evutil_secure_rng_add_bytes(buf, 32);
487 : #endif
488 5553 : evutil_secure_rng_get_bytes(buf, sizeof(buf));
489 5553 : return rv;
490 : }
491 :
492 : /**
493 : * Un-initialize libevent in preparation for an exit
494 : */
495 : void
496 235 : tor_libevent_free_all(void)
497 : {
498 235 : tor_event_free(rescan_mainloop_ev);
499 235 : if (the_event_base)
500 4 : event_base_free(the_event_base);
501 235 : the_event_base = NULL;
502 235 : }
503 :
504 : /**
505 : * Run the event loop for the provided event_base, handling events until
506 : * something stops it. If <b>once</b> is set, then just poll-and-run
507 : * once, then exit. Return 0 on success, -1 if an error occurred, or 1
508 : * if we exited because no events were pending or active.
509 : *
510 : * This isn't reentrant or multithreaded.
511 : */
512 : int
513 104581 : tor_libevent_run_event_loop(struct event_base *base, int once)
514 : {
515 104581 : const int flags = once ? EVLOOP_ONCE : 0;
516 104581 : return event_base_loop(base, flags);
517 : }
518 :
519 : /** Tell the event loop to exit after <b>delay</b>. If <b>delay</b> is NULL,
520 : * instead exit after we're done running the currently active events. */
521 : void
522 14 : tor_libevent_exit_loop_after_delay(struct event_base *base,
523 : const struct timeval *delay)
524 : {
525 14 : event_base_loopexit(base, delay);
526 14 : }
527 :
528 : /** Tell the event loop to exit after running whichever callback is currently
529 : * active. */
530 : void
531 223 : tor_libevent_exit_loop_after_callback(struct event_base *base)
532 : {
533 223 : event_base_loopbreak(base);
534 223 : }
535 :
536 : #if defined(TOR_UNIT_TESTS)
537 : /** For testing: called post-fork to make libevent reinitialize
538 : * kernel structures. */
539 : void
540 1854 : tor_libevent_postfork(void)
541 : {
542 1854 : int r = event_reinit(tor_libevent_get_base());
543 1854 : tor_assert(r == 0);
544 1854 : }
545 : #endif /* defined(TOR_UNIT_TESTS) */
|