diff options
author | George Kadianakis <desnacked@riseup.net> | 2019-05-15 23:23:18 +0300 |
---|---|---|
committer | George Kadianakis <desnacked@riseup.net> | 2019-05-15 23:23:18 +0300 |
commit | 338cfb31798267dc8260415ef55ddceb042367bd (patch) | |
tree | 9150b19e54cda807f1850109146aa1d2477eb8aa /src | |
parent | 39a14421b1f50b4bea8c42e4f76a67b648bfa8e0 (diff) | |
parent | 3c2648bbda53f74a4e960ad149600c3a2b12305c (diff) | |
download | tor-338cfb31798267dc8260415ef55ddceb042367bd.tar.gz tor-338cfb31798267dc8260415ef55ddceb042367bd.zip |
Merge branch 'tor-github/pr/1002'
Diffstat (limited to 'src')
-rw-r--r-- | src/app/main/shutdown.c | 15 | ||||
-rw-r--r-- | src/app/main/subsystem_list.c | 7 | ||||
-rw-r--r-- | src/core/include.am | 8 | ||||
-rw-r--r-- | src/core/mainloop/mainloop.c | 288 | ||||
-rw-r--r-- | src/core/mainloop/mainloop.h | 1 | ||||
-rw-r--r-- | src/core/or/circuitstats.c | 2 | ||||
-rw-r--r-- | src/core/or/or_periodic.c | 65 | ||||
-rw-r--r-- | src/core/or/or_periodic.h | 17 | ||||
-rw-r--r-- | src/core/or/or_sys.c | 43 | ||||
-rw-r--r-- | src/core/or/or_sys.h | 17 | ||||
-rw-r--r-- | src/feature/relay/relay_periodic.c | 308 | ||||
-rw-r--r-- | src/feature/relay/relay_periodic.h | 18 | ||||
-rw-r--r-- | src/feature/relay/relay_sys.c | 48 | ||||
-rw-r--r-- | src/feature/relay/relay_sys.h | 17 | ||||
-rw-r--r-- | src/feature/relay/selftest.c | 1 |
15 files changed, 550 insertions, 305 deletions
diff --git a/src/app/main/shutdown.c b/src/app/main/shutdown.c index c302ce455c..1871717ad5 100644 --- a/src/app/main/shutdown.c +++ b/src/app/main/shutdown.c @@ -25,10 +25,7 @@ #include "core/or/circuitpadding.h" #include "core/or/connection_edge.h" #include "core/or/dos.h" -#include "core/or/policies.h" -#include "core/or/protover.h" #include "core/or/scheduler.h" -#include "core/or/versions.h" #include "feature/client/addressmap.h" #include "feature/client/bridges.h" #include "feature/client/entrynodes.h" @@ -47,17 +44,13 @@ #include "feature/nodelist/nodelist.h" #include "feature/nodelist/routerlist.h" #include "feature/nodelist/routerlist.h" -#include "feature/relay/dns.h" #include "feature/relay/ext_orport.h" -#include "feature/relay/onion_queue.h" -#include "feature/relay/routerkeys.h" #include "feature/rend/rendcache.h" #include "feature/rend/rendclient.h" #include "feature/stats/geoip_stats.h" #include "feature/stats/rephist.h" #include "lib/evloop/compat_libevent.h" #include "lib/geoip/geoip.h" -#include "src/feature/relay/router.h" void evdns_shutdown(int); @@ -127,8 +120,6 @@ tor_free_all(int postfork) rend_cache_free_all(); rend_service_authorization_free_all(); rep_hist_free_all(); - dns_free_all(); - clear_pending_onions(); circuit_free_all(); circpad_machines_free(); entry_guards_free_all(); @@ -141,23 +132,17 @@ tor_free_all(int postfork) nodelist_free_all(); microdesc_free_all(); routerparse_free_all(); - ext_orport_free_all(); control_free_all(); - protover_free_all(); bridges_free_all(); consdiffmgr_free_all(); hs_free_all(); dos_free_all(); circuitmux_ewma_free_all(); accounting_free_all(); - protover_summary_cache_free_all(); if (!postfork) { config_free_all(); or_state_free_all(); - router_free_all(); - routerkeys_free_all(); - policies_free_all(); } if (!postfork) { #ifndef _WIN32 diff --git a/src/app/main/subsystem_list.c b/src/app/main/subsystem_list.c index 00effe01aa..f595796232 100644 --- a/src/app/main/subsystem_list.c +++ b/src/app/main/subsystem_list.c @@ -10,19 +10,21 @@ #include "core/mainloop/mainloop_sys.h" #include "core/or/ocirc_event_sys.h" +#include "core/or/or_sys.h" #include "core/or/orconn_event_sys.h" #include "feature/control/btrack_sys.h" +#include "feature/relay/relay_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/process_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 "feature/dirauth/dirauth_sys.h" @@ -49,6 +51,9 @@ const subsys_fns_t *tor_subsystems[] = { &sys_btrack, /* -30 */ &sys_mainloop, /* 5 */ + &sys_or, /* 20 */ + + &sys_relay, /* 50 */ #ifdef HAVE_MODULE_DIRAUTH &sys_dirauth, /* 70 */ diff --git a/src/core/include.am b/src/core/include.am index 8435ce0415..b04c5db541 100644 --- a/src/core/include.am +++ b/src/core/include.am @@ -46,6 +46,8 @@ LIBTOR_APP_A_SOURCES = \ src/core/or/dos.c \ src/core/or/onion.c \ src/core/or/ocirc_event.c \ + src/core/or/or_periodic.c \ + src/core/or/or_sys.c \ src/core/or/orconn_event.c \ src/core/or/policies.c \ src/core/or/protover.c \ @@ -138,6 +140,8 @@ LIBTOR_APP_A_SOURCES = \ src/feature/relay/dns.c \ src/feature/relay/ext_orport.c \ src/feature/relay/onion_queue.c \ + src/feature/relay/relay_periodic.c \ + src/feature/relay/relay_sys.c \ src/feature/relay/router.c \ src/feature/relay/routerkeys.c \ src/feature/relay/routermode.c \ @@ -262,6 +266,8 @@ noinst_HEADERS += \ src/core/or/listener_connection_st.h \ src/core/or/onion.h \ src/core/or/or.h \ + src/core/or/or_periodic.h \ + src/core/or/or_sys.h \ src/core/or/orconn_event.h \ src/core/or/orconn_event_sys.h \ src/core/or/or_circuit_st.h \ @@ -407,6 +413,8 @@ noinst_HEADERS += \ src/feature/relay/dns_structs.h \ src/feature/relay/ext_orport.h \ src/feature/relay/onion_queue.h \ + src/feature/relay/relay_periodic.h \ + src/feature/relay/relay_sys.h \ src/feature/relay/router.h \ src/feature/relay/routerkeys.h \ src/feature/relay/routermode.h \ diff --git a/src/core/mainloop/mainloop.c b/src/core/mainloop/mainloop.c index 4401f805d9..82042e8498 100644 --- a/src/core/mainloop/mainloop.c +++ b/src/core/mainloop/mainloop.c @@ -1342,28 +1342,18 @@ static int periodic_events_initialized = 0; #define CALLBACK(name) \ static int name ## _callback(time_t, const or_options_t *) CALLBACK(add_entropy); -CALLBACK(check_canonical_channels); -CALLBACK(check_descriptor); -CALLBACK(check_dns_honesty); -CALLBACK(check_ed_keys); CALLBACK(check_expired_networkstatus); -CALLBACK(check_for_reachability_bw); -CALLBACK(check_onion_keys_expiry_time); CALLBACK(clean_caches); CALLBACK(clean_consdiffmgr); -CALLBACK(expire_old_ciruits_serverside); CALLBACK(fetch_networkstatus); CALLBACK(heartbeat); CALLBACK(hs_service); CALLBACK(launch_descriptor_fetches); CALLBACK(prune_old_routers); -CALLBACK(reachability_warnings); CALLBACK(record_bridge_stats); CALLBACK(rend_cache_failure_clean); CALLBACK(reset_padding_counts); -CALLBACK(retry_dns); CALLBACK(retry_listeners); -CALLBACK(rotate_onion_key); CALLBACK(rotate_x509_certificate); CALLBACK(save_state); CALLBACK(write_stats_file); @@ -1408,20 +1398,6 @@ STATIC periodic_event_item_t mainloop_periodic_events[] = { CALLBACK(write_stats_file, NET_PARTICIPANT, FL(RUN_ON_DISABLE)), CALLBACK(prune_old_routers, NET_PARTICIPANT, FL(RUN_ON_DISABLE)), - /* Routers (bridge and relay) only. */ - CALLBACK(check_descriptor, ROUTER, FL(NEED_NET)), - CALLBACK(check_ed_keys, ROUTER, 0), - CALLBACK(check_for_reachability_bw, ROUTER, FL(NEED_NET)), - CALLBACK(check_onion_keys_expiry_time, ROUTER, 0), - CALLBACK(expire_old_ciruits_serverside, ROUTER, FL(NEED_NET)), - CALLBACK(reachability_warnings, ROUTER, FL(NEED_NET)), - CALLBACK(retry_dns, ROUTER, 0), - CALLBACK(rotate_onion_key, ROUTER, 0), - - /* Relay only. */ - CALLBACK(check_canonical_channels, RELAY, FL(NEED_NET)), - CALLBACK(check_dns_honesty, RELAY, FL(NEED_NET)), - /* Hidden Service service only. */ CALLBACK(hs_service, HS_SERVICE, FL(NEED_NET)), // XXXX break this down more @@ -1447,7 +1423,6 @@ STATIC periodic_event_item_t mainloop_periodic_events[] = { * implement particular callbacks. We keep them separate here so that we * can access them by name. We also keep them inside periodic_events[] * so that we can implement "reset all timers" in a reasonable way. */ -static periodic_event_item_t *check_descriptor_event=NULL; static periodic_event_item_t *fetch_networkstatus_event=NULL; static periodic_event_item_t *launch_descriptor_fetches_event=NULL; static periodic_event_item_t *check_dns_honesty_event=NULL; @@ -1544,7 +1519,6 @@ initialize_periodic_events(void) #define NAMED_CALLBACK(name) \ STMT_BEGIN name ## _event = periodic_events_find( #name ); STMT_END - NAMED_CALLBACK(check_descriptor); NAMED_CALLBACK(prune_old_routers); NAMED_CALLBACK(fetch_networkstatus); NAMED_CALLBACK(launch_descriptor_fetches); @@ -1556,7 +1530,6 @@ STATIC void teardown_periodic_events(void) { periodic_events_disconnect_all(); - check_descriptor_event = NULL; fetch_networkstatus_event = NULL; launch_descriptor_fetches_event = NULL; check_dns_honesty_event = NULL; @@ -1608,19 +1581,6 @@ periodic_events_on_new_options(const or_options_t *options) } /** - * Update our schedule so that we'll check whether we need to update our - * descriptor immediately, rather than after up to CHECK_DESCRIPTOR_INTERVAL - * seconds. - */ -void -reschedule_descriptor_update_check(void) -{ - if (check_descriptor_event) { - periodic_event_reschedule(check_descriptor_event); - } -} - -/** * Update our schedule so that we'll check whether we need to fetch directory * info immediately. */ @@ -1762,77 +1722,6 @@ second_elapsed_callback(time_t now, const or_options_t *options) return 1; } -/* 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)) { - 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 ONION_KEY_CONSENSUS_CHECK_INTERVAL; - } - - log_info(LD_GENERAL,"Rotating onion key."); - rotate_onion_key(); - cpuworkers_rotate_keyinfo(); - if (router_rebuild_descriptor(1)<0) { - log_info(LD_CONFIG, "Couldn't rebuild router descriptor"); - } - if (advertised_server_mode() && !net_is_disabled()) - router_upload_dir_desc_to_dirservers(0); - 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. - */ -static int -check_ed_keys_callback(time_t now, const or_options_t *options) -{ - if (server_mode(options)) { - if (should_make_new_ed_keys(options, now)) { - int new_signing_key = load_ed_keys(options, now); - if (new_signing_key < 0 || - generate_ed_link_cert(options, now, new_signing_key > 0)) { - log_err(LD_OR, "Unable to update Ed25519 keys! Exiting."); - tor_shutdown_event_loop_and_exit(1); - } - } - return 30; - } - return PERIODIC_EVENT_NO_UPDATE; -} - /** * Periodic callback: Every {LAZY,GREEDY}_DESCRIPTOR_RETRY_INTERVAL, * see about fetching descriptors, microdescriptors, and extrainfo @@ -2053,17 +1942,6 @@ 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) { @@ -2138,19 +2016,6 @@ rend_cache_failure_clean_callback(time_t now, const or_options_t *options) } /** - * Periodic callback: If we're a server and initializing dns failed, retry. - */ -static int -retry_dns_callback(time_t now, const or_options_t *options) -{ - (void)now; -#define RETRY_DNS_INTERVAL (10*60) - if (server_mode(options) && has_dns_init_failed()) - dns_init(); - return RETRY_DNS_INTERVAL; -} - -/** * Periodic callback: prune routerlist of old information about Tor network. */ static int @@ -2171,71 +2036,6 @@ prune_old_routers_callback(time_t now, const or_options_t *options) return ROUTERLIST_PRUNING_INTERVAL; } -/** Periodic callback: consider rebuilding or and re-uploading our descriptor - * (if we've passed our internal checks). */ -static int -check_descriptor_callback(time_t now, const or_options_t *options) -{ -/** How often do we check whether part of our router info has changed in a - * way that would require an upload? That includes checking whether our IP - * address has changed. */ -#define CHECK_DESCRIPTOR_INTERVAL (60) - - (void)options; - - /* 2b. Once per minute, regenerate and upload the descriptor if the old - * one is inaccurate. */ - if (!net_is_disabled()) { - check_descriptor_bandwidth_changed(now); - check_descriptor_ipaddress_changed(now); - mark_my_descriptor_dirty_if_too_old(now); - consider_publishable_server(0); - } - - return CHECK_DESCRIPTOR_INTERVAL; -} - -/** - * Periodic callback: check whether we're reachable (as a relay), and - * whether our bandwidth has changed enough that we need to - * publish a new descriptor. - */ -static int -check_for_reachability_bw_callback(time_t now, const or_options_t *options) -{ - /* XXXX This whole thing was stuck in the middle of what is now - * XXXX check_descriptor_callback. I'm not sure it's right. */ - - static int dirport_reachability_count = 0; - /* also, check religiously for reachability, if it's within the first - * 20 minutes of our uptime. */ - if (server_mode(options) && - (have_completed_a_circuit() || !any_predicted_circuits(now)) && - !net_is_disabled()) { - if (get_uptime() < TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT) { - router_do_reachability_checks(1, dirport_reachability_count==0); - if (++dirport_reachability_count > 5) - dirport_reachability_count = 0; - return 1; - } else { - /* If we haven't checked for 12 hours and our bandwidth estimate is - * low, do another bandwidth test. This is especially important for - * bridges, since they might go long periods without much use. */ - const routerinfo_t *me = router_get_my_routerinfo(); - static int first_time = 1; - if (!first_time && me && - me->bandwidthcapacity < me->bandwidthrate && - me->bandwidthcapacity < 51200) { - reset_bandwidth_test(); - } - first_time = 0; -#define BANDWIDTH_RECHECK_INTERVAL (12*60*60) - return BANDWIDTH_RECHECK_INTERVAL; - } - } - return CHECK_DESCRIPTOR_INTERVAL; -} - /** * Periodic event: once a minute, (or every second if TestingTorNetwork, or * during client bootstrap), check whether we want to download any @@ -2278,93 +2078,6 @@ retry_listeners_callback(time_t now, const or_options_t *options) return PERIODIC_EVENT_NO_UPDATE; } -/** - * Periodic callback: as a server, see if we have any old unused circuits - * that should be expired */ -static int -expire_old_ciruits_serverside_callback(time_t now, const or_options_t *options) -{ - (void)options; - /* every 11 seconds, so not usually the same second as other such events */ - circuit_expire_old_circuits_serverside(now); - return 11; -} - -/** - * Callback: Send warnings if Tor doesn't find its ports reachable. - */ -static int -reachability_warnings_callback(time_t now, const or_options_t *options) -{ - (void) now; - - if (get_uptime() < TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT) { - return (int)(TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT - get_uptime()); - } - - if (server_mode(options) && - !net_is_disabled() && - have_completed_a_circuit()) { - /* every 20 minutes, check and complain if necessary */ - const routerinfo_t *me = router_get_my_routerinfo(); - if (me && !check_whether_orport_reachable(options)) { - char *address = tor_dup_ip(me->addr); - log_warn(LD_CONFIG,"Your server (%s:%d) has not managed to confirm that " - "its ORPort is reachable. Relays do not publish descriptors " - "until their ORPort and DirPort are reachable. Please check " - "your firewalls, ports, address, /etc/hosts file, etc.", - address, me->or_port); - control_event_server_status(LOG_WARN, - "REACHABILITY_FAILED ORADDRESS=%s:%d", - address, me->or_port); - tor_free(address); - } - - if (me && !check_whether_dirport_reachable(options)) { - char *address = tor_dup_ip(me->addr); - log_warn(LD_CONFIG, - "Your server (%s:%d) has not managed to confirm that its " - "DirPort is reachable. Relays do not publish descriptors " - "until their ORPort and DirPort are reachable. Please check " - "your firewalls, ports, address, /etc/hosts file, etc.", - address, me->dir_port); - control_event_server_status(LOG_WARN, - "REACHABILITY_FAILED DIRADDRESS=%s:%d", - address, me->dir_port); - tor_free(address); - } - } - - return TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT; -} - -static int dns_honesty_first_time = 1; - -/** - * Periodic event: if we're an exit, see if our DNS server is telling us - * obvious lies. - */ -static int -check_dns_honesty_callback(time_t now, const or_options_t *options) -{ - (void)now; - /* 9. and if we're an exit node, check whether our DNS is telling stories - * to us. */ - if (net_is_disabled() || - ! public_server_mode(options) || - router_my_exit_policy_is_reject_star()) - return PERIODIC_EVENT_NO_UPDATE; - - if (dns_honesty_first_time) { - /* Don't launch right when we start */ - dns_honesty_first_time = 0; - return crypto_rand_int_range(60, 180); - } - - dns_launch_correctness_checks(); - return 12*3600 + crypto_rand_int(12*3600); -} - static int heartbeat_callback_first_time = 1; /** @@ -2830,7 +2543,6 @@ tor_mainloop_free_all(void) can_complete_circuits = 0; quiet_level = 0; should_init_bridge_stats = 1; - dns_honesty_first_time = 1; heartbeat_callback_first_time = 1; current_second = 0; memset(¤t_second_last_changed, 0, diff --git a/src/core/mainloop/mainloop.h b/src/core/mainloop/mainloop.h index 3a611f81aa..cdc2bf8608 100644 --- a/src/core/mainloop/mainloop.h +++ b/src/core/mainloop/mainloop.h @@ -59,7 +59,6 @@ void directory_info_has_arrived(time_t now, int from_cache, int suppress_logs); void ip_address_changed(int at_interface); void dns_servers_relaunch_checks(void); void reset_all_main_loop_timers(void); -void reschedule_descriptor_update_check(void); void reschedule_directory_downloads(void); void reschedule_or_state_save(void); void mainloop_schedule_postloop_cleanup(void); diff --git a/src/core/or/circuitstats.c b/src/core/or/circuitstats.c index e5a3bac30b..03eea1d779 100644 --- a/src/core/or/circuitstats.c +++ b/src/core/or/circuitstats.c @@ -44,6 +44,7 @@ #include "lib/time/tvdiff.h" #include "lib/encoding/confline.h" #include "feature/dirauth/authmode.h" +#include "feature/relay/relay_periodic.h" #include "core/or/crypt_path_st.h" #include "core/or/origin_circuit_st.h" @@ -1420,6 +1421,7 @@ void circuit_build_times_network_is_live(circuit_build_times_t *cbt) { time_t now = approx_time(); + // XXXX this should use pubsub if (cbt->liveness.nonlive_timeouts > 0) { time_t time_since_live = now - cbt->liveness.network_last_live; log_notice(LD_CIRC, diff --git a/src/core/or/or_periodic.c b/src/core/or/or_periodic.c new file mode 100644 index 0000000000..93dfa8cf8b --- /dev/null +++ b/src/core/or/or_periodic.c @@ -0,0 +1,65 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file or_periodic.c + * @brief Periodic callbacks for the onion routing subsystem + **/ + +#include "orconfig.h" +#include "core/or/or.h" + +#include "core/mainloop/periodic.h" + +#include "core/or/channel.h" +#include "core/or/circuituse.h" +#include "core/or/or_periodic.h" + +#include "src/feature/relay/routermode.h" + +#define DECLARE_EVENT(name, roles, flags) \ + static periodic_event_item_t name ## _event = \ + PERIODIC_EVENT(name, \ + PERIODIC_EVENT_ROLE_##roles, \ + flags) + +#define FL(name) (PERIODIC_EVENT_FLAG_ ## name) + +#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; +} + +DECLARE_EVENT(check_canonical_channels, RELAY, FL(NEED_NET)); + +/** + * Periodic callback: as a server, see if we have any old unused circuits + * that should be expired */ +static int +expire_old_circuits_serverside_callback(time_t now, + const or_options_t *options) +{ + (void)options; + /* every 11 seconds, so not usually the same second as other such events */ + circuit_expire_old_circuits_serverside(now); + return 11; +} + +DECLARE_EVENT(expire_old_circuits_serverside, ROUTER, FL(NEED_NET)); + +void +or_register_periodic_events(void) +{ + // These are router-only events, but they're owned by the OR subsystem. */ + periodic_events_register(&check_canonical_channels_event); + periodic_events_register(&expire_old_circuits_serverside_event); +} diff --git a/src/core/or/or_periodic.h b/src/core/or/or_periodic.h new file mode 100644 index 0000000000..c2f47cf5ef --- /dev/null +++ b/src/core/or/or_periodic.h @@ -0,0 +1,17 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file or_periodic.h + * @brief Header for core/or/or_periodic.c + **/ + +#ifndef TOR_CORE_OR_OR_PERIODIC_H +#define TOR_CORE_OR_OR_PERIODIC_H + +void or_register_periodic_events(void); + +#endif /* !defined(TOR_CORE_OR_OR_PERIODIC_H) */ diff --git a/src/core/or/or_sys.c b/src/core/or/or_sys.c new file mode 100644 index 0000000000..6f8c81a4df --- /dev/null +++ b/src/core/or/or_sys.c @@ -0,0 +1,43 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file or_sys.c + * @brief Subsystem definitions for OR module. + **/ + +#include "orconfig.h" +#include "core/or/or.h" +#include "core/or/or_periodic.h" +#include "core/or/or_sys.h" +#include "core/or/policies.h" +#include "core/or/protover.h" +#include "core/or/versions.h" + +#include "lib/subsys/subsys.h" + +static int +subsys_or_initialize(void) +{ + or_register_periodic_events(); + return 0; +} + +static void +subsys_or_shutdown(void) +{ + protover_free_all(); + protover_summary_cache_free_all(); + policies_free_all(); +} + +const struct subsys_fns_t sys_or = { + .name = "or", + .supported = true, + .level = 20, + .initialize = subsys_or_initialize, + .shutdown = subsys_or_shutdown, +}; diff --git a/src/core/or/or_sys.h b/src/core/or/or_sys.h new file mode 100644 index 0000000000..c37ef01858 --- /dev/null +++ b/src/core/or/or_sys.h @@ -0,0 +1,17 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file or_sys.h + * @brief Header for core/or/or_sys.c + **/ + +#ifndef TOR_CORE_OR_OR_SYS_H +#define TOR_CORE_OR_OR_SYS_H + +extern const struct subsys_fns_t sys_or; + +#endif /* !defined(TOR_CORE_OR_OR_SYS_H) */ diff --git a/src/feature/relay/relay_periodic.c b/src/feature/relay/relay_periodic.c new file mode 100644 index 0000000000..8908b57415 --- /dev/null +++ b/src/feature/relay/relay_periodic.c @@ -0,0 +1,308 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file relay_periodic.c + * @brief Periodic functions for the relay subsytem + **/ + +#include "orconfig.h" +#include "core/or/or.h" + +#include "core/mainloop/periodic.h" +#include "core/mainloop/cpuworker.h" // XXXX use a pubsub event. +#include "core/mainloop/mainloop.h" +#include "core/mainloop/netstatus.h" +#include "core/or/circuituse.h" // XXXX move have_performed_bandwidth_test + +#include "feature/relay/dns.h" +#include "feature/relay/relay_periodic.h" +#include "feature/relay/router.h" +#include "feature/relay/routerkeys.h" +#include "feature/relay/routermode.h" +#include "feature/relay/selftest.h" +#include "src/feature/stats/predict_ports.h" + +#include "lib/crypt_ops/crypto_rand.h" + +#include "feature/nodelist/routerinfo_st.h" +#include "feature/control/control_events.h" + +#define DECLARE_EVENT(name, roles, flags) \ + static periodic_event_item_t name ## _event = \ + PERIODIC_EVENT(name, \ + PERIODIC_EVENT_ROLE_##roles, \ + flags) + +#define FL(name) (PERIODIC_EVENT_FLAG_##name) + +/** + * Periodic callback: If we're a server and initializing dns failed, retry. + */ +static int +retry_dns_callback(time_t now, const or_options_t *options) +{ + (void)now; +#define RETRY_DNS_INTERVAL (10*60) + if (server_mode(options) && has_dns_init_failed()) + dns_init(); + return RETRY_DNS_INTERVAL; +} + +DECLARE_EVENT(retry_dns, ROUTER, 0); + +static int dns_honesty_first_time = 1; + +/** + * Periodic event: if we're an exit, see if our DNS server is telling us + * obvious lies. + */ +static int +check_dns_honesty_callback(time_t now, const or_options_t *options) +{ + (void)now; + /* 9. and if we're an exit node, check whether our DNS is telling stories + * to us. */ + if (net_is_disabled() || + ! public_server_mode(options) || + router_my_exit_policy_is_reject_star()) + return PERIODIC_EVENT_NO_UPDATE; + + if (dns_honesty_first_time) { + /* Don't launch right when we start */ + dns_honesty_first_time = 0; + return crypto_rand_int_range(60, 180); + } + + dns_launch_correctness_checks(); + return 12*3600 + crypto_rand_int(12*3600); +} + +DECLARE_EVENT(check_dns_honesty, RELAY, FL(NEED_NET)); + +/* 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)) { + 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 ONION_KEY_CONSENSUS_CHECK_INTERVAL; + } + + log_info(LD_GENERAL,"Rotating onion key."); + rotate_onion_key(); + cpuworkers_rotate_keyinfo(); + if (router_rebuild_descriptor(1)<0) { + log_info(LD_CONFIG, "Couldn't rebuild router descriptor"); + } + if (advertised_server_mode() && !net_is_disabled()) + router_upload_dir_desc_to_dirservers(0); + return ONION_KEY_CONSENSUS_CHECK_INTERVAL; + } + return PERIODIC_EVENT_NO_UPDATE; +} + +DECLARE_EVENT(rotate_onion_key, ROUTER, 0); + +/** Periodic callback: consider rebuilding or and re-uploading our descriptor + * (if we've passed our internal checks). */ +static int +check_descriptor_callback(time_t now, const or_options_t *options) +{ +/** How often do we check whether part of our router info has changed in a + * way that would require an upload? That includes checking whether our IP + * address has changed. */ +#define CHECK_DESCRIPTOR_INTERVAL (60) + + (void)options; + + /* 2b. Once per minute, regenerate and upload the descriptor if the old + * one is inaccurate. */ + if (!net_is_disabled()) { + check_descriptor_bandwidth_changed(now); + check_descriptor_ipaddress_changed(now); + mark_my_descriptor_dirty_if_too_old(now); + consider_publishable_server(0); + } + + return CHECK_DESCRIPTOR_INTERVAL; +} + +DECLARE_EVENT(check_descriptor, ROUTER, FL(NEED_NET)); + +static int dirport_reachability_count = 0; + +/** + * Periodic callback: check whether we're reachable (as a relay), and + * whether our bandwidth has changed enough that we need to + * publish a new descriptor. + */ +static int +check_for_reachability_bw_callback(time_t now, const or_options_t *options) +{ + /* XXXX This whole thing was stuck in the middle of what is now + * XXXX check_descriptor_callback. I'm not sure it's right. */ + + /* also, check religiously for reachability, if it's within the first + * 20 minutes of our uptime. */ + if (server_mode(options) && + (have_completed_a_circuit() || !any_predicted_circuits(now)) && + !net_is_disabled()) { + if (get_uptime() < TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT) { + router_do_reachability_checks(1, dirport_reachability_count==0); + if (++dirport_reachability_count > 5) + dirport_reachability_count = 0; + return 1; + } else { + /* If we haven't checked for 12 hours and our bandwidth estimate is + * low, do another bandwidth test. This is especially important for + * bridges, since they might go long periods without much use. */ + const routerinfo_t *me = router_get_my_routerinfo(); + static int first_time = 1; + if (!first_time && me && + me->bandwidthcapacity < me->bandwidthrate && + me->bandwidthcapacity < 51200) { + reset_bandwidth_test(); + } + first_time = 0; +#define BANDWIDTH_RECHECK_INTERVAL (12*60*60) + return BANDWIDTH_RECHECK_INTERVAL; + } + } + return CHECK_DESCRIPTOR_INTERVAL; +} + +DECLARE_EVENT(check_for_reachability_bw, ROUTER, FL(NEED_NET)); + +/** + * Callback: Send warnings if Tor doesn't find its ports reachable. + */ +static int +reachability_warnings_callback(time_t now, const or_options_t *options) +{ + (void) now; + + if (get_uptime() < TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT) { + return (int)(TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT - get_uptime()); + } + + if (server_mode(options) && + !net_is_disabled() && + have_completed_a_circuit()) { + /* every 20 minutes, check and complain if necessary */ + const routerinfo_t *me = router_get_my_routerinfo(); + if (me && !check_whether_orport_reachable(options)) { + char *address = tor_dup_ip(me->addr); + log_warn(LD_CONFIG,"Your server (%s:%d) has not managed to confirm that " + "its ORPort is reachable. Relays do not publish descriptors " + "until their ORPort and DirPort are reachable. Please check " + "your firewalls, ports, address, /etc/hosts file, etc.", + address, me->or_port); + control_event_server_status(LOG_WARN, + "REACHABILITY_FAILED ORADDRESS=%s:%d", + address, me->or_port); + tor_free(address); + } + + if (me && !check_whether_dirport_reachable(options)) { + char *address = tor_dup_ip(me->addr); + log_warn(LD_CONFIG, + "Your server (%s:%d) has not managed to confirm that its " + "DirPort is reachable. Relays do not publish descriptors " + "until their ORPort and DirPort are reachable. Please check " + "your firewalls, ports, address, /etc/hosts file, etc.", + address, me->dir_port); + control_event_server_status(LOG_WARN, + "REACHABILITY_FAILED DIRADDRESS=%s:%d", + address, me->dir_port); + tor_free(address); + } + } + + return TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT; +} + +DECLARE_EVENT(reachability_warnings, ROUTER, FL(NEED_NET)); + +/* Periodic callback: Every 30 seconds, check whether it's time to make new + * Ed25519 subkeys. + */ +static int +check_ed_keys_callback(time_t now, const or_options_t *options) +{ + if (server_mode(options)) { + if (should_make_new_ed_keys(options, now)) { + int new_signing_key = load_ed_keys(options, now); + if (new_signing_key < 0 || + generate_ed_link_cert(options, now, new_signing_key > 0)) { + log_err(LD_OR, "Unable to update Ed25519 keys! Exiting."); + tor_shutdown_event_loop_and_exit(1); + } + } + return 30; + } + return PERIODIC_EVENT_NO_UPDATE; +} + +DECLARE_EVENT(check_ed_keys, ROUTER, 0); + +/* 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; +} + +DECLARE_EVENT(check_onion_keys_expiry_time, ROUTER, 0); + +void +relay_register_periodic_events(void) +{ + periodic_events_register(&retry_dns_event); + periodic_events_register(&check_dns_honesty_event); + periodic_events_register(&rotate_onion_key_event); + periodic_events_register(&check_descriptor_event); + periodic_events_register(&check_for_reachability_bw_event); + periodic_events_register(&reachability_warnings_event); + periodic_events_register(&check_ed_keys_event); + periodic_events_register(&check_onion_keys_expiry_time_event); + + dns_honesty_first_time = 1; + dirport_reachability_count = 0; +} + +/** + * Update our schedule so that we'll check whether we need to update our + * descriptor immediately, rather than after up to CHECK_DESCRIPTOR_INTERVAL + * seconds. + */ +void +reschedule_descriptor_update_check(void) +{ + periodic_event_reschedule(&check_descriptor_event); +} diff --git a/src/feature/relay/relay_periodic.h b/src/feature/relay/relay_periodic.h new file mode 100644 index 0000000000..b6ea83c749 --- /dev/null +++ b/src/feature/relay/relay_periodic.h @@ -0,0 +1,18 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file relay_periodic.h + * @brief Header for feature/relay/relay_periodic.c + **/ + +#ifndef TOR_FEATURE_RELAY_RELAY_PERIODIC_H +#define TOR_FEATURE_RELAY_RELAY_PERIODIC_H + +void relay_register_periodic_events(void); +void reschedule_descriptor_update_check(void); + +#endif /* !defined(TOR_FEATURE_RELAY_RELAY_PERIODIC_H) */ diff --git a/src/feature/relay/relay_sys.c b/src/feature/relay/relay_sys.c new file mode 100644 index 0000000000..106e88b2a5 --- /dev/null +++ b/src/feature/relay/relay_sys.c @@ -0,0 +1,48 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file relay_sys.c + * @brief Subsystem definitions for the relay module. + **/ + +#include "orconfig.h" +#include "core/or/or.h" + +#include "feature/relay/dns.h" +#include "feature/relay/ext_orport.h" +#include "feature/relay/onion_queue.h" +#include "feature/relay/relay_periodic.h" +#include "feature/relay/relay_sys.h" +#include "feature/relay/routerkeys.h" +#include "feature/relay/router.h" + +#include "lib/subsys/subsys.h" + +static int +subsys_relay_initialize(void) +{ + relay_register_periodic_events(); + return 0; +} + +static void +subsys_relay_shutdown(void) +{ + dns_free_all(); + ext_orport_free_all(); + clear_pending_onions(); + routerkeys_free_all(); + router_free_all(); +} + +const struct subsys_fns_t sys_relay = { + .name = "relay", + .supported = true, + .level = 50, + .initialize = subsys_relay_initialize, + .shutdown = subsys_relay_shutdown, +}; diff --git a/src/feature/relay/relay_sys.h b/src/feature/relay/relay_sys.h new file mode 100644 index 0000000000..32e21d90d8 --- /dev/null +++ b/src/feature/relay/relay_sys.h @@ -0,0 +1,17 @@ +/* Copyright (c) 2001 Matej Pfajfar. + * Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +/** + * @file relay_sys.h + * @brief Header for feature/relay/relay_sys.c + **/ + +#ifndef TOR_FEATURE_RELAY_RELAY_SYS_H +#define TOR_FEATURE_RELAY_RELAY_SYS_H + +extern const struct subsys_fns_t sys_relay; + +#endif /* !defined(TOR_FEATURE_RELAY_RELAY_SYS_H) */ diff --git a/src/feature/relay/selftest.c b/src/feature/relay/selftest.c index eeddd09b63..f8b54ff45d 100644 --- a/src/feature/relay/selftest.c +++ b/src/feature/relay/selftest.c @@ -35,6 +35,7 @@ #include "feature/nodelist/routerlist.h" // but... #include "feature/nodelist/routerset.h" #include "feature/nodelist/torcert.h" +#include "feature/relay/relay_periodic.h" #include "feature/relay/router.h" #include "feature/relay/selftest.h" |