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