mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-28 06:13:31 +01:00
Merge branch 'ticket26063_squashed'
This commit is contained in:
commit
1eede00a4b
5
changes/ticket26063
Normal file
5
changes/ticket26063
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
o Major features (CPU usage, mobile):
|
||||||
|
- When Tor is disabled (via DisableNetwork or via hibernation), it
|
||||||
|
no longer needs to run any per-second events. This change should
|
||||||
|
make it easier for mobile applications to disable Tor while the
|
||||||
|
device is sleeping, or Tor is not running. Closes ticket 26063.
|
@ -253,10 +253,39 @@ periodic_timer_new(struct event_base *base,
|
|||||||
}
|
}
|
||||||
timer->cb = cb;
|
timer->cb = cb;
|
||||||
timer->data = data;
|
timer->data = data;
|
||||||
event_add(timer->ev, (struct timeval *)tv); /*drop const for old libevent*/
|
periodic_timer_launch(timer, tv);
|
||||||
return timer;
|
return timer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Launch the timer <b>timer</b> to run at <b>tv</b> from now, and every
|
||||||
|
* <b>tv</b> thereafter.
|
||||||
|
*
|
||||||
|
* If the timer is already enabled, this function does nothing.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
periodic_timer_launch(periodic_timer_t *timer, const struct timeval *tv)
|
||||||
|
{
|
||||||
|
tor_assert(timer);
|
||||||
|
if (event_pending(timer->ev, EV_TIMEOUT, NULL))
|
||||||
|
return;
|
||||||
|
event_add(timer->ev, tv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable the provided <b>timer</b>, but do not free it.
|
||||||
|
*
|
||||||
|
* You can reenable the same timer later with periodic_timer_launch.
|
||||||
|
*
|
||||||
|
* If the timer is already disabled, this function does nothing.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
periodic_timer_disable(periodic_timer_t *timer)
|
||||||
|
{
|
||||||
|
tor_assert(timer);
|
||||||
|
event_del(timer->ev);
|
||||||
|
}
|
||||||
|
|
||||||
/** Stop and free a periodic timer */
|
/** Stop and free a periodic timer */
|
||||||
void
|
void
|
||||||
periodic_timer_free_(periodic_timer_t *timer)
|
periodic_timer_free_(periodic_timer_t *timer)
|
||||||
|
@ -31,6 +31,8 @@ periodic_timer_t *periodic_timer_new(struct event_base *base,
|
|||||||
void (*cb)(periodic_timer_t *timer, void *data),
|
void (*cb)(periodic_timer_t *timer, void *data),
|
||||||
void *data);
|
void *data);
|
||||||
void periodic_timer_free_(periodic_timer_t *);
|
void periodic_timer_free_(periodic_timer_t *);
|
||||||
|
void periodic_timer_launch(periodic_timer_t *, const struct timeval *tv);
|
||||||
|
void periodic_timer_disable(periodic_timer_t *);
|
||||||
#define periodic_timer_free(t) \
|
#define periodic_timer_free(t) \
|
||||||
FREE_AND_NULL(periodic_timer_t, periodic_timer_free_, (t))
|
FREE_AND_NULL(periodic_timer_t, periodic_timer_free_, (t))
|
||||||
|
|
||||||
|
@ -1449,9 +1449,9 @@ options_act_reversible(const or_options_t *old_options, char **msg)
|
|||||||
consider_hibernation(time(NULL));
|
consider_hibernation(time(NULL));
|
||||||
|
|
||||||
/* Launch the listeners. (We do this before we setuid, so we can bind to
|
/* Launch the listeners. (We do this before we setuid, so we can bind to
|
||||||
* ports under 1024.) We don't want to rebind if we're hibernating. If
|
* ports under 1024.) We don't want to rebind if we're hibernating or
|
||||||
* networking is disabled, this will close all but the control listeners,
|
* shutting down. If networking is disabled, this will close all but the
|
||||||
* but disable those. */
|
* control listeners, but disable those. */
|
||||||
if (!we_are_hibernating()) {
|
if (!we_are_hibernating()) {
|
||||||
if (retry_all_listeners(replaced_listeners, new_listeners,
|
if (retry_all_listeners(replaced_listeners, new_listeners,
|
||||||
options->DisableNetwork) < 0) {
|
options->DisableNetwork) < 0) {
|
||||||
@ -2001,6 +2001,9 @@ options_act(const or_options_t *old_options)
|
|||||||
finish_daemon(options->DataDirectory);
|
finish_daemon(options->DataDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* See whether we need to enable/disable our once-a-second timer. */
|
||||||
|
reschedule_per_second_timer();
|
||||||
|
|
||||||
/* We want to reinit keys as needed before we do much of anything else:
|
/* We want to reinit keys as needed before we do much of anything else:
|
||||||
keys are important, and other things can depend on them. */
|
keys are important, and other things can depend on them. */
|
||||||
if (transition_affects_workers ||
|
if (transition_affects_workers ||
|
||||||
|
@ -1762,13 +1762,13 @@ connection_connect_sockaddr,(connection_t *conn,
|
|||||||
tor_assert(sa);
|
tor_assert(sa);
|
||||||
tor_assert(socket_error);
|
tor_assert(socket_error);
|
||||||
|
|
||||||
if (get_options()->DisableNetwork) {
|
if (net_is_completely_disabled()) {
|
||||||
/* We should never even try to connect anyplace if DisableNetwork is set.
|
/* We should never even try to connect anyplace if the network is
|
||||||
* Warn if we do, and refuse to make the connection.
|
* completely shut off.
|
||||||
*
|
*
|
||||||
* We only check DisableNetwork here, not we_are_hibernating(), since
|
* (We don't check net_is_disabled() here, since we still sometimes
|
||||||
* we'll still try to fulfill client requests sometimes in the latter case
|
* want to open connections when we're in soft hibernation.)
|
||||||
* (if it is soft hibernation) */
|
*/
|
||||||
static ratelim_t disablenet_violated = RATELIM_INIT(30*60);
|
static ratelim_t disablenet_violated = RATELIM_INIT(30*60);
|
||||||
*socket_error = SOCK_ERRNO(ENETUNREACH);
|
*socket_error = SOCK_ERRNO(ENETUNREACH);
|
||||||
log_fn_ratelim(&disablenet_violated, LOG_WARN, LD_BUG,
|
log_fn_ratelim(&disablenet_violated, LOG_WARN, LD_BUG,
|
||||||
|
@ -3537,6 +3537,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
|
|||||||
n_stream->base_.state = EXIT_CONN_STATE_RESOLVEFAILED;
|
n_stream->base_.state = EXIT_CONN_STATE_RESOLVEFAILED;
|
||||||
/* default to failed, change in dns_resolve if it turns out not to fail */
|
/* default to failed, change in dns_resolve if it turns out not to fail */
|
||||||
|
|
||||||
|
/* If we're hibernating or shutting down, we refuse to open new streams. */
|
||||||
if (we_are_hibernating()) {
|
if (we_are_hibernating()) {
|
||||||
relay_send_end_cell_from_edge(rh.stream_id, circ,
|
relay_send_end_cell_from_edge(rh.stream_id, circ,
|
||||||
END_STREAM_REASON_HIBERNATING, NULL);
|
END_STREAM_REASON_HIBERNATING, NULL);
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
/* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
/* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||||
* Copyright (c) 2007-2017, The Tor Project, Inc. */
|
* Copyright (c) 2007-2017, The Tor Project, Inc. */
|
||||||
/* See LICENSE for licensing information */
|
/* See LICENSE for licensing information */
|
||||||
@ -112,6 +113,10 @@ static int disable_log_messages = 0;
|
|||||||
#define EVENT_IS_INTERESTING(e) \
|
#define EVENT_IS_INTERESTING(e) \
|
||||||
(!! (global_event_mask & EVENT_MASK_(e)))
|
(!! (global_event_mask & EVENT_MASK_(e)))
|
||||||
|
|
||||||
|
/** Macro: true if any event from the bitfield 'e' is interesting. */
|
||||||
|
#define ANY_EVENT_IS_INTERESTING(e) \
|
||||||
|
EVENT_IS_INTERESTING(e)
|
||||||
|
|
||||||
/** If we're using cookie-type authentication, how long should our cookies be?
|
/** If we're using cookie-type authentication, how long should our cookies be?
|
||||||
*/
|
*/
|
||||||
#define AUTHENTICATION_COOKIE_LEN 32
|
#define AUTHENTICATION_COOKIE_LEN 32
|
||||||
@ -219,6 +224,7 @@ static void set_cached_network_liveness(int liveness);
|
|||||||
static void flush_queued_events_cb(mainloop_event_t *event, void *arg);
|
static void flush_queued_events_cb(mainloop_event_t *event, void *arg);
|
||||||
|
|
||||||
static char * download_status_to_string(const download_status_t *dl);
|
static char * download_status_to_string(const download_status_t *dl);
|
||||||
|
static void control_get_bytes_rw_last_sec(uint64_t *r, uint64_t *w);
|
||||||
|
|
||||||
/** Given a control event code for a message event, return the corresponding
|
/** Given a control event code for a message event, return the corresponding
|
||||||
* log severity. */
|
* log severity. */
|
||||||
@ -271,6 +277,7 @@ control_update_global_event_mask(void)
|
|||||||
smartlist_t *conns = get_connection_array();
|
smartlist_t *conns = get_connection_array();
|
||||||
event_mask_t old_mask, new_mask;
|
event_mask_t old_mask, new_mask;
|
||||||
old_mask = global_event_mask;
|
old_mask = global_event_mask;
|
||||||
|
int any_old_per_sec_events = control_any_per_second_event_enabled();
|
||||||
|
|
||||||
global_event_mask = 0;
|
global_event_mask = 0;
|
||||||
SMARTLIST_FOREACH(conns, connection_t *, _conn,
|
SMARTLIST_FOREACH(conns, connection_t *, _conn,
|
||||||
@ -288,10 +295,13 @@ control_update_global_event_mask(void)
|
|||||||
* we want to hear...*/
|
* we want to hear...*/
|
||||||
control_adjust_event_log_severity();
|
control_adjust_event_log_severity();
|
||||||
|
|
||||||
|
/* Macro: true if ev was false before and is true now. */
|
||||||
|
#define NEWLY_ENABLED(ev) \
|
||||||
|
(! (old_mask & (ev)) && (new_mask & (ev)))
|
||||||
|
|
||||||
/* ...then, if we've started logging stream or circ bw, clear the
|
/* ...then, if we've started logging stream or circ bw, clear the
|
||||||
* appropriate fields. */
|
* appropriate fields. */
|
||||||
if (! (old_mask & EVENT_STREAM_BANDWIDTH_USED) &&
|
if (NEWLY_ENABLED(EVENT_STREAM_BANDWIDTH_USED)) {
|
||||||
(new_mask & EVENT_STREAM_BANDWIDTH_USED)) {
|
|
||||||
SMARTLIST_FOREACH(conns, connection_t *, conn,
|
SMARTLIST_FOREACH(conns, connection_t *, conn,
|
||||||
{
|
{
|
||||||
if (conn->type == CONN_TYPE_AP) {
|
if (conn->type == CONN_TYPE_AP) {
|
||||||
@ -300,10 +310,18 @@ control_update_global_event_mask(void)
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (! (old_mask & EVENT_CIRC_BANDWIDTH_USED) &&
|
if (NEWLY_ENABLED(EVENT_CIRC_BANDWIDTH_USED)) {
|
||||||
(new_mask & EVENT_CIRC_BANDWIDTH_USED)) {
|
|
||||||
clear_circ_bw_fields();
|
clear_circ_bw_fields();
|
||||||
}
|
}
|
||||||
|
if (NEWLY_ENABLED(EVENT_BANDWIDTH_USED)) {
|
||||||
|
uint64_t r, w;
|
||||||
|
control_get_bytes_rw_last_sec(&r, &w);
|
||||||
|
}
|
||||||
|
if (any_old_per_sec_events != control_any_per_second_event_enabled()) {
|
||||||
|
reschedule_per_second_timer();
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef NEWLY_ENABLED
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adjust the log severities that result in control_event_logmsg being called
|
/** Adjust the log severities that result in control_event_logmsg being called
|
||||||
@ -352,6 +370,65 @@ control_event_is_interesting(int event)
|
|||||||
return EVENT_IS_INTERESTING(event);
|
return EVENT_IS_INTERESTING(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Return true if any event that needs to fire once a second is enabled. */
|
||||||
|
int
|
||||||
|
control_any_per_second_event_enabled(void)
|
||||||
|
{
|
||||||
|
return ANY_EVENT_IS_INTERESTING(
|
||||||
|
EVENT_BANDWIDTH_USED |
|
||||||
|
EVENT_CELL_STATS |
|
||||||
|
EVENT_CIRC_BANDWIDTH_USED |
|
||||||
|
EVENT_CONN_BW |
|
||||||
|
EVENT_STREAM_BANDWIDTH_USED
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The value of 'get_bytes_read()' the previous time that
|
||||||
|
* control_get_bytes_rw_last_sec() as called. */
|
||||||
|
static uint64_t stats_prev_n_read = 0;
|
||||||
|
/* The value of 'get_bytes_written()' the previous time that
|
||||||
|
* control_get_bytes_rw_last_sec() as called. */
|
||||||
|
static uint64_t stats_prev_n_written = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set <b>n_read</b> and <b>n_written</b> to the total number of bytes read
|
||||||
|
* and written by Tor since the last call to this function.
|
||||||
|
*
|
||||||
|
* Call this only from the main thread.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
control_get_bytes_rw_last_sec(uint64_t *n_read,
|
||||||
|
uint64_t *n_written)
|
||||||
|
{
|
||||||
|
const uint64_t stats_n_bytes_read = get_bytes_read();
|
||||||
|
const uint64_t stats_n_bytes_written = get_bytes_written();
|
||||||
|
|
||||||
|
*n_read = stats_n_bytes_read - stats_prev_n_read;
|
||||||
|
*n_written = stats_n_bytes_written - stats_prev_n_written;
|
||||||
|
stats_prev_n_read = stats_n_bytes_read;
|
||||||
|
stats_prev_n_written = stats_n_bytes_written;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run all the controller events (if any) that are scheduled to trigger once
|
||||||
|
* per second.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
control_per_second_events(void)
|
||||||
|
{
|
||||||
|
if (!control_any_per_second_event_enabled())
|
||||||
|
return;
|
||||||
|
|
||||||
|
uint64_t bytes_read, bytes_written;
|
||||||
|
control_get_bytes_rw_last_sec(&bytes_read, &bytes_written);
|
||||||
|
control_event_bandwidth_used((uint32_t)bytes_read,(uint32_t)bytes_written);
|
||||||
|
|
||||||
|
control_event_stream_bandwidth_used();
|
||||||
|
control_event_conn_bandwidth_used();
|
||||||
|
control_event_circ_bandwidth_used();
|
||||||
|
control_event_circuit_cell_stats();
|
||||||
|
}
|
||||||
|
|
||||||
/** Append a NUL-terminated string <b>s</b> to the end of
|
/** Append a NUL-terminated string <b>s</b> to the end of
|
||||||
* <b>conn</b>-\>outbuf.
|
* <b>conn</b>-\>outbuf.
|
||||||
*/
|
*/
|
||||||
@ -7035,6 +7112,8 @@ control_event_bootstrap_problem(const char *warn, const char *reason,
|
|||||||
if (bootstrap_problems >= BOOTSTRAP_PROBLEM_THRESHOLD)
|
if (bootstrap_problems >= BOOTSTRAP_PROBLEM_THRESHOLD)
|
||||||
dowarn = 1;
|
dowarn = 1;
|
||||||
|
|
||||||
|
/* Don't warn about our bootstrapping status if we are hibernating or
|
||||||
|
* shutting down. */
|
||||||
if (we_are_hibernating())
|
if (we_are_hibernating())
|
||||||
dowarn = 0;
|
dowarn = 0;
|
||||||
|
|
||||||
@ -7606,6 +7685,8 @@ control_free_all(void)
|
|||||||
{
|
{
|
||||||
smartlist_t *queued_events = NULL;
|
smartlist_t *queued_events = NULL;
|
||||||
|
|
||||||
|
stats_prev_n_read = stats_prev_n_written = 0;
|
||||||
|
|
||||||
if (authentication_cookie) /* Free the auth cookie */
|
if (authentication_cookie) /* Free the auth cookie */
|
||||||
tor_free(authentication_cookie);
|
tor_free(authentication_cookie);
|
||||||
if (detached_onion_services) { /* Free the detached onion services */
|
if (detached_onion_services) { /* Free the detached onion services */
|
||||||
|
@ -40,6 +40,9 @@ int connection_control_process_inbuf(control_connection_t *conn);
|
|||||||
#define EVENT_NS 0x000F
|
#define EVENT_NS 0x000F
|
||||||
int control_event_is_interesting(int event);
|
int control_event_is_interesting(int event);
|
||||||
|
|
||||||
|
void control_per_second_events(void);
|
||||||
|
int control_any_per_second_event_enabled(void);
|
||||||
|
|
||||||
int control_event_circuit_status(origin_circuit_t *circ,
|
int control_event_circuit_status(origin_circuit_t *circ,
|
||||||
circuit_status_event_t e, int reason);
|
circuit_status_event_t e, int reason);
|
||||||
int control_event_circuit_purpose_changed(origin_circuit_t *circ,
|
int control_event_circuit_purpose_changed(origin_circuit_t *circ,
|
||||||
|
@ -955,7 +955,7 @@ dirserv_set_router_is_running(routerinfo_t *router, time_t now)
|
|||||||
tor_assert(node);
|
tor_assert(node);
|
||||||
|
|
||||||
if (router_is_me(router)) {
|
if (router_is_me(router)) {
|
||||||
/* We always know if we are down ourselves. */
|
/* We always know if we are shutting down or hibernating ourselves. */
|
||||||
answer = ! we_are_hibernating();
|
answer = ! we_are_hibernating();
|
||||||
} else if (router->is_hibernating &&
|
} else if (router->is_hibernating &&
|
||||||
(router->cache_info.published_on +
|
(router->cache_info.published_on +
|
||||||
|
@ -883,13 +883,26 @@ hibernate_begin_shutdown(void)
|
|||||||
hibernate_begin(HIBERNATE_STATE_EXITING, time(NULL));
|
hibernate_begin(HIBERNATE_STATE_EXITING, time(NULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return true iff we are currently hibernating. */
|
/**
|
||||||
|
* Return true iff we are currently hibernating -- that is, if we are in
|
||||||
|
* any non-live state.
|
||||||
|
*/
|
||||||
MOCK_IMPL(int,
|
MOCK_IMPL(int,
|
||||||
we_are_hibernating,(void))
|
we_are_hibernating,(void))
|
||||||
{
|
{
|
||||||
return hibernate_state != HIBERNATE_STATE_LIVE;
|
return hibernate_state != HIBERNATE_STATE_LIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true iff we are currently _fully_ hibernating -- that is, if we are
|
||||||
|
* in a state where we expect to handle no network activity at all.
|
||||||
|
*/
|
||||||
|
MOCK_IMPL(int,
|
||||||
|
we_are_fully_hibernating,(void))
|
||||||
|
{
|
||||||
|
return hibernate_state == HIBERNATE_STATE_DORMANT;
|
||||||
|
}
|
||||||
|
|
||||||
/** If we aren't currently dormant, close all connections and become
|
/** If we aren't currently dormant, close all connections and become
|
||||||
* dormant. */
|
* dormant. */
|
||||||
static void
|
static void
|
||||||
@ -1187,6 +1200,8 @@ on_hibernate_state_change(hibernate_state_t prev_state)
|
|||||||
if (prev_state != HIBERNATE_STATE_INITIAL) {
|
if (prev_state != HIBERNATE_STATE_INITIAL) {
|
||||||
rescan_periodic_events(get_options());
|
rescan_periodic_events(get_options());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reschedule_per_second_timer();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Free all resources held by the accounting module */
|
/** Free all resources held by the accounting module */
|
||||||
|
@ -25,6 +25,7 @@ void accounting_add_bytes(size_t n_read, size_t n_written, int seconds);
|
|||||||
int accounting_record_bandwidth_usage(time_t now, or_state_t *state);
|
int accounting_record_bandwidth_usage(time_t now, or_state_t *state);
|
||||||
void hibernate_begin_shutdown(void);
|
void hibernate_begin_shutdown(void);
|
||||||
MOCK_DECL(int, we_are_hibernating, (void));
|
MOCK_DECL(int, we_are_hibernating, (void));
|
||||||
|
MOCK_DECL(int, we_are_fully_hibernating,(void));
|
||||||
void consider_hibernation(time_t now);
|
void consider_hibernation(time_t now);
|
||||||
int getinfo_helper_accounting(control_connection_t *conn,
|
int getinfo_helper_accounting(control_connection_t *conn,
|
||||||
const char *question, char **answer,
|
const char *question, char **answer,
|
||||||
|
@ -163,11 +163,6 @@ token_bucket_rw_t global_bucket;
|
|||||||
/* Token bucket for relayed traffic. */
|
/* Token bucket for relayed traffic. */
|
||||||
token_bucket_rw_t global_relayed_bucket;
|
token_bucket_rw_t global_relayed_bucket;
|
||||||
|
|
||||||
/* DOCDOC stats_prev_n_read */
|
|
||||||
static uint64_t stats_prev_n_read = 0;
|
|
||||||
/* DOCDOC stats_prev_n_written */
|
|
||||||
static uint64_t stats_prev_n_written = 0;
|
|
||||||
|
|
||||||
/* XXX we might want to keep stats about global_relayed_*_bucket too. Or not.*/
|
/* XXX we might want to keep stats about global_relayed_*_bucket too. Or not.*/
|
||||||
/** How many bytes have we read since we started the process? */
|
/** How many bytes have we read since we started the process? */
|
||||||
static uint64_t stats_n_bytes_read = 0;
|
static uint64_t stats_n_bytes_read = 0;
|
||||||
@ -1258,7 +1253,8 @@ run_connection_housekeeping(int i, time_t now)
|
|||||||
} else if (we_are_hibernating() &&
|
} else if (we_are_hibernating() &&
|
||||||
! have_any_circuits &&
|
! have_any_circuits &&
|
||||||
!connection_get_outbuf_len(conn)) {
|
!connection_get_outbuf_len(conn)) {
|
||||||
/* We're hibernating, there's no circuits, and nothing to flush.*/
|
/* We're hibernating or shutting down, there's no circuits, and nothing to
|
||||||
|
* flush.*/
|
||||||
log_info(LD_OR,"Expiring non-used OR connection to fd %d (%s:%d) "
|
log_info(LD_OR,"Expiring non-used OR connection to fd %d (%s:%d) "
|
||||||
"[Hibernating or exiting].",
|
"[Hibernating or exiting].",
|
||||||
(int)conn->s,conn->address, conn->port);
|
(int)conn->s,conn->address, conn->port);
|
||||||
@ -2495,6 +2491,36 @@ hs_service_callback(time_t now, const or_options_t *options)
|
|||||||
|
|
||||||
/** Timer: used to invoke second_elapsed_callback() once per second. */
|
/** Timer: used to invoke second_elapsed_callback() once per second. */
|
||||||
static periodic_timer_t *second_timer = NULL;
|
static periodic_timer_t *second_timer = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable or disable the per-second timer as appropriate, creating it if
|
||||||
|
* necessary.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
reschedule_per_second_timer(void)
|
||||||
|
{
|
||||||
|
struct timeval one_second;
|
||||||
|
one_second.tv_sec = 1;
|
||||||
|
one_second.tv_usec = 0;
|
||||||
|
|
||||||
|
if (! second_timer) {
|
||||||
|
second_timer = periodic_timer_new(tor_libevent_get_base(),
|
||||||
|
&one_second,
|
||||||
|
second_elapsed_callback,
|
||||||
|
NULL);
|
||||||
|
tor_assert(second_timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool run_per_second_events =
|
||||||
|
control_any_per_second_event_enabled() || ! net_is_completely_disabled();
|
||||||
|
|
||||||
|
if (run_per_second_events) {
|
||||||
|
periodic_timer_launch(second_timer, &one_second);
|
||||||
|
} else {
|
||||||
|
periodic_timer_disable(second_timer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** Last time that update_current_time was called. */
|
/** Last time that update_current_time was called. */
|
||||||
static time_t current_second = 0;
|
static time_t current_second = 0;
|
||||||
/** Last time that update_current_time updated current_second. */
|
/** Last time that update_current_time updated current_second. */
|
||||||
@ -2568,8 +2594,6 @@ second_elapsed_callback(periodic_timer_t *timer, void *arg)
|
|||||||
* could use Libevent's timers for this rather than checking the current
|
* could use Libevent's timers for this rather than checking the current
|
||||||
* time against a bunch of timeouts every second. */
|
* time against a bunch of timeouts every second. */
|
||||||
time_t now;
|
time_t now;
|
||||||
size_t bytes_written;
|
|
||||||
size_t bytes_read;
|
|
||||||
(void)timer;
|
(void)timer;
|
||||||
(void)arg;
|
(void)arg;
|
||||||
|
|
||||||
@ -2581,18 +2605,8 @@ second_elapsed_callback(periodic_timer_t *timer, void *arg)
|
|||||||
*/
|
*/
|
||||||
update_current_time(now);
|
update_current_time(now);
|
||||||
|
|
||||||
/* the second has rolled over. check more stuff. */
|
/* Maybe some controller events are ready to fire */
|
||||||
// remove this once it's unneeded
|
control_per_second_events();
|
||||||
bytes_read = (size_t)(stats_n_bytes_read - stats_prev_n_read);
|
|
||||||
bytes_written = (size_t)(stats_n_bytes_written - stats_prev_n_written);
|
|
||||||
stats_prev_n_read = stats_n_bytes_read;
|
|
||||||
stats_prev_n_written = stats_n_bytes_written;
|
|
||||||
|
|
||||||
control_event_bandwidth_used((uint32_t)bytes_read,(uint32_t)bytes_written);
|
|
||||||
control_event_stream_bandwidth_used();
|
|
||||||
control_event_conn_bandwidth_used();
|
|
||||||
control_event_circ_bandwidth_used();
|
|
||||||
control_event_circuit_cell_stats();
|
|
||||||
|
|
||||||
run_scheduled_events(now);
|
run_scheduled_events(now);
|
||||||
}
|
}
|
||||||
@ -2872,17 +2886,7 @@ do_main_loop(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* set up once-a-second callback. */
|
/* set up once-a-second callback. */
|
||||||
if (! second_timer) {
|
reschedule_per_second_timer();
|
||||||
struct timeval one_second;
|
|
||||||
one_second.tv_sec = 1;
|
|
||||||
one_second.tv_usec = 0;
|
|
||||||
|
|
||||||
second_timer = periodic_timer_new(tor_libevent_get_base(),
|
|
||||||
&one_second,
|
|
||||||
second_elapsed_callback,
|
|
||||||
NULL);
|
|
||||||
tor_assert(second_timer);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_SYSTEMD_209
|
#ifdef HAVE_SYSTEMD_209
|
||||||
uint64_t watchdog_delay;
|
uint64_t watchdog_delay;
|
||||||
@ -3697,7 +3701,6 @@ tor_free_all(int postfork)
|
|||||||
|
|
||||||
memset(&global_bucket, 0, sizeof(global_bucket));
|
memset(&global_bucket, 0, sizeof(global_bucket));
|
||||||
memset(&global_relayed_bucket, 0, sizeof(global_relayed_bucket));
|
memset(&global_relayed_bucket, 0, sizeof(global_relayed_bucket));
|
||||||
stats_prev_n_read = stats_prev_n_written = 0;
|
|
||||||
stats_n_bytes_read = stats_n_bytes_written = 0;
|
stats_n_bytes_read = stats_n_bytes_written = 0;
|
||||||
time_of_process_start = 0;
|
time_of_process_start = 0;
|
||||||
time_of_last_signewnym = 0;
|
time_of_last_signewnym = 0;
|
||||||
|
@ -94,6 +94,7 @@ uint64_t get_main_loop_error_count(void);
|
|||||||
uint64_t get_main_loop_idle_count(void);
|
uint64_t get_main_loop_idle_count(void);
|
||||||
|
|
||||||
void periodic_events_on_new_options(const or_options_t *options);
|
void periodic_events_on_new_options(const or_options_t *options);
|
||||||
|
void reschedule_per_second_timer(void);
|
||||||
|
|
||||||
extern time_t time_of_process_start;
|
extern time_t time_of_process_start;
|
||||||
extern int quiet_level;
|
extern int quiet_level;
|
||||||
|
@ -1599,15 +1599,24 @@ router_perform_bandwidth_test(int num_circs, time_t now)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return true iff our network is in some sense disabled: either we're
|
/** Return true iff our network is in some sense disabled or shutting down:
|
||||||
* hibernating, entering hibernation, or the network is turned off with
|
* either we're hibernating, entering hibernation, or the network is turned
|
||||||
* DisableNetwork. */
|
* off with DisableNetwork. */
|
||||||
int
|
int
|
||||||
net_is_disabled(void)
|
net_is_disabled(void)
|
||||||
{
|
{
|
||||||
return get_options()->DisableNetwork || we_are_hibernating();
|
return get_options()->DisableNetwork || we_are_hibernating();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Return true iff our network is in some sense "completely disabled" either
|
||||||
|
* we're fully hibernating or the network is turned off with
|
||||||
|
* DisableNetwork. */
|
||||||
|
int
|
||||||
|
net_is_completely_disabled(void)
|
||||||
|
{
|
||||||
|
return get_options()->DisableNetwork || we_are_fully_hibernating();
|
||||||
|
}
|
||||||
|
|
||||||
/** Return true iff we believe ourselves to be an authoritative
|
/** Return true iff we believe ourselves to be an authoritative
|
||||||
* directory server.
|
* directory server.
|
||||||
*/
|
*/
|
||||||
@ -2268,6 +2277,7 @@ router_build_fresh_descriptor(routerinfo_t **r, extrainfo_t **e)
|
|||||||
/* and compute ri->bandwidthburst similarly */
|
/* and compute ri->bandwidthburst similarly */
|
||||||
ri->bandwidthburst = get_effective_bwburst(options);
|
ri->bandwidthburst = get_effective_bwburst(options);
|
||||||
|
|
||||||
|
/* Report bandwidth, unless we're hibernating or shutting down */
|
||||||
ri->bandwidthcapacity = hibernating ? 0 : rep_hist_bandwidth_assess();
|
ri->bandwidthcapacity = hibernating ? 0 : rep_hist_bandwidth_assess();
|
||||||
|
|
||||||
if (dns_seems_to_be_broken() || has_dns_init_failed()) {
|
if (dns_seems_to_be_broken() || has_dns_init_failed()) {
|
||||||
@ -2538,6 +2548,8 @@ check_descriptor_bandwidth_changed(time_t now)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
prev = router_get_my_routerinfo()->bandwidthcapacity;
|
prev = router_get_my_routerinfo()->bandwidthcapacity;
|
||||||
|
/* Consider ourselves to have zero bandwidth if we're hibernating or
|
||||||
|
* shutting down. */
|
||||||
cur = we_are_hibernating() ? 0 : rep_hist_bandwidth_assess();
|
cur = we_are_hibernating() ? 0 : rep_hist_bandwidth_assess();
|
||||||
if ((prev != cur && (!prev || !cur)) ||
|
if ((prev != cur && (!prev || !cur)) ||
|
||||||
cur > prev*2 ||
|
cur > prev*2 ||
|
||||||
|
@ -53,6 +53,7 @@ void router_dirport_found_reachable(void);
|
|||||||
void router_perform_bandwidth_test(int num_circs, time_t now);
|
void router_perform_bandwidth_test(int num_circs, time_t now);
|
||||||
|
|
||||||
int net_is_disabled(void);
|
int net_is_disabled(void);
|
||||||
|
int net_is_completely_disabled(void);
|
||||||
|
|
||||||
int authdir_mode(const or_options_t *options);
|
int authdir_mode(const or_options_t *options);
|
||||||
int authdir_mode_handles_descs(const or_options_t *options, int purpose);
|
int authdir_mode_handles_descs(const or_options_t *options, int purpose);
|
||||||
|
Loading…
Reference in New Issue
Block a user