compat_libevent.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. /* Copyright (c) 2009-2016, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. /**
  4. * \file compat_libevent.c
  5. * \brief Wrappers to handle porting between different versions of libevent.
  6. *
  7. * In an ideal world, we'd just use Libevent 2.0 from now on. But as of June
  8. * 2012, Libevent 1.4 is still all over, and some poor souls are stuck on
  9. * Libevent 1.3e. */
  10. #include "orconfig.h"
  11. #include "compat.h"
  12. #define COMPAT_LIBEVENT_PRIVATE
  13. #include "compat_libevent.h"
  14. #include "crypto.h"
  15. #include "util.h"
  16. #include "torlog.h"
  17. #include <event2/event.h>
  18. #include <event2/thread.h>
  19. #ifdef USE_BUFFEREVENTS
  20. #include <event2/bufferevent.h>
  21. #endif
  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. /** Ignore any libevent log message that contains <b>msg</b>. */
  63. void
  64. suppress_libevent_log_msg(const char *msg)
  65. {
  66. suppress_msg = msg;
  67. }
  68. /* Wrapper for event_free() that tolerates tor_event_free(NULL) */
  69. void
  70. tor_event_free(struct event *ev)
  71. {
  72. if (ev == NULL)
  73. return;
  74. event_free(ev);
  75. }
  76. /** Global event base for use by the main thread. */
  77. static struct event_base *the_event_base = NULL;
  78. /* This is what passes for version detection on OSX. We set
  79. * MACOSX_KQUEUE_IS_BROKEN to true iff we're on a version of OSX before
  80. * 10.4.0 (aka 1040). */
  81. #ifdef __APPLE__
  82. #ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
  83. #define MACOSX_KQUEUE_IS_BROKEN \
  84. (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1040)
  85. #else
  86. #define MACOSX_KQUEUE_IS_BROKEN 0
  87. #endif
  88. #endif
  89. #ifdef USE_BUFFEREVENTS
  90. static int using_iocp_bufferevents = 0;
  91. static void tor_libevent_set_tick_timeout(int msec_per_tick);
  92. int
  93. tor_libevent_using_iocp_bufferevents(void)
  94. {
  95. return using_iocp_bufferevents;
  96. }
  97. #endif
  98. /** Initialize the Libevent library and set up the event base. */
  99. void
  100. tor_libevent_initialize(tor_libevent_cfg *torcfg)
  101. {
  102. tor_assert(the_event_base == NULL);
  103. /* some paths below don't use torcfg, so avoid unused variable warnings */
  104. (void)torcfg;
  105. {
  106. int attempts = 0;
  107. int using_threads;
  108. struct event_config *cfg;
  109. retry:
  110. ++attempts;
  111. using_threads = 0;
  112. cfg = event_config_new();
  113. tor_assert(cfg);
  114. #if defined(_WIN32) && defined(USE_BUFFEREVENTS)
  115. if (! torcfg->disable_iocp) {
  116. evthread_use_windows_threads();
  117. event_config_set_flag(cfg, EVENT_BASE_FLAG_STARTUP_IOCP);
  118. using_iocp_bufferevents = 1;
  119. using_threads = 1;
  120. } else {
  121. using_iocp_bufferevents = 0;
  122. }
  123. #elif defined(__COVERITY__)
  124. /* Avoid a 'dead code' warning below. */
  125. using_threads = ! torcfg->disable_iocp;
  126. #endif
  127. if (!using_threads) {
  128. /* Telling Libevent not to try to turn locking on can avoid a needless
  129. * socketpair() attempt. */
  130. event_config_set_flag(cfg, EVENT_BASE_FLAG_NOLOCK);
  131. }
  132. if (torcfg->num_cpus > 0)
  133. event_config_set_num_cpus_hint(cfg, torcfg->num_cpus);
  134. /* We can enable changelist support with epoll, since we don't give
  135. * Libevent any dup'd fds. This lets us avoid some syscalls. */
  136. event_config_set_flag(cfg, EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST);
  137. the_event_base = event_base_new_with_config(cfg);
  138. event_config_free(cfg);
  139. if (using_threads && the_event_base == NULL && attempts < 2) {
  140. /* This could be a socketpair() failure, which can happen sometimes on
  141. * windows boxes with obnoxious firewall rules. Downgrade and try
  142. * again. */
  143. #if defined(_WIN32) && defined(USE_BUFFEREVENTS)
  144. if (torcfg->disable_iocp == 0) {
  145. log_warn(LD_GENERAL, "Unable to initialize Libevent. Trying again "
  146. "with IOCP disabled.");
  147. } else
  148. #endif
  149. {
  150. log_warn(LD_GENERAL, "Unable to initialize Libevent. Trying again.");
  151. }
  152. torcfg->disable_iocp = 1;
  153. goto retry;
  154. }
  155. }
  156. if (!the_event_base) {
  157. /* LCOV_EXCL_START */
  158. log_err(LD_GENERAL, "Unable to initialize Libevent: cannot continue.");
  159. exit(1);
  160. /* LCOV_EXCL_STOP */
  161. }
  162. log_info(LD_GENERAL,
  163. "Initialized libevent version %s using method %s. Good.",
  164. event_get_version(), tor_libevent_get_method());
  165. #ifdef USE_BUFFEREVENTS
  166. tor_libevent_set_tick_timeout(torcfg->msec_per_tick);
  167. #endif
  168. }
  169. /** Return the current Libevent event base that we're set up to use. */
  170. MOCK_IMPL(struct event_base *,
  171. tor_libevent_get_base, (void))
  172. {
  173. tor_assert(the_event_base != NULL);
  174. return the_event_base;
  175. }
  176. /** Return the name of the Libevent backend we're using. */
  177. const char *
  178. tor_libevent_get_method(void)
  179. {
  180. return event_base_get_method(the_event_base);
  181. }
  182. /** Return a string representation of the version of the currently running
  183. * version of Libevent. */
  184. const char *
  185. tor_libevent_get_version_str(void)
  186. {
  187. return event_get_version();
  188. }
  189. /** Return a string representation of the version of Libevent that was used
  190. * at compilation time. */
  191. const char *
  192. tor_libevent_get_header_version_str(void)
  193. {
  194. return LIBEVENT_VERSION;
  195. }
  196. /** Represents a timer that's run every N microseconds by Libevent. */
  197. struct periodic_timer_t {
  198. /** Underlying event used to implement this periodic event. */
  199. struct event *ev;
  200. /** The callback we'll be invoking whenever the event triggers */
  201. void (*cb)(struct periodic_timer_t *, void *);
  202. /** User-supplied data for the callback */
  203. void *data;
  204. };
  205. /** Libevent callback to implement a periodic event. */
  206. static void
  207. periodic_timer_cb(evutil_socket_t fd, short what, void *arg)
  208. {
  209. periodic_timer_t *timer = arg;
  210. (void) what;
  211. (void) fd;
  212. timer->cb(timer, timer->data);
  213. }
  214. /** Create and schedule a new timer that will run every <b>tv</b> in
  215. * the event loop of <b>base</b>. When the timer fires, it will
  216. * run the timer in <b>cb</b> with the user-supplied data in <b>data</b>. */
  217. periodic_timer_t *
  218. periodic_timer_new(struct event_base *base,
  219. const struct timeval *tv,
  220. void (*cb)(periodic_timer_t *timer, void *data),
  221. void *data)
  222. {
  223. periodic_timer_t *timer;
  224. tor_assert(base);
  225. tor_assert(tv);
  226. tor_assert(cb);
  227. timer = tor_malloc_zero(sizeof(periodic_timer_t));
  228. if (!(timer->ev = tor_event_new(base, -1, EV_PERSIST,
  229. periodic_timer_cb, timer))) {
  230. tor_free(timer);
  231. return NULL;
  232. }
  233. timer->cb = cb;
  234. timer->data = data;
  235. event_add(timer->ev, (struct timeval *)tv); /*drop const for old libevent*/
  236. return timer;
  237. }
  238. /** Stop and free a periodic timer */
  239. void
  240. periodic_timer_free(periodic_timer_t *timer)
  241. {
  242. if (!timer)
  243. return;
  244. tor_event_free(timer->ev);
  245. tor_free(timer);
  246. }
  247. #ifdef USE_BUFFEREVENTS
  248. static const struct timeval *one_tick = NULL;
  249. /**
  250. * Return a special timeout to be passed whenever libevent's O(1) timeout
  251. * implementation should be used. Only use this when the timer is supposed
  252. * to fire after msec_per_tick ticks have elapsed.
  253. */
  254. const struct timeval *
  255. tor_libevent_get_one_tick_timeout(void)
  256. {
  257. tor_assert(one_tick);
  258. return one_tick;
  259. }
  260. /** Initialize the common timeout that we'll use to refill the buckets every
  261. * time a tick elapses. */
  262. static void
  263. tor_libevent_set_tick_timeout(int msec_per_tick)
  264. {
  265. struct event_base *base = tor_libevent_get_base();
  266. struct timeval tv;
  267. tor_assert(! one_tick);
  268. tv.tv_sec = msec_per_tick / 1000;
  269. tv.tv_usec = (msec_per_tick % 1000) * 1000;
  270. one_tick = event_base_init_common_timeout(base, &tv);
  271. }
  272. static struct bufferevent *
  273. tor_get_root_bufferevent(struct bufferevent *bev)
  274. {
  275. struct bufferevent *u;
  276. while ((u = bufferevent_get_underlying(bev)) != NULL)
  277. bev = u;
  278. return bev;
  279. }
  280. int
  281. tor_set_bufferevent_rate_limit(struct bufferevent *bev,
  282. struct ev_token_bucket_cfg *cfg)
  283. {
  284. return bufferevent_set_rate_limit(tor_get_root_bufferevent(bev), cfg);
  285. }
  286. int
  287. tor_add_bufferevent_to_rate_limit_group(struct bufferevent *bev,
  288. struct bufferevent_rate_limit_group *g)
  289. {
  290. return bufferevent_add_to_rate_limit_group(tor_get_root_bufferevent(bev), g);
  291. }
  292. #endif
  293. int
  294. tor_init_libevent_rng(void)
  295. {
  296. int rv = 0;
  297. char buf[256];
  298. if (evutil_secure_rng_init() < 0) {
  299. rv = -1;
  300. }
  301. crypto_rand(buf, 32);
  302. evutil_secure_rng_add_bytes(buf, 32);
  303. evutil_secure_rng_get_bytes(buf, sizeof(buf));
  304. return rv;
  305. }
  306. #if defined(LIBEVENT_VERSION_NUMBER) && LIBEVENT_VERSION_NUMBER >= V(2,1,1) \
  307. && !defined(TOR_UNIT_TESTS)
  308. void
  309. tor_gettimeofday_cached(struct timeval *tv)
  310. {
  311. event_base_gettimeofday_cached(the_event_base, tv);
  312. }
  313. void
  314. tor_gettimeofday_cache_clear(void)
  315. {
  316. event_base_update_cache_time(the_event_base);
  317. }
  318. #else
  319. /** Cache the current hi-res time; the cache gets reset when libevent
  320. * calls us. */
  321. static struct timeval cached_time_hires = {0, 0};
  322. /** Return a fairly recent view of the current time. */
  323. void
  324. tor_gettimeofday_cached(struct timeval *tv)
  325. {
  326. if (cached_time_hires.tv_sec == 0) {
  327. tor_gettimeofday(&cached_time_hires);
  328. }
  329. *tv = cached_time_hires;
  330. }
  331. /** Reset the cached view of the current time, so that the next time we try
  332. * to learn it, we will get an up-to-date value. */
  333. void
  334. tor_gettimeofday_cache_clear(void)
  335. {
  336. cached_time_hires.tv_sec = 0;
  337. }
  338. #ifdef TOR_UNIT_TESTS
  339. /** For testing: force-update the cached time to a given value. */
  340. void
  341. tor_gettimeofday_cache_set(const struct timeval *tv)
  342. {
  343. tor_assert(tv);
  344. memcpy(&cached_time_hires, tv, sizeof(*tv));
  345. }
  346. #endif
  347. #endif
  348. /**
  349. * As tor_gettimeofday_cached, but can never move backwards in time.
  350. *
  351. * The returned value may diverge from wall-clock time, since wall-clock time
  352. * can trivially be adjusted backwards, and this can't. Don't mix wall-clock
  353. * time with these values in the same calculation.
  354. *
  355. * Depending on implementation, this function may or may not "smooth out" huge
  356. * jumps forward in wall-clock time. It may or may not keep its results
  357. * advancing forward (as opposed to stalling) if the wall-clock time goes
  358. * backwards. The current implementation does neither of of these.
  359. *
  360. * This function is not thread-safe; do not call it outside the main thread.
  361. *
  362. * In future versions of Tor, this may return a time does not have its
  363. * origin at the Unix epoch.
  364. */
  365. void
  366. tor_gettimeofday_cached_monotonic(struct timeval *tv)
  367. {
  368. struct timeval last_tv = { 0, 0 };
  369. tor_gettimeofday_cached(tv);
  370. if (timercmp(tv, &last_tv, OP_LT)) {
  371. memcpy(tv, &last_tv, sizeof(struct timeval));
  372. } else {
  373. memcpy(&last_tv, tv, sizeof(struct timeval));
  374. }
  375. }