tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

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) */