aboutsummaryrefslogtreecommitdiff
path: root/src/app/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/app/main')
-rw-r--r--src/app/main/main.c114
-rw-r--r--src/app/main/subsysmgr.c202
-rw-r--r--src/app/main/subsysmgr.h24
-rw-r--r--src/app/main/subsystem_list.c49
4 files changed, 311 insertions, 78 deletions
diff --git a/src/app/main/main.c b/src/app/main/main.c
index 67f2181cd5..4b60763f75 100644
--- a/src/app/main/main.c
+++ b/src/app/main/main.c
@@ -15,12 +15,14 @@
#include "app/config/statefile.h"
#include "app/main/main.h"
#include "app/main/ntmain.h"
+#include "app/main/subsysmgr.h"
#include "core/mainloop/connection.h"
#include "core/mainloop/cpuworker.h"
#include "core/mainloop/mainloop.h"
#include "core/mainloop/netstatus.h"
#include "core/or/channel.h"
#include "core/or/channelpadding.h"
+#include "core/or/circuitpadding.h"
#include "core/or/channeltls.h"
#include "core/or/circuitlist.h"
#include "core/or/circuitmux_ewma.h"
@@ -33,6 +35,7 @@
#include "core/or/relay.h"
#include "core/or/scheduler.h"
#include "core/or/status.h"
+#include "core/or/versions.h"
#include "feature/api/tor_api.h"
#include "feature/api/tor_api_internal.h"
#include "feature/client/addressmap.h"
@@ -65,11 +68,11 @@
#include "feature/stats/predict_ports.h"
#include "feature/stats/rephist.h"
#include "lib/compress/compress.h"
-#include "lib/container/buffers.h"
+#include "lib/buf/buffers.h"
#include "lib/crypt_ops/crypto_rand.h"
#include "lib/crypt_ops/crypto_s2k.h"
-#include "lib/err/backtrace.h"
#include "lib/geoip/geoip.h"
+#include "lib/net/resolve.h"
#include "lib/process/waitpid.h"
@@ -83,6 +86,7 @@
#include "lib/encoding/confline.h"
#include "lib/evloop/timers.h"
#include "lib/crypt_ops/crypto_init.h"
+#include "lib/version/torversion.h"
#include <event2/event.h>
@@ -301,6 +305,19 @@ process_signal(int sig)
log_heartbeat(time(NULL));
control_event_signal(sig);
break;
+ case SIGACTIVE:
+ /* "SIGACTIVE" counts as ersatz user activity. */
+ note_user_activity(approx_time());
+ control_event_signal(sig);
+ break;
+ case SIGDORMANT:
+ /* "SIGDORMANT" means to ignore past user activity */
+ log_notice(LD_GENERAL, "Going dormant because of controller request.");
+ reset_user_activity(0);
+ set_network_participation(false);
+ schedule_rescan_periodic_events();
+ control_event_signal(sig);
+ break;
}
}
@@ -426,18 +443,6 @@ dumpstats(int severity)
rend_service_dump_stats(severity);
}
-/** Called by exit() as we shut down the process.
- */
-static void
-exit_function(void)
-{
- /* NOTE: If we ever daemonize, this gets called immediately. That's
- * okay for now, because we only use this on Windows. */
-#ifdef _WIN32
- WSACleanup();
-#endif
-}
-
#ifdef _WIN32
#define UNIX_ONLY 0
#else
@@ -482,6 +487,8 @@ static struct {
{ SIGNEWNYM, 0, NULL },
{ SIGCLEARDNSCACHE, 0, NULL },
{ SIGHEARTBEAT, 0, NULL },
+ { SIGACTIVE, 0, NULL },
+ { SIGDORMANT, 0, NULL },
{ -1, -1, NULL }
};
@@ -546,18 +553,13 @@ tor_init(int argc, char *argv[])
tor_snprintf(progname, sizeof(progname), "Tor %s", get_version());
log_set_application_name(progname);
- /* Set up the crypto nice and early */
- if (crypto_early_init() < 0) {
- log_err(LD_GENERAL, "Unable to initialize the crypto subsystem!");
- return -1;
- }
-
/* Initialize the history structures. */
rep_hist_init();
/* Initialize the service cache. */
rend_cache_init();
addressmap_init(); /* Init the client dns cache. Do it always, since it's
* cheap. */
+
/* Initialize the HS subsystem. */
hs_init();
@@ -632,12 +634,6 @@ tor_init(int argc, char *argv[])
rust_log_welcome_string();
#endif /* defined(HAVE_RUST) */
- if (network_init()<0) {
- log_err(LD_BUG,"Error initializing network; exiting.");
- return -1;
- }
- atexit(exit_function);
-
int init_rv = options_init_from_torrc(argc,argv);
if (init_rv < 0) {
log_err(LD_CONFIG,"Reading config failed--see warnings above.");
@@ -651,9 +647,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 */
+ /* Initialize channelpadding and circpad parameters to defaults
+ * until we get a consensus */
channelpadding_new_consensus_params(NULL);
+ circpad_new_consensus_params(NULL);
+
+ /* Initialize circuit padding to defaults+torrc until we get a consensus */
+ circpad_machines_init();
/* Initialize predicted ports list after loading options */
predicted_ports_init();
@@ -772,6 +772,7 @@ tor_free_all(int postfork)
dns_free_all();
clear_pending_onions();
circuit_free_all();
+ circpad_machines_free();
entry_guards_free_all();
pt_free_all();
channel_tls_free_all();
@@ -784,7 +785,6 @@ tor_free_all(int postfork)
routerparse_free_all();
ext_orport_free_all();
control_free_all();
- tor_free_getaddrinfo_cache();
protover_free_all();
bridges_free_all();
consdiffmgr_free_all();
@@ -792,6 +792,7 @@ tor_free_all(int postfork)
dos_free_all();
circuitmux_ewma_free_all();
accounting_free_all();
+ protover_summary_cache_free_all();
if (!postfork) {
config_free_all();
@@ -801,7 +802,6 @@ tor_free_all(int postfork)
policies_free_all();
}
if (!postfork) {
- tor_tls_free_all();
#ifndef _WIN32
tor_getpwnam(NULL);
#endif
@@ -814,12 +814,12 @@ tor_free_all(int postfork)
release_lockfile();
}
tor_libevent_free_all();
+
+ subsystems_shutdown();
+
/* Stuff in util.c and address.c*/
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. */
}
}
@@ -878,7 +878,6 @@ tor_cleanup(void)
later, if it makes shutdown unacceptably slow. But for
now, leave it here: it's helped us catch bugs in the
past. */
- crypto_global_cleanup();
}
/** Read/create keys as needed, and echo our fingerprint to stdout. */
@@ -1274,7 +1273,6 @@ int
run_tor_main_loop(void)
{
handle_signals();
- monotime_init();
timers_initialize();
initialize_mainloop_events();
@@ -1386,54 +1384,13 @@ tor_run_main(const tor_main_configuration_t *tor_cfg)
{
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);
-
- /* SetProcessDEPPolicy is only supported on 32-bit Windows.
- * (On 64-bit Windows it always fails, and some compilers don't like the
- * PSETDEP cast.)
- * 32-bit Windows defines _WIN32.
- * 64-bit Windows defines _WIN32 and _WIN64. */
-#ifndef _WIN64
- /* Call SetProcessDEPPolicy to permanently enable DEP.
- The function will not resolve on earlier versions of Windows,
- and failure is not dangerous. */
- HMODULE hMod = GetModuleHandleA("Kernel32.dll");
- if (hMod) {
- typedef BOOL (WINAPI *PSETDEP)(DWORD);
- PSETDEP setdeppolicy = (PSETDEP)GetProcAddress(hMod,
- "SetProcessDEPPolicy");
- if (setdeppolicy) {
- /* PROCESS_DEP_ENABLE | PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION */
- setdeppolicy(3);
- }
- }
-#endif /* !defined(_WIN64) */
-#endif /* defined(_WIN32) */
-
- {
- int bt_err = configure_backtrace_handler(get_version());
- if (bt_err < 0) {
- log_warn(LD_BUG, "Unable to install backtrace handler: %s",
- strerror(-bt_err));
- }
- }
-
#ifdef EVENT_SET_MEM_FUNCTIONS_IMPLEMENTED
event_set_mem_functions(tor_malloc_, tor_realloc_, tor_free_);
#endif
- init_protocol_warning_severity_level();
+ subsystems_init();
- update_approx_time(time(NULL));
- tor_threads_init();
- tor_compress_init();
- init_logging(0);
- monotime_init();
+ init_protocol_warning_severity_level();
int argc = tor_cfg->argc + tor_cfg->argc_owned;
char **argv = tor_calloc(argc, sizeof(char*));
@@ -1469,6 +1426,7 @@ tor_run_main(const tor_main_configuration_t *tor_cfg)
tor_free_all(0);
return -1;
}
+ tor_make_getaddrinfo_cache_active();
// registering libevent rng
#ifdef HAVE_EVUTIL_SECURE_RNG_SET_URANDOM_DEVICE_FILE
diff --git a/src/app/main/subsysmgr.c b/src/app/main/subsysmgr.c
new file mode 100644
index 0000000000..e0ca3ce4df
--- /dev/null
+++ b/src/app/main/subsysmgr.c
@@ -0,0 +1,202 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2019, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "orconfig.h"
+#include "app/main/subsysmgr.h"
+#include "lib/err/torerr.h"
+
+#include "lib/log/log.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/**
+ * True iff we have checked tor_subsystems for consistency.
+ **/
+static bool subsystem_array_validated = false;
+
+/**
+ * True if a given subsystem is initialized. Expand this array if there
+ * are more than this number of subsystems. (We'd rather not
+ * dynamically allocate in this module.)
+ **/
+static bool sys_initialized[128];
+
+/**
+ * Exit with a raw assertion if the subsystems list is inconsistent;
+ * initialize the subsystem_initialized array.
+ **/
+static void
+check_and_setup(void)
+{
+ if (subsystem_array_validated)
+ return;
+
+ raw_assert(ARRAY_LENGTH(sys_initialized) >= n_tor_subsystems);
+ memset(sys_initialized, 0, sizeof(sys_initialized));
+
+ int last_level = MIN_SUBSYS_LEVEL;
+
+ for (unsigned i = 0; i < n_tor_subsystems; ++i) {
+ const subsys_fns_t *sys = tor_subsystems[i];
+ if (sys->level < MIN_SUBSYS_LEVEL || sys->level > MAX_SUBSYS_LEVEL) {
+ fprintf(stderr, "BUG: Subsystem %s (at %u) has an invalid level %d. "
+ "It is supposed to be between %d and %d (inclusive).\n",
+ sys->name, i, sys->level, MIN_SUBSYS_LEVEL, MAX_SUBSYS_LEVEL);
+ raw_assert_unreached_msg("There is a bug in subsystem_list.c");
+ }
+ if (sys->level < last_level) {
+ fprintf(stderr, "BUG: Subsystem %s (at #%u) is in the wrong position. "
+ "Its level is %d; but the previous subsystem's level was %d.\n",
+ sys->name, i, sys->level, last_level);
+ raw_assert_unreached_msg("There is a bug in subsystem_list.c");
+ }
+ last_level = sys->level;
+ }
+
+ subsystem_array_validated = true;
+}
+
+/**
+ * Initialize all the subsystems; exit on failure.
+ **/
+int
+subsystems_init(void)
+{
+ return subsystems_init_upto(MAX_SUBSYS_LEVEL);
+}
+
+/**
+ * Initialize all the subsystems whose level is less than or equal to
+ * <b>target_level</b>; exit on failure.
+ **/
+int
+subsystems_init_upto(int target_level)
+{
+ check_and_setup();
+
+ for (unsigned i = 0; i < n_tor_subsystems; ++i) {
+ const subsys_fns_t *sys = tor_subsystems[i];
+ if (!sys->supported)
+ continue;
+ if (sys->level > target_level)
+ break;
+ if (sys_initialized[i])
+ continue;
+ int r = 0;
+ if (sys->initialize) {
+ // Note that the logging subsystem is designed so that it does no harm
+ // to log a message in an uninitialized state. These messages will be
+ // discarded for now, however.
+ log_debug(LD_GENERAL, "Initializing %s", sys->name);
+ r = sys->initialize();
+ }
+ if (r < 0) {
+ fprintf(stderr, "BUG: subsystem %s (at %u) initialization failed.\n",
+ sys->name, i);
+ raw_assert_unreached_msg("A subsystem couldn't be initialized.");
+ }
+ sys_initialized[i] = true;
+ }
+
+ return 0;
+}
+
+/**
+ * Shut down all the subsystems.
+ **/
+void
+subsystems_shutdown(void)
+{
+ subsystems_shutdown_downto(MIN_SUBSYS_LEVEL - 1);
+}
+
+/**
+ * Shut down all the subsystems whose level is above <b>target_level</b>.
+ **/
+void
+subsystems_shutdown_downto(int target_level)
+{
+ check_and_setup();
+
+ for (int i = (int)n_tor_subsystems - 1; i >= 0; --i) {
+ const subsys_fns_t *sys = tor_subsystems[i];
+ if (!sys->supported)
+ continue;
+ if (sys->level <= target_level)
+ break;
+ if (! sys_initialized[i])
+ continue;
+ if (sys->shutdown) {
+ log_debug(LD_GENERAL, "Shutting down %s", sys->name);
+ sys->shutdown();
+ }
+ sys_initialized[i] = false;
+ }
+}
+
+/**
+ * Run pre-fork code on all subsystems that declare any
+ **/
+void
+subsystems_prefork(void)
+{
+ check_and_setup();
+
+ for (int i = (int)n_tor_subsystems - 1; i >= 0; --i) {
+ const subsys_fns_t *sys = tor_subsystems[i];
+ if (!sys->supported)
+ continue;
+ if (! sys_initialized[i])
+ continue;
+ if (sys->prefork) {
+ log_debug(LD_GENERAL, "Pre-fork: %s", sys->name);
+ sys->prefork();
+ }
+ }
+}
+
+/**
+ * Run post-fork code on all subsystems that declare any
+ **/
+void
+subsystems_postfork(void)
+{
+ check_and_setup();
+
+ for (unsigned i = 0; i < n_tor_subsystems; ++i) {
+ const subsys_fns_t *sys = tor_subsystems[i];
+ if (!sys->supported)
+ continue;
+ if (! sys_initialized[i])
+ continue;
+ if (sys->postfork) {
+ log_debug(LD_GENERAL, "Post-fork: %s", sys->name);
+ sys->postfork();
+ }
+ }
+}
+
+/**
+ * Run thread-cleanup code on all subsystems that declare any
+ **/
+void
+subsystems_thread_cleanup(void)
+{
+ check_and_setup();
+
+ for (int i = (int)n_tor_subsystems - 1; i >= 0; --i) {
+ const subsys_fns_t *sys = tor_subsystems[i];
+ if (!sys->supported)
+ continue;
+ if (! sys_initialized[i])
+ continue;
+ if (sys->thread_cleanup) {
+ log_debug(LD_GENERAL, "Thread cleanup: %s", sys->name);
+ sys->thread_cleanup();
+ }
+ }
+}
diff --git a/src/app/main/subsysmgr.h b/src/app/main/subsysmgr.h
new file mode 100644
index 0000000000..a5e62f71d9
--- /dev/null
+++ b/src/app/main/subsysmgr.h
@@ -0,0 +1,24 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2019, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#ifndef TOR_SUBSYSMGR_T
+#define TOR_SUBSYSMGR_T
+
+#include "lib/subsys/subsys.h"
+
+extern const struct subsys_fns_t *tor_subsystems[];
+extern const unsigned n_tor_subsystems;
+
+int subsystems_init(void);
+int subsystems_init_upto(int level);
+
+void subsystems_shutdown(void);
+void subsystems_shutdown_downto(int level);
+
+void subsystems_prefork(void);
+void subsystems_postfork(void);
+void subsystems_thread_cleanup(void);
+
+#endif
diff --git a/src/app/main/subsystem_list.c b/src/app/main/subsystem_list.c
new file mode 100644
index 0000000000..3834176182
--- /dev/null
+++ b/src/app/main/subsystem_list.c
@@ -0,0 +1,49 @@
+/* Copyright (c) 2003-2004, Roger Dingledine
+ * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2019, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include "orconfig.h"
+#include "app/main/subsysmgr.h"
+#include "lib/cc/compat_compiler.h"
+#include "lib/cc/torint.h"
+
+#include "core/or/ocirc_event_sys.h"
+#include "core/or/orconn_event_sys.h"
+#include "feature/control/btrack_sys.h"
+#include "lib/compress/compress_sys.h"
+#include "lib/crypt_ops/crypto_sys.h"
+#include "lib/err/torerr_sys.h"
+#include "lib/log/log_sys.h"
+#include "lib/net/network_sys.h"
+#include "lib/process/winprocess_sys.h"
+#include "lib/thread/thread_sys.h"
+#include "lib/time/time_sys.h"
+#include "lib/tls/tortls_sys.h"
+#include "lib/wallclock/wallclock_sys.h"
+#include "lib/process/process_sys.h"
+
+#include <stddef.h>
+
+/**
+ * Global list of the subsystems in Tor, in the order of their initialization.
+ **/
+const subsys_fns_t *tor_subsystems[] = {
+ &sys_winprocess, /* -100 */
+ &sys_torerr, /* -100 */
+ &sys_wallclock, /* -99 */
+ &sys_threads, /* -95 */
+ &sys_logging, /* -90 */
+ &sys_time, /* -90 */
+ &sys_network, /* -90 */
+ &sys_compress, /* -70 */
+ &sys_crypto, /* -60 */
+ &sys_tortls, /* -50 */
+ &sys_process, /* -35 */
+
+ &sys_orconn_event, /* -33 */
+ &sys_ocirc_event, /* -32 */
+ &sys_btrack, /* -30 */
+};
+
+const unsigned n_tor_subsystems = ARRAY_LENGTH(tor_subsystems);