aboutsummaryrefslogtreecommitdiff
path: root/src/or/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/or/main.c')
-rw-r--r--src/or/main.c156
1 files changed, 137 insertions, 19 deletions
diff --git a/src/or/main.c b/src/or/main.c
index 3139381f30..7b1f4975f7 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -1,7 +1,7 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2016, The Tor Project, Inc. */
+ * Copyright (c) 2007-2017, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
@@ -54,15 +54,19 @@
#include "buffers.h"
#include "channel.h"
#include "channeltls.h"
+#include "channelpadding.h"
#include "circuitbuild.h"
#include "circuitlist.h"
#include "circuituse.h"
#include "command.h"
+#include "compat_rust.h"
+#include "compress.h"
#include "config.h"
#include "confparse.h"
#include "connection.h"
#include "connection_edge.h"
#include "connection_or.h"
+#include "consdiffmgr.h"
#include "control.h"
#include "cpuworker.h"
#include "crypto_s2k.h"
@@ -104,7 +108,6 @@
#include "ext_orport.h"
#ifdef USE_DMALLOC
#include <dmalloc.h>
-#include <openssl/crypto.h>
#endif
#include "memarea.h"
#include "sandbox.h"
@@ -176,7 +179,7 @@ static int signewnym_is_pending = 0;
static unsigned newnym_epoch = 0;
/** Smartlist of all open connections. */
-static smartlist_t *connection_array = NULL;
+STATIC smartlist_t *connection_array = NULL;
/** List of connections that have been marked for close and need to be freed
* and removed from connection_array. */
static smartlist_t *closeable_connection_lst = NULL;
@@ -1095,8 +1098,9 @@ run_connection_housekeeping(int i, time_t now)
} else if (!have_any_circuits &&
now - or_conn->idle_timeout >=
chan->timestamp_last_had_circuits) {
- log_info(LD_OR,"Expiring non-used OR connection to fd %d (%s:%d) "
- "[no circuits for %d; timeout %d; %scanonical].",
+ log_info(LD_OR,"Expiring non-used OR connection "U64_FORMAT" to fd %d "
+ "(%s:%d) [no circuits for %d; timeout %d; %scanonical].",
+ U64_PRINTF_ARG(chan->global_identifier),
(int)conn->s, conn->address, conn->port,
(int)(now - chan->timestamp_last_had_circuits),
or_conn->idle_timeout,
@@ -1119,6 +1123,8 @@ run_connection_housekeeping(int i, time_t now)
memset(&cell,0,sizeof(cell_t));
cell.command = CELL_PADDING;
connection_or_write_cell_to_buf(&cell, or_conn);
+ } else {
+ channelpadding_decide_to_pad_channel(chan);
}
}
@@ -1161,6 +1167,7 @@ static int periodic_events_initialized = 0;
#define CALLBACK(name) \
static int name ## _callback(time_t, const or_options_t *)
CALLBACK(rotate_onion_key);
+CALLBACK(check_onion_keys_expiry_time);
CALLBACK(check_ed_keys);
CALLBACK(launch_descriptor_fetches);
CALLBACK(rotate_x509_certificate);
@@ -1184,6 +1191,9 @@ CALLBACK(check_dns_honesty);
CALLBACK(write_bridge_ns);
CALLBACK(check_fw_helper_app);
CALLBACK(heartbeat);
+CALLBACK(clean_consdiffmgr);
+CALLBACK(reset_padding_counts);
+CALLBACK(check_canonical_channels);
#undef CALLBACK
@@ -1192,6 +1202,7 @@ CALLBACK(heartbeat);
static periodic_event_item_t periodic_events[] = {
CALLBACK(rotate_onion_key),
+ CALLBACK(check_onion_keys_expiry_time),
CALLBACK(check_ed_keys),
CALLBACK(launch_descriptor_fetches),
CALLBACK(rotate_x509_certificate),
@@ -1215,6 +1226,9 @@ static periodic_event_item_t periodic_events[] = {
CALLBACK(write_bridge_ns),
CALLBACK(check_fw_helper_app),
CALLBACK(heartbeat),
+ CALLBACK(clean_consdiffmgr),
+ CALLBACK(reset_padding_counts),
+ CALLBACK(check_canonical_channels),
END_OF_PERIODIC_EVENTS
};
#undef CALLBACK
@@ -1470,19 +1484,26 @@ run_scheduled_events(time_t now)
/* 11b. check pending unconfigured managed proxies */
if (!net_is_disabled() && pt_proxies_configuration_pending())
pt_configure_remaining_proxies();
+
+ /* 12. launch diff computations. (This is free if there are none to
+ * launch.) */
+ if (dir_server_mode(options)) {
+ consdiffmgr_rescan();
+ }
}
-/* Periodic callback: Every MIN_ONION_KEY_LIFETIME seconds, rotate the onion
- * keys, shut down and restart all cpuworkers, and update our descriptor if
- * necessary.
+/* Periodic callback: rotate the onion keys after the period defined by the
+ * "onion-key-rotation-days" consensus parameter, shut down and restart all
+ * cpuworkers, and update our descriptor if necessary.
*/
static int
rotate_onion_key_callback(time_t now, const or_options_t *options)
{
if (server_mode(options)) {
- time_t rotation_time = get_onion_key_set_at()+MIN_ONION_KEY_LIFETIME;
+ int onion_key_lifetime = get_onion_key_lifetime();
+ time_t rotation_time = get_onion_key_set_at()+onion_key_lifetime;
if (rotation_time > now) {
- return safe_timer_diff(now, rotation_time);
+ return ONION_KEY_CONSENSUS_CHECK_INTERVAL;
}
log_info(LD_GENERAL,"Rotating onion key.");
@@ -1493,11 +1514,35 @@ rotate_onion_key_callback(time_t now, const or_options_t *options)
}
if (advertised_server_mode() && !options->DisableNetwork)
router_upload_dir_desc_to_dirservers(0);
- return MIN_ONION_KEY_LIFETIME;
+ return ONION_KEY_CONSENSUS_CHECK_INTERVAL;
}
return PERIODIC_EVENT_NO_UPDATE;
}
+/* Period callback: Check if our old onion keys are still valid after the
+ * period of time defined by the consensus parameter
+ * "onion-key-grace-period-days", otherwise expire them by setting them to
+ * NULL.
+ */
+static int
+check_onion_keys_expiry_time_callback(time_t now, const or_options_t *options)
+{
+ if (server_mode(options)) {
+ int onion_key_grace_period = get_onion_key_grace_period();
+ time_t expiry_time = get_onion_key_set_at()+onion_key_grace_period;
+ if (expiry_time > now) {
+ return ONION_KEY_CONSENSUS_CHECK_INTERVAL;
+ }
+
+ log_info(LD_GENERAL, "Expiring old onion keys.");
+ expire_old_onion_keys();
+ cpuworkers_rotate_keyinfo();
+ return ONION_KEY_CONSENSUS_CHECK_INTERVAL;
+ }
+
+ return PERIODIC_EVENT_NO_UPDATE;
+}
+
/* Periodic callback: Every 30 seconds, check whether it's time to make new
* Ed25519 subkeys.
*/
@@ -1511,7 +1556,7 @@ check_ed_keys_callback(time_t now, const or_options_t *options)
generate_ed_link_cert(options, now, new_signing_key > 0)) {
log_err(LD_OR, "Unable to update Ed25519 keys! Exiting.");
tor_cleanup();
- exit(0);
+ exit(1);
}
}
return 30;
@@ -1726,6 +1771,28 @@ write_stats_file_callback(time_t now, const or_options_t *options)
return safe_timer_diff(now, next_time_to_write_stats_files);
}
+#define CHANNEL_CHECK_INTERVAL (60*60)
+static int
+check_canonical_channels_callback(time_t now, const or_options_t *options)
+{
+ (void)now;
+ if (public_server_mode(options))
+ channel_check_for_duplicates();
+
+ return CHANNEL_CHECK_INTERVAL;
+}
+
+static int
+reset_padding_counts_callback(time_t now, const or_options_t *options)
+{
+ if (options->PaddingStatistics) {
+ rep_hist_prep_published_padding_counts(now);
+ }
+
+ rep_hist_reset_padding_counts();
+ return REPHIST_CELL_PADDING_COUNTS_INTERVAL;
+}
+
/**
* Periodic callback: Write bridge statistics to disk if appropriate.
*/
@@ -2014,6 +2081,17 @@ heartbeat_callback(time_t now, const or_options_t *options)
return options->HeartbeatPeriod;
}
+#define CDM_CLEAN_CALLBACK_INTERVAL 600
+static int
+clean_consdiffmgr_callback(time_t now, const or_options_t *options)
+{
+ (void)now;
+ if (server_mode(options)) {
+ consdiffmgr_cleanup();
+ }
+ return CDM_CLEAN_CALLBACK_INTERVAL;
+}
+
/** Timer: used to invoke second_elapsed_callback() once per second. */
static periodic_timer_t *second_timer = NULL;
/** Number of libevent errors in the last second: we die if we get too many. */
@@ -2343,6 +2421,8 @@ do_main_loop(void)
}
handle_signals(1);
+ monotime_init();
+ timers_initialize();
/* load the private keys, if we're supposed to have them, and set up the
* TLS context. */
@@ -2410,9 +2490,10 @@ do_main_loop(void)
/* launch cpuworkers. Need to do this *after* we've read the onion key. */
cpu_init();
}
+ consdiffmgr_enable_background_compression();
/* Setup shared random protocol subsystem. */
- if (authdir_mode_publishes_statuses(get_options())) {
+ if (authdir_mode_v3(get_options())) {
if (sr_init(1) < 0) {
return -1;
}
@@ -2980,11 +3061,16 @@ tor_init(int argc, char *argv[])
const char *version = get_version();
log_notice(LD_GENERAL, "Tor %s running on %s with Libevent %s, "
- "OpenSSL %s and Zlib %s.", version,
+ "OpenSSL %s, Zlib %s, Liblzma %s, and Libzstd %s.", version,
get_uname(),
tor_libevent_get_version_str(),
crypto_openssl_get_version_str(),
- tor_zlib_get_version_str());
+ tor_compress_supports_method(ZLIB_METHOD) ?
+ tor_compress_version_str(ZLIB_METHOD) : "N/A",
+ tor_compress_supports_method(LZMA_METHOD) ?
+ tor_compress_version_str(LZMA_METHOD) : "N/A",
+ tor_compress_supports_method(ZSTD_METHOD) ?
+ tor_compress_version_str(ZSTD_METHOD) : "N/A");
log_notice(LD_GENERAL, "Tor can't help you if you use it wrong! "
"Learn how to be safe at "
@@ -2995,6 +3081,15 @@ tor_init(int argc, char *argv[])
"Expect more bugs than usual.");
}
+ {
+ rust_str_t rust_str = rust_welcome_string();
+ const char *s = rust_str_get(rust_str);
+ if (strlen(s) > 0) {
+ log_notice(LD_GENERAL, "%s", s);
+ }
+ rust_str_free(rust_str);
+ }
+
if (network_init()<0) {
log_err(LD_BUG,"Error initializing network; exiting.");
return -1;
@@ -3009,6 +3104,13 @@ tor_init(int argc, char *argv[])
/* The options are now initialised */
const or_options_t *options = get_options();
+ /* Initialize channelpadding parameters to defaults until we get
+ * a consensus */
+ channelpadding_new_consensus_params(NULL);
+
+ /* Initialize predicted ports list after loading options */
+ predicted_ports_init();
+
#ifndef _WIN32
if (geteuid()==0)
log_warn(LD_GENERAL,"You are running Tor as root. You don't need to, "
@@ -3066,7 +3168,7 @@ try_locking(const or_options_t *options, int err_if_locked)
r = try_locking(options, 0);
if (r<0) {
log_err(LD_GENERAL, "No, it's still there. Exiting.");
- exit(0);
+ exit(1);
}
return r;
}
@@ -3138,6 +3240,7 @@ tor_free_all(int postfork)
sandbox_free_getaddrinfo_cache();
protover_free_all();
bridges_free_all();
+ consdiffmgr_free_all();
if (!postfork) {
config_free_all();
or_state_free_all();
@@ -3167,6 +3270,7 @@ tor_free_all(int postfork)
if (!postfork) {
escaped(NULL);
esc_router_info(NULL);
+ clean_up_backtrace_handler();
logs_free_all(); /* free log strings. do this last so logs keep working. */
}
}
@@ -3204,6 +3308,9 @@ tor_cleanup(void)
rep_hist_record_mtbf_data(now, 0);
keypin_close_journal();
}
+
+ timers_shutdown();
+
#ifdef USE_DMALLOC
dmalloc_log_stats();
#endif
@@ -3559,6 +3666,8 @@ sandbox_init_filter(void)
OPEN_DATADIR("stats");
STAT_DATADIR("stats");
STAT_DATADIR2("stats", "dirreq-stats");
+
+ consdiffmgr_register_with_sandbox(&cfg);
}
init_addrinfo();
@@ -3575,6 +3684,11 @@ tor_main(int argc, char *argv[])
int result = 0;
#ifdef _WIN32
+#ifndef HeapEnableTerminationOnCorruption
+#define HeapEnableTerminationOnCorruption 1
+#endif
+ /* On heap corruption, just give up; don't try to play along. */
+ HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
/* Call SetProcessDEPPolicy to permanently enable DEP.
The function will not resolve on earlier versions of Windows,
and failure is not dangerous. */
@@ -3583,7 +3697,10 @@ tor_main(int argc, char *argv[])
typedef BOOL (WINAPI *PSETDEP)(DWORD);
PSETDEP setdeppolicy = (PSETDEP)GetProcAddress(hMod,
"SetProcessDEPPolicy");
- if (setdeppolicy) setdeppolicy(1); /* PROCESS_DEP_ENABLE */
+ if (setdeppolicy) {
+ /* PROCESS_DEP_ENABLE | PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION */
+ setdeppolicy(3);
+ }
}
#endif
@@ -3591,14 +3708,15 @@ tor_main(int argc, char *argv[])
update_approx_time(time(NULL));
tor_threads_init();
+ tor_compress_init();
init_logging(0);
monotime_init();
#ifdef USE_DMALLOC
{
/* Instruct OpenSSL to use our internal wrappers for malloc,
realloc and free. */
- int r = CRYPTO_set_mem_ex_functions(tor_malloc_, tor_realloc_, tor_free_);
- tor_assert(r);
+ int r = crypto_use_tor_alloc_functions();
+ tor_assert(r == 0);
}
#endif
#ifdef NT_SERVICE