diff options
Diffstat (limited to 'src/or/main.c')
-rw-r--r-- | src/or/main.c | 337 |
1 files changed, 194 insertions, 143 deletions
diff --git a/src/or/main.c b/src/or/main.c index 4fac17a59c..bbee8e0fb9 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -65,7 +65,7 @@ #include <openssl/crypto.h> #endif #include "memarea.h" -#include "../common/sandbox.h" +#include "sandbox.h" #ifdef HAVE_EVENT2_EVENT_H #include <event2/event.h> @@ -99,6 +99,7 @@ static void second_elapsed_callback(periodic_timer_t *timer, void *args); static int conn_close_if_marked(int i); static void connection_start_reading_from_linked_conn(connection_t *conn); static int connection_should_read_from_linked_conn(connection_t *conn); +static int run_main_loop_until_done(void); /********* START VARIABLES **********/ @@ -132,10 +133,6 @@ static uint64_t stats_n_bytes_written = 0; time_t time_of_process_start = 0; /** How many seconds have we been running? */ long stats_n_seconds_working = 0; -/** When do we next launch DNS wildcarding checks? */ -static time_t time_to_check_for_correct_dns = 0; -/** When do we next make sure our Ed25519 keys aren't about to expire? */ -static time_t time_to_check_ed_keys = 0; /** How often will we honor SIGNEWNYM requests? */ #define MAX_SIGNEWNYM_RATE 10 @@ -1205,7 +1202,49 @@ get_signewnym_epoch(void) return newnym_epoch; } -static time_t time_to_check_descriptor = 0; +typedef struct { + time_t last_rotated_x509_certificate; + time_t check_v3_certificate; + time_t check_listeners; + time_t download_networkstatus; + time_t try_getting_descriptors; + time_t reset_descriptor_failures; + time_t add_entropy; + time_t write_bridge_status_file; + time_t downrate_stability; + time_t save_stability; + time_t clean_caches; + time_t recheck_bandwidth; + time_t check_for_expired_networkstatus; + time_t write_stats_files; + time_t write_bridge_stats; + time_t check_port_forwarding; + time_t launch_reachability_tests; + time_t retry_dns_init; + time_t next_heartbeat; + time_t check_descriptor; + /** When do we next launch DNS wildcarding checks? */ + time_t check_for_correct_dns; + /** When do we next make sure our Ed25519 keys aren't about to expire? */ + time_t check_ed_keys; + +} time_to_t; + +static time_to_t time_to = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/** Reset all the time_to's so we'll do all our actions again as if we + * just started up. + * Useful if our clock just moved back a long time from the future, + * so we don't wait until that future arrives again before acting. + */ +void +reset_all_main_loop_timers(void) +{ + memset(&time_to, 0, sizeof(time_to)); +} + /** * Update our schedule so that we'll check whether we need to update our * descriptor immediately, rather than after up to CHECK_DESCRIPTOR_INTERVAL @@ -1214,7 +1253,7 @@ static time_t time_to_check_descriptor = 0; void reschedule_descriptor_update_check(void) { - time_to_check_descriptor = 0; + time_to.check_descriptor = 0; } /** Perform regular maintenance tasks. This function gets run once per @@ -1223,26 +1262,7 @@ reschedule_descriptor_update_check(void) static void run_scheduled_events(time_t now) { - static time_t last_rotated_x509_certificate = 0; - static time_t time_to_check_v3_certificate = 0; - static time_t time_to_check_listeners = 0; - static time_t time_to_download_networkstatus = 0; - static time_t time_to_try_getting_descriptors = 0; - static time_t time_to_reset_descriptor_failures = 0; - static time_t time_to_add_entropy = 0; - static time_t time_to_write_bridge_status_file = 0; - static time_t time_to_downrate_stability = 0; - static time_t time_to_save_stability = 0; - static time_t time_to_clean_caches = 0; - static time_t time_to_recheck_bandwidth = 0; - static time_t time_to_check_for_expired_networkstatus = 0; - static time_t time_to_write_stats_files = 0; - static time_t time_to_write_bridge_stats = 0; - static time_t time_to_check_port_forwarding = 0; - static time_t time_to_launch_reachability_tests = 0; static int should_init_bridge_stats = 1; - static time_t time_to_retry_dns_init = 0; - static time_t time_to_next_heartbeat = 0; const or_options_t *options = get_options(); int is_server = server_mode(options); @@ -1282,7 +1302,7 @@ run_scheduled_events(time_t now) router_upload_dir_desc_to_dirservers(0); } - if (is_server && time_to_check_ed_keys < now) { + if (is_server && time_to.check_ed_keys < now) { if (should_make_new_ed_keys(options, now)) { if (load_ed_keys(options, now) < 0 || generate_ed_link_cert(options, now)) { @@ -1291,22 +1311,22 @@ run_scheduled_events(time_t now) exit(0); } } - time_to_check_ed_keys = now + 30; + time_to.check_ed_keys = now + 30; } if (!should_delay_dir_fetches(options, NULL) && - time_to_try_getting_descriptors < now) { + time_to.try_getting_descriptors < now) { update_all_descriptor_downloads(now); update_extrainfo_downloads(now); if (router_have_minimum_dir_info()) - time_to_try_getting_descriptors = now + LAZY_DESCRIPTOR_RETRY_INTERVAL; + time_to.try_getting_descriptors = now + LAZY_DESCRIPTOR_RETRY_INTERVAL; else - time_to_try_getting_descriptors = now + GREEDY_DESCRIPTOR_RETRY_INTERVAL; + time_to.try_getting_descriptors = now + GREEDY_DESCRIPTOR_RETRY_INTERVAL; } - if (time_to_reset_descriptor_failures < now) { + if (time_to.reset_descriptor_failures < now) { router_reset_descriptor_download_failures(); - time_to_reset_descriptor_failures = + time_to.reset_descriptor_failures = now + DESCRIPTOR_FAILURE_RESET_INTERVAL; } @@ -1315,28 +1335,29 @@ run_scheduled_events(time_t now) /* 1b. Every MAX_SSL_KEY_LIFETIME_INTERNAL seconds, we change our * TLS context. */ - if (!last_rotated_x509_certificate) - last_rotated_x509_certificate = now; - if (last_rotated_x509_certificate+MAX_SSL_KEY_LIFETIME_INTERNAL < now) { + if (!time_to.last_rotated_x509_certificate) + time_to.last_rotated_x509_certificate = now; + if (time_to.last_rotated_x509_certificate + + MAX_SSL_KEY_LIFETIME_INTERNAL < now) { log_info(LD_GENERAL,"Rotating tls context."); if (router_initialize_tls_context() < 0) { log_warn(LD_BUG, "Error reinitializing TLS context"); /* XXX is it a bug here, that we just keep going? -RD */ } - last_rotated_x509_certificate = now; + time_to.last_rotated_x509_certificate = now; /* We also make sure to rotate the TLS connections themselves if they've * been up for too long -- but that's done via is_bad_for_new_circs in * connection_run_housekeeping() above. */ } - if (time_to_add_entropy < now) { - if (time_to_add_entropy) { + if (time_to.add_entropy < now) { + if (time_to.add_entropy) { /* We already seeded once, so don't die on failure. */ - crypto_seed_rng(0); + crypto_seed_rng(); } /** How often do we add more entropy to OpenSSL's RNG pool? */ #define ENTROPY_INTERVAL (60*60) - time_to_add_entropy = now + ENTROPY_INTERVAL; + time_to.add_entropy = now + ENTROPY_INTERVAL; } /* 1c. If we have to change the accounting interval or record @@ -1344,10 +1365,10 @@ run_scheduled_events(time_t now) if (accounting_is_enabled(options)) accounting_run_housekeeping(now); - if (time_to_launch_reachability_tests < now && + if (time_to.launch_reachability_tests < now && (authdir_mode_tests_reachability(options)) && !net_is_disabled()) { - time_to_launch_reachability_tests = now + REACHABILITY_TEST_INTERVAL; + time_to.launch_reachability_tests = now + REACHABILITY_TEST_INTERVAL; /* try to determine reachability of the other Tor relays */ dirserv_test_reachability(now); } @@ -1355,29 +1376,29 @@ run_scheduled_events(time_t now) /* 1d. Periodically, we discount older stability information so that new * stability info counts more, and save the stability information to disk as * appropriate. */ - if (time_to_downrate_stability < now) - time_to_downrate_stability = rep_hist_downrate_old_runs(now); + if (time_to.downrate_stability < now) + time_to.downrate_stability = rep_hist_downrate_old_runs(now); if (authdir_mode_tests_reachability(options)) { - if (time_to_save_stability < now) { - if (time_to_save_stability && rep_hist_record_mtbf_data(now, 1)<0) { + if (time_to.save_stability < now) { + if (time_to.save_stability && rep_hist_record_mtbf_data(now, 1)<0) { log_warn(LD_GENERAL, "Couldn't store mtbf data."); } #define SAVE_STABILITY_INTERVAL (30*60) - time_to_save_stability = now + SAVE_STABILITY_INTERVAL; + time_to.save_stability = now + SAVE_STABILITY_INTERVAL; } } /* 1e. Periodically, if we're a v3 authority, we check whether our cert is * close to expiring and warn the admin if it is. */ - if (time_to_check_v3_certificate < now) { + if (time_to.check_v3_certificate < now) { v3_authority_check_key_expiry(); #define CHECK_V3_CERTIFICATE_INTERVAL (5*60) - time_to_check_v3_certificate = now + CHECK_V3_CERTIFICATE_INTERVAL; + time_to.check_v3_certificate = now + CHECK_V3_CERTIFICATE_INTERVAL; } /* 1f. Check whether our networkstatus has expired. */ - if (time_to_check_for_expired_networkstatus < now) { + if (time_to.check_for_expired_networkstatus < now) { networkstatus_t *ns = networkstatus_get_latest_consensus(); /*XXXX RD: This value needs to be the same as REASONABLY_LIVE_TIME in * networkstatus_get_reasonably_live_consensus(), but that value is way @@ -1388,68 +1409,68 @@ run_scheduled_events(time_t now) router_dir_info_changed(); } #define CHECK_EXPIRED_NS_INTERVAL (2*60) - time_to_check_for_expired_networkstatus = now + CHECK_EXPIRED_NS_INTERVAL; + time_to.check_for_expired_networkstatus = now + CHECK_EXPIRED_NS_INTERVAL; } /* 1g. Check whether we should write statistics to disk. */ - if (time_to_write_stats_files < now) { + if (time_to.write_stats_files < now) { #define CHECK_WRITE_STATS_INTERVAL (60*60) - time_t next_time_to_write_stats_files = (time_to_write_stats_files > 0 ? - time_to_write_stats_files : now) + CHECK_WRITE_STATS_INTERVAL; + time_t next_time_to_write_stats_files = (time_to.write_stats_files > 0 ? + time_to.write_stats_files : now) + CHECK_WRITE_STATS_INTERVAL; if (options->CellStatistics) { time_t next_write = - rep_hist_buffer_stats_write(time_to_write_stats_files); + rep_hist_buffer_stats_write(time_to.write_stats_files); if (next_write && next_write < next_time_to_write_stats_files) next_time_to_write_stats_files = next_write; } if (options->DirReqStatistics) { - time_t next_write = geoip_dirreq_stats_write(time_to_write_stats_files); + time_t next_write = geoip_dirreq_stats_write(time_to.write_stats_files); if (next_write && next_write < next_time_to_write_stats_files) next_time_to_write_stats_files = next_write; } if (options->EntryStatistics) { - time_t next_write = geoip_entry_stats_write(time_to_write_stats_files); + time_t next_write = geoip_entry_stats_write(time_to.write_stats_files); if (next_write && next_write < next_time_to_write_stats_files) next_time_to_write_stats_files = next_write; } if (options->HiddenServiceStatistics) { - time_t next_write = rep_hist_hs_stats_write(time_to_write_stats_files); + time_t next_write = rep_hist_hs_stats_write(time_to.write_stats_files); if (next_write && next_write < next_time_to_write_stats_files) next_time_to_write_stats_files = next_write; } if (options->ExitPortStatistics) { - time_t next_write = rep_hist_exit_stats_write(time_to_write_stats_files); + time_t next_write = rep_hist_exit_stats_write(time_to.write_stats_files); if (next_write && next_write < next_time_to_write_stats_files) next_time_to_write_stats_files = next_write; } if (options->ConnDirectionStatistics) { - time_t next_write = rep_hist_conn_stats_write(time_to_write_stats_files); + time_t next_write = rep_hist_conn_stats_write(time_to.write_stats_files); if (next_write && next_write < next_time_to_write_stats_files) next_time_to_write_stats_files = next_write; } if (options->BridgeAuthoritativeDir) { - time_t next_write = rep_hist_desc_stats_write(time_to_write_stats_files); + time_t next_write = rep_hist_desc_stats_write(time_to.write_stats_files); if (next_write && next_write < next_time_to_write_stats_files) next_time_to_write_stats_files = next_write; } - time_to_write_stats_files = next_time_to_write_stats_files; + time_to.write_stats_files = next_time_to_write_stats_files; } /* 1h. Check whether we should write bridge statistics to disk. */ if (should_record_bridge_info(options)) { - if (time_to_write_bridge_stats < now) { + if (time_to.write_bridge_stats < now) { if (should_init_bridge_stats) { /* (Re-)initialize bridge statistics. */ geoip_bridge_stats_init(now); - time_to_write_bridge_stats = now + WRITE_STATS_INTERVAL; + time_to.write_bridge_stats = now + WRITE_STATS_INTERVAL; should_init_bridge_stats = 0; } else { /* Possibly write bridge statistics to disk and ask when to write * them next time. */ - time_to_write_bridge_stats = geoip_bridge_stats_write( - time_to_write_bridge_stats); + time_to.write_bridge_stats = geoip_bridge_stats_write( + time_to.write_bridge_stats); } } } else if (!should_init_bridge_stats) { @@ -1459,19 +1480,19 @@ run_scheduled_events(time_t now) } /* Remove old information from rephist and the rend cache. */ - if (time_to_clean_caches < now) { + if (time_to.clean_caches < now) { rep_history_clean(now - options->RephistTrackTime); rend_cache_clean(now); rend_cache_clean_v2_descs_as_dir(now, 0); microdesc_cache_rebuild(NULL, 0); #define CLEAN_CACHES_INTERVAL (30*60) - time_to_clean_caches = now + CLEAN_CACHES_INTERVAL; + time_to.clean_caches = now + CLEAN_CACHES_INTERVAL; } #define RETRY_DNS_INTERVAL (10*60) /* If we're a server and initializing dns failed, retry periodically. */ - if (time_to_retry_dns_init < now) { - time_to_retry_dns_init = now + RETRY_DNS_INTERVAL; + if (time_to.retry_dns_init < now) { + time_to.retry_dns_init = now + RETRY_DNS_INTERVAL; if (is_server && has_dns_init_failed()) dns_init(); } @@ -1486,9 +1507,9 @@ run_scheduled_events(time_t now) /* 2b. Once per minute, regenerate and upload the descriptor if the old * one is inaccurate. */ - if (time_to_check_descriptor < now && !options->DisableNetwork) { + if (time_to.check_descriptor < now && !options->DisableNetwork) { static int dirport_reachability_count = 0; - time_to_check_descriptor = now + CHECK_DESCRIPTOR_INTERVAL; + time_to.check_descriptor = now + CHECK_DESCRIPTOR_INTERVAL; check_descriptor_bandwidth_changed(now); check_descriptor_ipaddress_changed(now); mark_my_descriptor_dirty_if_too_old(now); @@ -1502,18 +1523,18 @@ run_scheduled_events(time_t now) consider_testing_reachability(1, dirport_reachability_count==0); if (++dirport_reachability_count > 5) dirport_reachability_count = 0; - } else if (time_to_recheck_bandwidth < now) { + } else if (time_to.recheck_bandwidth < now) { /* 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(); - if (time_to_recheck_bandwidth && me && + if (time_to.recheck_bandwidth && me && me->bandwidthcapacity < me->bandwidthrate && me->bandwidthcapacity < 51200) { reset_bandwidth_test(); } #define BANDWIDTH_RECHECK_INTERVAL (12*60*60) - time_to_recheck_bandwidth = now + BANDWIDTH_RECHECK_INTERVAL; + time_to.recheck_bandwidth = now + BANDWIDTH_RECHECK_INTERVAL; } } @@ -1531,8 +1552,8 @@ run_scheduled_events(time_t now) #define networkstatus_dl_check_interval(o) ((o)->TestingTorNetwork ? 1 : 60) if (!should_delay_dir_fetches(options, NULL) && - time_to_download_networkstatus < now) { - time_to_download_networkstatus = + time_to.download_networkstatus < now) { + time_to.download_networkstatus = now + networkstatus_dl_check_interval(options); update_networkstatus_downloads(now); } @@ -1562,9 +1583,9 @@ run_scheduled_events(time_t now) connection_expire_held_open(); /* 3d. And every 60 seconds, we relaunch listeners if any died. */ - if (!net_is_disabled() && time_to_check_listeners < now) { + if (!net_is_disabled() && time_to.check_listeners < now) { retry_all_listeners(NULL, NULL, 0); - time_to_check_listeners = now+60; + time_to.check_listeners = now+60; } /* 4. Every second, we try a new circuit if there are no valid @@ -1616,28 +1637,29 @@ run_scheduled_events(time_t now) * to us. */ if (!net_is_disabled() && public_server_mode(options) && - time_to_check_for_correct_dns < now && + time_to.check_for_correct_dns < now && ! router_my_exit_policy_is_reject_star()) { - if (!time_to_check_for_correct_dns) { - time_to_check_for_correct_dns = now + 60 + crypto_rand_int(120); + if (!time_to.check_for_correct_dns) { + time_to.check_for_correct_dns = + crypto_rand_time_range(now + 60, now + 180); } else { dns_launch_correctness_checks(); - time_to_check_for_correct_dns = now + 12*3600 + + time_to.check_for_correct_dns = now + 12*3600 + crypto_rand_int(12*3600); } } /* 10. write bridge networkstatus file to disk */ if (options->BridgeAuthoritativeDir && - time_to_write_bridge_status_file < now) { + time_to.write_bridge_status_file < now) { networkstatus_dump_bridge_status_to_file(now); #define BRIDGE_STATUSFILE_INTERVAL (30*60) - time_to_write_bridge_status_file = now+BRIDGE_STATUSFILE_INTERVAL; + time_to.write_bridge_status_file = now+BRIDGE_STATUSFILE_INTERVAL; } /* 11. check the port forwarding app */ if (!net_is_disabled() && - time_to_check_port_forwarding < now && + time_to.check_port_forwarding < now && options->PortForwarding && is_server) { #define PORT_FORWARDING_CHECK_INTERVAL 5 @@ -1650,7 +1672,7 @@ run_scheduled_events(time_t now) SMARTLIST_FOREACH(ports_to_forward, char *, cp, tor_free(cp)); smartlist_free(ports_to_forward); } - time_to_check_port_forwarding = now+PORT_FORWARDING_CHECK_INTERVAL; + time_to.check_port_forwarding = now+PORT_FORWARDING_CHECK_INTERVAL; } /* 11b. check pending unconfigured managed proxies */ @@ -1659,10 +1681,10 @@ run_scheduled_events(time_t now) /* 12. write the heartbeat message */ if (options->HeartbeatPeriod && - time_to_next_heartbeat <= now) { - if (time_to_next_heartbeat) /* don't log the first heartbeat */ + time_to.next_heartbeat <= now) { + if (time_to.next_heartbeat) /* don't log the first heartbeat */ log_heartbeat(now); - time_to_next_heartbeat = now+options->HeartbeatPeriod; + time_to.next_heartbeat = now+options->HeartbeatPeriod; } } @@ -1762,8 +1784,6 @@ second_elapsed_callback(periodic_timer_t *timer, void *arg) if (seconds_elapsed < -NUM_JUMPED_SECONDS_BEFORE_WARN || seconds_elapsed >= NUM_JUMPED_SECONDS_BEFORE_WARN) { circuit_note_clock_jumped(seconds_elapsed); - /* XXX if the time jumps *back* many months, do our events in - * run_scheduled_events() recover? I don't think they do. -RD */ } else if (seconds_elapsed > 0) stats_n_seconds_working += seconds_elapsed; @@ -1887,7 +1907,7 @@ dns_servers_relaunch_checks(void) { if (server_mode(get_options())) { dns_reset_correctness_checks(); - time_to_check_for_correct_dns = 0; + time_to.check_for_correct_dns = 0; } } @@ -1971,7 +1991,6 @@ do_hup(void) int do_main_loop(void) { - int loop_result; time_t now; /* initialize dns resolve map, spawn workers if needed */ @@ -2117,51 +2136,78 @@ do_main_loop(void) } #endif - for (;;) { - if (nt_service_is_stopping()) - return 0; + return run_main_loop_until_done(); +} + +/** + * Run the main loop a single time. Return 0 for "exit"; -1 for "exit with + * error", and 1 for "run this again." + */ +static int +run_main_loop_once(void) +{ + int loop_result; + + if (nt_service_is_stopping()) + return 0; #ifndef _WIN32 - /* Make it easier to tell whether libevent failure is our fault or not. */ - errno = 0; + /* Make it easier to tell whether libevent failure is our fault or not. */ + errno = 0; #endif - /* All active linked conns should get their read events activated. */ - SMARTLIST_FOREACH(active_linked_connection_lst, connection_t *, conn, - event_active(conn->read_event, EV_READ, 1)); - called_loop_once = smartlist_len(active_linked_connection_lst) ? 1 : 0; - - update_approx_time(time(NULL)); - - /* poll until we have an event, or the second ends, or until we have - * some active linked connections to trigger events for. */ - loop_result = event_base_loop(tor_libevent_get_base(), - called_loop_once ? EVLOOP_ONCE : 0); - - /* let catch() handle things like ^c, and otherwise don't worry about it */ - if (loop_result < 0) { - int e = tor_socket_errno(-1); - /* let the program survive things like ^z */ - if (e != EINTR && !ERRNO_IS_EINPROGRESS(e)) { - log_err(LD_NET,"libevent call with %s failed: %s [%d]", - tor_libevent_get_method(), tor_socket_strerror(e), e); - return -1; + /* All active linked conns should get their read events activated. */ + SMARTLIST_FOREACH(active_linked_connection_lst, connection_t *, conn, + event_active(conn->read_event, EV_READ, 1)); + called_loop_once = smartlist_len(active_linked_connection_lst) ? 1 : 0; + + update_approx_time(time(NULL)); + + /* poll until we have an event, or the second ends, or until we have + * some active linked connections to trigger events for. */ + loop_result = event_base_loop(tor_libevent_get_base(), + called_loop_once ? EVLOOP_ONCE : 0); + + /* let catch() handle things like ^c, and otherwise don't worry about it */ + if (loop_result < 0) { + int e = tor_socket_errno(-1); + /* let the program survive things like ^z */ + if (e != EINTR && !ERRNO_IS_EINPROGRESS(e)) { + log_err(LD_NET,"libevent call with %s failed: %s [%d]", + tor_libevent_get_method(), tor_socket_strerror(e), e); + return -1; #ifndef _WIN32 - } else if (e == EINVAL) { - log_warn(LD_NET, "EINVAL from libevent: should you upgrade libevent?"); - if (got_libevent_error()) - return -1; + } else if (e == EINVAL) { + log_warn(LD_NET, "EINVAL from libevent: should you upgrade libevent?"); + if (got_libevent_error()) + return -1; #endif - } else { - if (ERRNO_IS_EINPROGRESS(e)) - log_warn(LD_BUG, - "libevent call returned EINPROGRESS? Please report."); - log_debug(LD_NET,"libevent call interrupted."); - /* You can't trust the results of this poll(). Go back to the - * top of the big for loop. */ - continue; - } + } else { + if (ERRNO_IS_EINPROGRESS(e)) + log_warn(LD_BUG, + "libevent call returned EINPROGRESS? Please report."); + log_debug(LD_NET,"libevent call interrupted."); + /* You can't trust the results of this poll(). Go back to the + * top of the big for loop. */ + return 1; } } + + return 1; +} + +/** Run the run_main_loop_once() function until it declares itself done, + * and return its final return value. + * + * Shadow won't invoke this function, so don't fill it up with things. + */ +static int +run_main_loop_until_done(void) +{ + int loop_result = 1; + do { + loop_result = run_main_loop_once(); + } while (loop_result == 1); + return loop_result; } #ifndef _WIN32 /* Only called when we're willing to use signals */ @@ -2321,12 +2367,13 @@ dumpstats(int severity) if (conn->type == CONN_TYPE_OR) { or_connection_t *or_conn = TO_OR_CONN(conn); if (or_conn->tls) { - tor_tls_get_buffer_sizes(or_conn->tls, &rbuf_cap, &rbuf_len, - &wbuf_cap, &wbuf_len); - tor_log(severity, LD_GENERAL, - "Conn %d: %d/%d bytes used on OpenSSL read buffer; " - "%d/%d bytes used on write buffer.", - i, (int)rbuf_len, (int)rbuf_cap, (int)wbuf_len, (int)wbuf_cap); + if (tor_tls_get_buffer_sizes(or_conn->tls, &rbuf_cap, &rbuf_len, + &wbuf_cap, &wbuf_len) == 0) { + tor_log(severity, LD_GENERAL, + "Conn %d: %d/%d bytes used on OpenSSL read buffer; " + "%d/%d bytes used on write buffer.", + i, (int)rbuf_len, (int)rbuf_cap, (int)wbuf_len, (int)wbuf_cap); + } } } } @@ -2490,10 +2537,11 @@ tor_init(int argc, char *argv[]) if (!strcmp(cl->key, "--quiet") || !strcmp(cl->key, "--dump-config")) quiet = 2; - /* --version, --digests, and --help imply --hush */ + /* The following options imply --hush */ if (!strcmp(cl->key, "--version") || !strcmp(cl->key, "--digests") || !strcmp(cl->key, "--list-torrc-options") || !strcmp(cl->key, "--library-versions") || + !strcmp(cl->key, "--hash-password") || !strcmp(cl->key, "-h") || !strcmp(cl->key, "--help")) { if (quiet < 1) quiet = 1; @@ -2811,6 +2859,7 @@ do_dump_config(void) const char *arg = options->command_arg; int how; char *opts; + if (!strcmp(arg, "short")) { how = OPTIONS_DUMP_MINIMAL; } else if (!strcmp(arg, "non-builtin")) { @@ -2818,8 +2867,9 @@ do_dump_config(void) } else if (!strcmp(arg, "full")) { how = OPTIONS_DUMP_ALL; } else { - printf("%s is not a recognized argument to --dump-config. " - "Please select 'short', 'non-builtin', or 'full'", arg); + fprintf(stderr, "No valid argument to --dump-config found!\n"); + fprintf(stderr, "Please select 'short', 'non-builtin', or 'full'.\n"); + return -1; } @@ -3120,7 +3170,8 @@ tor_main(int argc, char *argv[]) result = 0; break; case CMD_VERIFY_CONFIG: - printf("Configuration was valid\n"); + if (quiet_level == 0) + printf("Configuration was valid\n"); result = 0; break; case CMD_DUMP_CONFIG: |