Update comments in get_interface_addresses_ioctl
[tor.git] / src / common / compat_libevent.c
blob29e5c5f63cddb946744155dcb97f9115df9ea928
1 /* Copyright (c) 2009-2015, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
4 /**
5 * \file compat_libevent.c
6 * \brief Wrappers to handle porting between different versions of libevent.
8 * In an ideal world, we'd just use Libevent 2.0 from now on. But as of June
9 * 2012, Libevent 1.4 is still all over, and some poor souls are stuck on
10 * Libevent 1.3e. */
12 #include "orconfig.h"
13 #include "compat.h"
14 #define COMPAT_LIBEVENT_PRIVATE
15 #include "compat_libevent.h"
17 #include "crypto.h"
19 #include "util.h"
20 #include "torlog.h"
22 #ifdef HAVE_EVENT2_EVENT_H
23 #include <event2/event.h>
24 #include <event2/thread.h>
25 #ifdef USE_BUFFEREVENTS
26 #include <event2/bufferevent.h>
27 #endif
28 #else
29 #include <event.h>
30 #endif
32 /** A string which, if it appears in a libevent log, should be ignored. */
33 static const char *suppress_msg = NULL;
34 /** Callback function passed to event_set_log() so we can intercept
35 * log messages from libevent. */
36 STATIC void
37 libevent_logging_callback(int severity, const char *msg)
39 char buf[1024];
40 size_t n;
41 if (suppress_msg && strstr(msg, suppress_msg))
42 return;
43 n = strlcpy(buf, msg, sizeof(buf));
44 if (n && n < sizeof(buf) && buf[n-1] == '\n') {
45 buf[n-1] = '\0';
47 switch (severity) {
48 case _EVENT_LOG_DEBUG:
49 log_debug(LD_NOCB|LD_NET, "Message from libevent: %s", buf);
50 break;
51 case _EVENT_LOG_MSG:
52 log_info(LD_NOCB|LD_NET, "Message from libevent: %s", buf);
53 break;
54 case _EVENT_LOG_WARN:
55 log_warn(LD_NOCB|LD_GENERAL, "Warning from libevent: %s", buf);
56 break;
57 case _EVENT_LOG_ERR:
58 log_err(LD_NOCB|LD_GENERAL, "Error from libevent: %s", buf);
59 break;
60 default:
61 log_warn(LD_NOCB|LD_GENERAL, "Message [%d] from libevent: %s",
62 severity, buf);
63 break;
66 /** Set hook to intercept log messages from libevent. */
67 void
68 configure_libevent_logging(void)
70 event_set_log_callback(libevent_logging_callback);
72 /** Ignore any libevent log message that contains <b>msg</b>. */
73 void
74 suppress_libevent_log_msg(const char *msg)
76 suppress_msg = msg;
79 #ifndef HAVE_EVENT2_EVENT_H
80 /** Work-alike replacement for event_new() on pre-Libevent-2.0 systems. */
81 struct event *
82 tor_event_new(struct event_base *base, int sock, short what,
83 void (*cb)(int, short, void *), void *arg)
85 struct event *e = tor_malloc_zero(sizeof(struct event));
86 event_set(e, sock, what, cb, arg);
87 if (! base)
88 base = tor_libevent_get_base();
89 event_base_set(base, e);
90 return e;
92 /** Work-alike replacement for evtimer_new() on pre-Libevent-2.0 systems. */
93 struct event *
94 tor_evtimer_new(struct event_base *base,
95 void (*cb)(int, short, void *), void *arg)
97 return tor_event_new(base, -1, 0, cb, arg);
99 /** Work-alike replacement for evsignal_new() on pre-Libevent-2.0 systems. */
100 struct event *
101 tor_evsignal_new(struct event_base * base, int sig,
102 void (*cb)(int, short, void *), void *arg)
104 return tor_event_new(base, sig, EV_SIGNAL|EV_PERSIST, cb, arg);
106 /** Work-alike replacement for event_free() on pre-Libevent-2.0 systems,
107 * except tolerate tor_event_free(NULL). */
108 void
109 tor_event_free(struct event *ev)
111 if (ev == NULL)
112 return;
113 event_del(ev);
114 tor_free(ev);
116 #else
117 /* Wrapper for event_free() that tolerates tor_event_free(NULL) */
118 void
119 tor_event_free(struct event *ev)
121 if (ev == NULL)
122 return;
123 event_free(ev);
125 #endif
127 /** Global event base for use by the main thread. */
128 struct event_base *the_event_base = NULL;
130 /* This is what passes for version detection on OSX. We set
131 * MACOSX_KQUEUE_IS_BROKEN to true iff we're on a version of OSX before
132 * 10.4.0 (aka 1040). */
133 #ifdef __APPLE__
134 #ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
135 #define MACOSX_KQUEUE_IS_BROKEN \
136 (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1040)
137 #else
138 #define MACOSX_KQUEUE_IS_BROKEN 0
139 #endif
140 #endif
142 #ifdef USE_BUFFEREVENTS
143 static int using_iocp_bufferevents = 0;
144 static void tor_libevent_set_tick_timeout(int msec_per_tick);
147 tor_libevent_using_iocp_bufferevents(void)
149 return using_iocp_bufferevents;
151 #endif
153 /** Initialize the Libevent library and set up the event base. */
154 void
155 tor_libevent_initialize(tor_libevent_cfg *torcfg)
157 tor_assert(the_event_base == NULL);
158 /* some paths below don't use torcfg, so avoid unused variable warnings */
159 (void)torcfg;
161 #ifdef HAVE_EVENT2_EVENT_H
163 int attempts = 0;
164 int using_threads;
165 struct event_config *cfg;
167 retry:
168 ++attempts;
169 using_threads = 0;
170 cfg = event_config_new();
171 tor_assert(cfg);
173 #if defined(_WIN32) && defined(USE_BUFFEREVENTS)
174 if (! torcfg->disable_iocp) {
175 evthread_use_windows_threads();
176 event_config_set_flag(cfg, EVENT_BASE_FLAG_STARTUP_IOCP);
177 using_iocp_bufferevents = 1;
178 using_threads = 1;
179 } else {
180 using_iocp_bufferevents = 0;
182 #elif defined(__COVERITY__)
183 /* Avoid a 'dead code' warning below. */
184 using_threads = ! torcfg->disable_iocp;
185 #endif
187 if (!using_threads) {
188 /* Telling Libevent not to try to turn locking on can avoid a needless
189 * socketpair() attempt. */
190 event_config_set_flag(cfg, EVENT_BASE_FLAG_NOLOCK);
193 #if defined(LIBEVENT_VERSION_NUMBER) && LIBEVENT_VERSION_NUMBER >= V(2,0,7)
194 if (torcfg->num_cpus > 0)
195 event_config_set_num_cpus_hint(cfg, torcfg->num_cpus);
196 #endif
198 #if LIBEVENT_VERSION_NUMBER >= V(2,0,9)
199 /* We can enable changelist support with epoll, since we don't give
200 * Libevent any dup'd fds. This lets us avoid some syscalls. */
201 event_config_set_flag(cfg, EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST);
202 #endif
204 the_event_base = event_base_new_with_config(cfg);
206 event_config_free(cfg);
208 if (using_threads && the_event_base == NULL && attempts < 2) {
209 /* This could be a socketpair() failure, which can happen sometimes on
210 * windows boxes with obnoxious firewall rules. Downgrade and try
211 * again. */
212 #if defined(_WIN32) && defined(USE_BUFFEREVENTS)
213 if (torcfg->disable_iocp == 0) {
214 log_warn(LD_GENERAL, "Unable to initialize Libevent. Trying again "
215 "with IOCP disabled.");
216 } else
217 #endif
219 log_warn(LD_GENERAL, "Unable to initialize Libevent. Trying again.");
222 torcfg->disable_iocp = 1;
223 goto retry;
226 #else
227 the_event_base = event_init();
228 #endif
230 if (!the_event_base) {
231 log_err(LD_GENERAL, "Unable to initialize Libevent: cannot continue.");
232 exit(1);
235 /* Making this a NOTICE for now so we can link bugs to a libevent versions
236 * or methods better. */
237 log_info(LD_GENERAL,
238 "Initialized libevent version %s using method %s. Good.",
239 event_get_version(), tor_libevent_get_method());
241 #ifdef USE_BUFFEREVENTS
242 tor_libevent_set_tick_timeout(torcfg->msec_per_tick);
243 #endif
246 /** Return the current Libevent event base that we're set up to use. */
247 MOCK_IMPL(struct event_base *,
248 tor_libevent_get_base, (void))
250 return the_event_base;
253 /** Return the name of the Libevent backend we're using. */
254 const char *
255 tor_libevent_get_method(void)
257 #ifdef HAVE_EVENT2_EVENT_H
258 return event_base_get_method(the_event_base);
259 #else
260 return event_get_method();
261 #endif
264 /** Return the le_version_t for the version of libevent specified in the
265 * string <b>v</b>. If the version is very new or uses an unrecognized
266 * version, format, return LE_OTHER. */
267 STATIC le_version_t
268 tor_decode_libevent_version(const char *v)
270 unsigned major, minor, patchlevel;
271 char c, e, extra;
272 int fields;
274 /* Try the new preferred "1.4.11-stable" format.
275 * Also accept "1.4.14b-stable". */
276 fields = tor_sscanf(v, "%u.%u.%u%c%c", &major, &minor, &patchlevel, &c, &e);
277 if (fields == 3 ||
278 ((fields == 4 || fields == 5 ) && (c == '-' || c == '_')) ||
279 (fields == 5 && TOR_ISALPHA(c) && (e == '-' || e == '_'))) {
280 return V(major,minor,patchlevel);
283 /* Try the old "1.3e" format. */
284 fields = tor_sscanf(v, "%u.%u%c%c", &major, &minor, &c, &extra);
285 if (fields == 3 && TOR_ISALPHA(c)) {
286 return V_OLD(major, minor, c);
287 } else if (fields == 2) {
288 return V(major, minor, 0);
291 return LE_OTHER;
294 /** Return an integer representing the binary interface of a Libevent library.
295 * Two different versions with different numbers are sure not to be binary
296 * compatible. Two different versions with the same numbers have a decent
297 * chance of binary compatibility.*/
298 STATIC int
299 le_versions_compatibility(le_version_t v)
301 if (v == LE_OTHER)
302 return 0;
303 if (v < V_OLD(1,0,'c'))
304 return 1;
305 else if (v < V(1,4,0))
306 return 2;
307 else if (v < V(1,4,99))
308 return 3;
309 else if (v < V(2,0,1))
310 return 4;
311 else /* Everything 2.0 and later should be compatible. */
312 return 5;
315 /** Return a string representation of the version of the currently running
316 * version of Libevent. */
317 const char *
318 tor_libevent_get_version_str(void)
320 return event_get_version();
323 #if defined(LIBEVENT_VERSION)
324 #define HEADER_VERSION LIBEVENT_VERSION
325 #elif defined(_EVENT_VERSION)
326 #define HEADER_VERSION _EVENT_VERSION
327 #endif
329 /** Return a string representation of the version of Libevent that was used
330 * at compilation time. */
331 const char *
332 tor_libevent_get_header_version_str(void)
334 return HEADER_VERSION;
337 /** See whether the headers we were built against differ from the library we
338 * linked against so much that we're likely to crash. If so, warn the
339 * user. */
340 void
341 tor_check_libevent_header_compatibility(void)
343 (void) le_versions_compatibility;
344 (void) tor_decode_libevent_version;
346 /* In libevent versions before 2.0, it's hard to keep binary compatibility
347 * between upgrades, and unpleasant to detect when the version we compiled
348 * against is unlike the version we have linked against. Here's how. */
349 #if defined(HEADER_VERSION)
350 /* We have a header-file version and a function-call version. Easy. */
351 if (strcmp(HEADER_VERSION, event_get_version())) {
352 le_version_t v1, v2;
353 int compat1 = -1, compat2 = -1;
354 int verybad;
355 v1 = tor_decode_libevent_version(HEADER_VERSION);
356 v2 = tor_decode_libevent_version(event_get_version());
357 compat1 = le_versions_compatibility(v1);
358 compat2 = le_versions_compatibility(v2);
360 verybad = compat1 != compat2;
362 tor_log(verybad ? LOG_WARN : LOG_NOTICE,
363 LD_GENERAL, "We were compiled with headers from version %s "
364 "of Libevent, but we're using a Libevent library that says it's "
365 "version %s.", HEADER_VERSION, event_get_version());
366 if (verybad)
367 log_warn(LD_GENERAL, "This will almost certainly make Tor crash.");
368 else
369 log_info(LD_GENERAL, "I think these versions are binary-compatible.");
371 #else
372 /* event_get_version but no _EVENT_VERSION. We might be in 1.4.0-beta or
373 earlier, where that's normal. To see whether we were compiled with an
374 earlier version, let's see whether the struct event defines MIN_HEAP_IDX.
376 #ifdef HAVE_STRUCT_EVENT_MIN_HEAP_IDX
377 /* The header files are 1.4.0-beta or later. If the version is not
378 * 1.4.0-beta, we are incompatible. */
380 if (strcmp(event_get_version(), "1.4.0-beta")) {
381 log_warn(LD_GENERAL, "It's a little hard to tell, but you seem to have "
382 "Libevent 1.4.0-beta header files, whereas you have linked "
383 "against Libevent %s. This will probably make Tor crash.",
384 event_get_version());
387 #else
388 /* Our headers are 1.3e or earlier. If the library version is not 1.4.x or
389 later, we're probably fine. */
391 const char *v = event_get_version();
392 if ((v[0] == '1' && v[2] == '.' && v[3] > '3') || v[0] > '1') {
393 log_warn(LD_GENERAL, "It's a little hard to tell, but you seem to have "
394 "Libevent header file from 1.3e or earlier, whereas you have "
395 "linked against Libevent %s. This will probably make Tor "
396 "crash.", event_get_version());
399 #endif
401 /* Your libevent is ancient. */
402 #endif
406 If possible, we're going to try to use Libevent's periodic timer support,
407 since it does a pretty good job of making sure that periodic events get
408 called exactly M seconds apart, rather than starting each one exactly M
409 seconds after the time that the last one was run.
411 #ifdef HAVE_EVENT2_EVENT_H
412 #define HAVE_PERIODIC
413 #define PERIODIC_FLAGS EV_PERSIST
414 #else
415 #define PERIODIC_FLAGS 0
416 #endif
418 /** Represents a timer that's run every N microseconds by Libevent. */
419 struct periodic_timer_t {
420 /** Underlying event used to implement this periodic event. */
421 struct event *ev;
422 /** The callback we'll be invoking whenever the event triggers */
423 void (*cb)(struct periodic_timer_t *, void *);
424 /** User-supplied data for the callback */
425 void *data;
426 #ifndef HAVE_PERIODIC
427 /** If Libevent doesn't know how to invoke events every N microseconds,
428 * we'll need to remember the timeout interval here. */
429 struct timeval tv;
430 #endif
433 /** Libevent callback to implement a periodic event. */
434 static void
435 periodic_timer_cb(evutil_socket_t fd, short what, void *arg)
437 periodic_timer_t *timer = arg;
438 (void) what;
439 (void) fd;
440 #ifndef HAVE_PERIODIC
441 /** reschedule the event as needed. */
442 event_add(timer->ev, &timer->tv);
443 #endif
444 timer->cb(timer, timer->data);
447 /** Create and schedule a new timer that will run every <b>tv</b> in
448 * the event loop of <b>base</b>. When the timer fires, it will
449 * run the timer in <b>cb</b> with the user-supplied data in <b>data</b>. */
450 periodic_timer_t *
451 periodic_timer_new(struct event_base *base,
452 const struct timeval *tv,
453 void (*cb)(periodic_timer_t *timer, void *data),
454 void *data)
456 periodic_timer_t *timer;
457 tor_assert(base);
458 tor_assert(tv);
459 tor_assert(cb);
460 timer = tor_malloc_zero(sizeof(periodic_timer_t));
461 if (!(timer->ev = tor_event_new(base, -1, PERIODIC_FLAGS,
462 periodic_timer_cb, timer))) {
463 tor_free(timer);
464 return NULL;
466 timer->cb = cb;
467 timer->data = data;
468 #ifndef HAVE_PERIODIC
469 memcpy(&timer->tv, tv, sizeof(struct timeval));
470 #endif
471 event_add(timer->ev, (struct timeval *)tv); /*drop const for old libevent*/
472 return timer;
475 /** Stop and free a periodic timer */
476 void
477 periodic_timer_free(periodic_timer_t *timer)
479 if (!timer)
480 return;
481 tor_event_free(timer->ev);
482 tor_free(timer);
485 #ifdef USE_BUFFEREVENTS
486 static const struct timeval *one_tick = NULL;
488 * Return a special timeout to be passed whenever libevent's O(1) timeout
489 * implementation should be used. Only use this when the timer is supposed
490 * to fire after msec_per_tick ticks have elapsed.
492 const struct timeval *
493 tor_libevent_get_one_tick_timeout(void)
495 tor_assert(one_tick);
496 return one_tick;
499 /** Initialize the common timeout that we'll use to refill the buckets every
500 * time a tick elapses. */
501 static void
502 tor_libevent_set_tick_timeout(int msec_per_tick)
504 struct event_base *base = tor_libevent_get_base();
505 struct timeval tv;
507 tor_assert(! one_tick);
508 tv.tv_sec = msec_per_tick / 1000;
509 tv.tv_usec = (msec_per_tick % 1000) * 1000;
510 one_tick = event_base_init_common_timeout(base, &tv);
513 static struct bufferevent *
514 tor_get_root_bufferevent(struct bufferevent *bev)
516 struct bufferevent *u;
517 while ((u = bufferevent_get_underlying(bev)) != NULL)
518 bev = u;
519 return bev;
523 tor_set_bufferevent_rate_limit(struct bufferevent *bev,
524 struct ev_token_bucket_cfg *cfg)
526 return bufferevent_set_rate_limit(tor_get_root_bufferevent(bev), cfg);
530 tor_add_bufferevent_to_rate_limit_group(struct bufferevent *bev,
531 struct bufferevent_rate_limit_group *g)
533 return bufferevent_add_to_rate_limit_group(tor_get_root_bufferevent(bev), g);
535 #endif
538 tor_init_libevent_rng(void)
540 int rv = 0;
541 #ifdef HAVE_EVUTIL_SECURE_RNG_INIT
542 char buf[256];
543 if (evutil_secure_rng_init() < 0) {
544 rv = -1;
546 /* Older libevent -- manually initialize the RNG */
547 crypto_rand(buf, 32);
548 evutil_secure_rng_add_bytes(buf, 32);
549 evutil_secure_rng_get_bytes(buf, sizeof(buf));
550 #endif
551 return rv;
554 #if defined(LIBEVENT_VERSION_NUMBER) && LIBEVENT_VERSION_NUMBER >= V(2,1,1) \
555 && !defined(TOR_UNIT_TESTS)
556 void
557 tor_gettimeofday_cached(struct timeval *tv)
559 event_base_gettimeofday_cached(the_event_base, tv);
561 void
562 tor_gettimeofday_cache_clear(void)
564 event_base_update_cache_time(the_event_base);
566 #else
567 /** Cache the current hi-res time; the cache gets reset when libevent
568 * calls us. */
569 static struct timeval cached_time_hires = {0, 0};
571 /** Return a fairly recent view of the current time. */
572 void
573 tor_gettimeofday_cached(struct timeval *tv)
575 if (cached_time_hires.tv_sec == 0) {
576 tor_gettimeofday(&cached_time_hires);
578 *tv = cached_time_hires;
581 /** Reset the cached view of the current time, so that the next time we try
582 * to learn it, we will get an up-to-date value. */
583 void
584 tor_gettimeofday_cache_clear(void)
586 cached_time_hires.tv_sec = 0;
589 #ifdef TOR_UNIT_TESTS
590 /** For testing: force-update the cached time to a given value. */
591 void
592 tor_gettimeofday_cache_set(const struct timeval *tv)
594 tor_assert(tv);
595 memcpy(&cached_time_hires, tv, sizeof(*tv));
597 #endif
598 #endif
601 * As tor_gettimeofday_cached, but can never move backwards in time.
603 * The returned value may diverge from wall-clock time, since wall-clock time
604 * can trivially be adjusted backwards, and this can't. Don't mix wall-clock
605 * time with these values in the same calculation.
607 * Depending on implementation, this function may or may not "smooth out" huge
608 * jumps forward in wall-clock time. It may or may not keep its results
609 * advancing forward (as opposed to stalling) if the wall-clock time goes
610 * backwards. The current implementation does neither of of these.
612 * This function is not thread-safe; do not call it outside the main thread.
614 * In future versions of Tor, this may return a time does not have its
615 * origin at the Unix epoch.
617 void
618 tor_gettimeofday_cached_monotonic(struct timeval *tv)
620 struct timeval last_tv = { 0, 0 };
622 tor_gettimeofday_cached(tv);
623 if (timercmp(tv, &last_tv, OP_LT)) {
624 memcpy(tv, &last_tv, sizeof(struct timeval));
625 } else {
626 memcpy(&last_tv, tv, sizeof(struct timeval));