From b7452dcbcb2f086e3fd7daf0c31b95d9e777190a Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Tue, 10 May 2011 05:15:02 -0700 Subject: [PATCH 01/22] Fix comment typo --- src/common/compat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/compat.h b/src/common/compat.h index af795ffba9..8144026ff0 100644 --- a/src/common/compat.h +++ b/src/common/compat.h @@ -398,7 +398,7 @@ int get_n_open_sockets(void); #define tor_socket_send(s, buf, len, flags) send(s, buf, len, flags) #define tor_socket_recv(s, buf, len, flags) recv(s, buf, len, flags) -/** Implementatino of struct in6_addr for platforms that do not have it. +/** Implementation of struct in6_addr for platforms that do not have it. * Generally, these platforms are ones without IPv6 support, but we want to * have a working in6_addr there anyway, so we can use it to parse IPv6 * addresses. */ From cb9df5e53c169efc0ec1ccbfeea4c8d2878b1a39 Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Thu, 12 May 2011 00:27:19 -0700 Subject: [PATCH 02/22] Fix comment typo --- src/common/compat_libevent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/compat_libevent.c b/src/common/compat_libevent.c index 3ad9be145d..6d89be804b 100644 --- a/src/common/compat_libevent.c +++ b/src/common/compat_libevent.c @@ -48,7 +48,7 @@ typedef uint32_t le_version_t; * it is. */ #define LE_OLD V(0,0,0) /** Represents a version of libevent so weird we can't figure out what version - * it it. */ + * it is. */ #define LE_OTHER V(0,0,99) static le_version_t tor_get_libevent_version(const char **v_out); From c714a098ea96fcd452a223ce7bbc6bfa2a6f0d02 Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Thu, 12 May 2011 02:57:09 -0700 Subject: [PATCH 03/22] Improve a documentation comment --- src/common/util.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/common/util.c b/src/common/util.c index 38c0ad05e6..014b3349af 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -769,13 +769,17 @@ tor_digest256_is_zero(const char *digest) if (next) *next = endptr; \ return 0 -/** Extract a long from the start of s, in the given numeric base. If - * there is unconverted data and next is provided, set *next to the - * first unconverted character. An error has occurred if no characters - * are converted; or if there are unconverted characters and next is NULL; or - * if the parsed value is not between min and max. When no error occurs, - * return the parsed value and set *ok (if provided) to 1. When an error - * occurs, return 0 and set *ok (if provided) to 0. +/** Extract a long from the start of s, in the given numeric + * base. If base is 0, s is parsed as a decimal, + * octal, or hex number in the syntax of a C integer literal. If + * there is unconverted data and next is provided, set + * *next to the first unconverted character. An error has + * occurred if no characters are converted; or if there are + * unconverted characters and next is NULL; or if the parsed + * value is not between min and max. When no error + * occurs, return the parsed value and set *ok (if provided) to + * 1. When an error occurs, return 0 and set *ok (if provided) + * to 0. */ long tor_parse_long(const char *s, int base, long min, long max, From 4b266c6e72254d848b2ca4f594c0b41770104d81 Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Sun, 15 May 2011 08:23:04 -0700 Subject: [PATCH 04/22] Implement __OwningControllerProcess option Implements part of feature 3049. --- src/common/Makefile.am | 4 +- src/common/procmon.c | 331 +++++++++++++++++++++++++++++++++++++++++ src/common/procmon.h | 29 ++++ src/or/config.c | 18 +++ src/or/control.c | 86 +++++++++++ src/or/control.h | 2 + src/or/or.h | 5 + 7 files changed, 473 insertions(+), 2 deletions(-) create mode 100644 src/common/procmon.c create mode 100644 src/common/procmon.h diff --git a/src/common/Makefile.am b/src/common/Makefile.am index b1e03cd710..88892455e7 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -12,11 +12,11 @@ libor_extra_source= endif libor_a_SOURCES = address.c log.c util.c compat.c container.c mempool.c \ - memarea.c util_codedigest.c $(libor_extra_source) + memarea.c util_codedigest.c procmon.c $(libor_extra_source) libor_crypto_a_SOURCES = crypto.c aes.c tortls.c torgzip.c libor_event_a_SOURCES = compat_libevent.c -noinst_HEADERS = address.h torlog.h crypto.h util.h compat.h aes.h torint.h tortls.h strlcpy.c strlcat.c torgzip.h container.h ht.h mempool.h memarea.h ciphers.inc compat_libevent.h tortls_states.h +noinst_HEADERS = address.h torlog.h crypto.h util.h compat.h aes.h torint.h tortls.h strlcpy.c strlcat.c torgzip.h container.h ht.h mempool.h memarea.h procmon.h ciphers.inc compat_libevent.h tortls_states.h common_sha1.i: $(libor_SOURCES) $(libor_crypto_a_SOURCES) $(noinst_HEADERS) if test "@SHA1SUM@" != none; then \ diff --git a/src/common/procmon.c b/src/common/procmon.c new file mode 100644 index 0000000000..cee956a52f --- /dev/null +++ b/src/common/procmon.c @@ -0,0 +1,331 @@ + +/** + * \file procmon.c + * \brief Process-termination monitor functions + **/ + +#include "procmon.h" + +#include "util.h" + +#ifdef HAVE_EVENT2_EVENT_H +#include +#else +#include +#endif + +#ifdef HAVE_SIGNAL_H +#include +#endif +#ifdef HAVE_ERRNO_H +#include +#endif + +#ifdef MS_WINDOWS +#include + +/* Windows does not define pid_t, but _getpid() returns an int. */ +typedef int pid_t; +#endif + +/* Define to 1 if process-termination monitors on this OS and Libevent + version must poll for process termination themselves. */ +#define PROCMON_POLLS 1 +/* Currently we need to poll in some way on all systems. */ + +#ifdef PROCMON_POLLS +static void tor_process_monitor_poll_cb(int unused1, short unused2, + void *procmon_); +#endif + +/* This struct may contain pointers into the original process + * specifier string, but it should *never* contain anything which + * needs to be freed. */ +struct parsed_process_specifier_t { + pid_t pid; +}; + +/** Parse the process specifier given in process_spec into + * *ppspec. Return 0 on success; return -1 and store an error + * message into *msg on failure. The caller must not free the + * returned error message. */ +static int +parse_process_specifier(const char *process_spec, + struct parsed_process_specifier_t *ppspec, + const char **msg) +{ + long pid_l; + int pid_ok = 0; + char *pspec_next; + + /* If we're lucky, long will turn out to be large enough to hold a + * PID everywhere that Tor runs. */ + pid_l = tor_parse_long(process_spec, 0, 1, LONG_MAX, &pid_ok, &pspec_next); + + /* Reserve room in the ‘process specifier’ for additional + * (platform-specific) identifying information beyond the PID, to + * make our process-existence checks a bit less racy in a future + * version. */ + if ((*pspec_next != 0) && (*pspec_next != ' ') && (*pspec_next != ':')) { + pid_ok = 0; + } + + ppspec->pid = (pid_t)(pid_l); + if (!pid_ok || (pid_l != (long)(ppspec->pid))) { + *msg = "invalid PID"; + goto err; + } + + return 0; + err: + return -1; +} + +struct tor_process_monitor_t { + /** Log domain for warning messages. */ + log_domain_mask_t log_domain; + + /** All systems: The best we can do in general is poll for the + * process's existence by PID periodically, and hope that the kernel + * doesn't reassign the same PID to another process between our + * polls. */ + pid_t pid; + +#ifdef MS_WINDOWS + /** Windows-only: Should we poll hproc? If false, poll pid + * instead. */ + int poll_hproc; + + /** Windows-only: Get a handle to the process (if possible) and + * periodically check whether the process we have a handle to has + * ended. */ + HANDLE hproc; + /* XXX023 We can and should have Libevent watch hproc for us, + * if/when some version of Libevent 2.x can be told to do so. */ +#endif + + /* XXX023 On Linux, we can and should receive the 22nd + * (space-delimited) field (‘starttime’) of /proc/$PID/stat from the + * owning controller and store it, and poll once in a while to see + * whether it has changed -- if so, the kernel has *definitely* + * reassigned the owning controller's PID and we should exit. On + * FreeBSD, we can do the same trick using either the 8th + * space-delimited field of /proc/$PID/status on the seven FBSD + * systems whose admins have mounted procfs, or the start-time field + * of the process-information structure returned by kvmgetprocs() on + * any system. The latter is ickier. */ + /* XXX023 On FreeBSD (and possibly other kqueue systems), we can and + * should arrange to receive EVFILT_PROC NOTE_EXIT notifications for + * pid, so we don't have to do such a heavyweight poll operation in + * order to avoid the PID-reassignment race condition. (We would + * still need to poll our own kqueue periodically until some version + * of Libevent 2.x learns to receive these events for us.) */ + + /** A Libevent event structure, to either poll for the process's + * existence or receive a notification when the process ends. */ + struct event *e; + + /** A callback to be called when the process ends. */ + tor_procmon_callback_t cb; + void *cb_arg; /**< A user-specified pointer to be passed to cb. */ +}; + +/** Verify that the process specifier given in process_spec is + * syntactically valid. Return 0 on success; return -1 and store an + * error message into *msg on failure. The caller must not + * free the returned error message. */ +int +tor_validate_process_specifier(const char *process_spec, + const char **msg) +{ + struct parsed_process_specifier_t ppspec; + + tor_assert(msg != NULL); + *msg = NULL; + + return parse_process_specifier(process_spec, &ppspec, msg); +} + +#ifdef HAVE_EVENT2_EVENT_H +#define PERIODIC_TIMER_FLAGS EV_PERSIST +#else +#define PERIODIC_TIMER_FLAGS (0) +#endif + +static const struct timeval poll_interval_tv = {15, 0}; + +/** Create a process-termination monitor for the process specifier + * given in process_spec. Return a newly allocated + * tor_process_monitor_t on success; return NULL and store an error + * message into *msg on failure. The caller must not free + * the returned error message. + * + * When the monitored process terminates, call + * cb(cb_arg). + */ +tor_process_monitor_t * +tor_process_monitor_new(struct event_base *base, + const char *process_spec, + log_domain_mask_t log_domain, + tor_procmon_callback_t cb, void *cb_arg, + const char **msg) +{ + tor_process_monitor_t *procmon = tor_malloc(sizeof(tor_process_monitor_t)); + struct parsed_process_specifier_t ppspec; + + tor_assert(msg != NULL); + *msg = NULL; + + if (procmon == NULL) { + *msg = "out of memory"; + goto err; + } + + procmon->log_domain = log_domain; + + if (parse_process_specifier(process_spec, &ppspec, msg)) + goto err; + + procmon->pid = ppspec.pid; + +#ifdef MS_WINDOWS + procmon->hproc = OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE, + FALSE, + procmon->pid); + + if (procmon->hproc != NULL) { + procmon->poll_hproc = 1; + log_info(procmon->log_domain, "Successfully opened handle to process %d; " + "monitoring it.", + (int)(procmon->pid)); + } else { + /* If we couldn't get a handle to the process, we'll try again the + * first time we poll. */ + log_info(procmon->log_domain, "Failed to open handle to process %d; will " + "try again later.", + (int)(procmon->pid)); + } +#endif + + procmon->cb = cb; + procmon->cb_arg = cb_arg; + +#ifdef PROCMON_POLLS + procmon->e = tor_event_new(base, -1 /* no FD */, PERIODIC_TIMER_FLAGS, + tor_process_monitor_poll_cb, procmon); + /* Note: If you port this file to plain Libevent 2, check that + * procmon->e is non-NULL. We don't need to here because + * tor_evtimer_new never returns NULL. */ + + evtimer_add(procmon->e, &poll_interval_tv); +#else +#error OOPS? +#endif + + return procmon; + err: + tor_process_monitor_free(procmon); + return NULL; +} + +#ifdef PROCMON_POLLS +/** Libevent callback to poll for the existence of the process + * monitored by procmon_. */ +static void +tor_process_monitor_poll_cb(int unused1, short unused2, void *procmon_) +{ + tor_process_monitor_t *procmon = (tor_process_monitor_t *)(procmon_); + int its_dead_jim; + + (void)unused1; (void)unused2; + + tor_assert(procmon != NULL); + +#ifdef MS_WINDOWS + if (procmon->poll_hproc) { + DWORD exit_code; + if (!GetExitCodeProcess(procmon->hproc, &exit_code)) { + char *errmsg = format_win32_error(GetLastError()); + log_warn(procmon->log_domain, "Error \"%s\" occurred while polling " + "handle for monitored process %d; assuming it's dead." + errmsg, procmon->pid); + tor_free(errmsg); + its_dead_jim = 1; + } else { + its_dead_jim = (exit_code != STILL_ACTIVE); + } + } else { + /* All we can do is try to open the process, and look at the error + * code if it fails again. */ + procmon->hproc = OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE, + FALSE, + procmon->pid); + + if (procmon->hproc != NULL) { + log_info(procmon->log_domain, "Successfully opened handle to monitored " + "process %d.", + procmon->pid); + its_dead_jim = 0; + procmon->poll_hproc = 1; + } else { + DWORD err_code = GetLastError(); + char *errmsg = format_win32_error(err_code); + + /* When I tested OpenProcess's error codes on Windows 7, I + * received error code 5 (ERROR_ACCESS_DENIED) for PIDs of + * existing processes that I could not open and error code 87 + * (ERROR_INVALID_PARAMETER) for PIDs that were not in use. + * Since the nonexistent-process error code is sane, I'm going + * to assume that all errors other than ERROR_INVALID_PARAMETER + * mean that the process we are monitoring is still alive. */ + its_dead_jim = (err_code == ERROR_INVALID_PARAMETER); + + if (!its_dead_jim) + log_info(procmon->log_domain, "Failed to open handle to monitored " + "process %d, and error code %d (%s) is not 'invalid " + "parameter' -- assuming the process is still alive.", + procmon->pid, + err_code, err_msg); + + tor_free(err_msg); + } + } +#else + /* Unix makes this part easy, if a bit racy. */ + its_dead_jim = kill(procmon->pid, 0); + its_dead_jim = its_dead_jim && (errno == ESRCH); +#endif + + log(its_dead_jim ? LOG_NOTICE : LOG_INFO, + procmon->log_domain, "Monitored process %d is %s.", + (int)procmon->pid, + its_dead_jim ? "dead" : "still alive"); + + if (its_dead_jim) { + procmon->cb(procmon->cb_arg); +#ifndef HAVE_EVENT2_EVENT_H + } else { + evtimer_add(procmon->e, &poll_interval_tv); +#endif + } +} +#endif + +/** Free the process-termination monitor procmon. */ +void +tor_process_monitor_free(tor_process_monitor_t *procmon) +{ + if (procmon == NULL) + return; + +#ifdef MS_WINDOWS + if (procmon->hproc != NULL) + CloseHandle(procmon->hproc); +#endif + + if (procmon->e != NULL) + tor_event_free(procmon->e); + + tor_free(procmon); +} + diff --git a/src/common/procmon.h b/src/common/procmon.h new file mode 100644 index 0000000000..f8c7444d5e --- /dev/null +++ b/src/common/procmon.h @@ -0,0 +1,29 @@ + +/** + * \file procmon.h + * \brief Headers for procmon.c + **/ + +#ifndef TOR_PROCMON_H +#define TOR_PROCMON_H + +#include "compat.h" +#include "compat_libevent.h" + +#include "torlog.h" + +typedef struct tor_process_monitor_t tor_process_monitor_t; + +typedef void (*tor_procmon_callback_t)(void *); + +int tor_validate_process_specifier(const char *process_spec, + const char **msg); +tor_process_monitor_t *tor_process_monitor_new(struct event_base *base, + const char *process_spec, + log_domain_mask_t log_domain, + tor_procmon_callback_t cb, + void *cb_arg, + const char **msg); +void tor_process_monitor_free(tor_process_monitor_t *procmon); + +#endif diff --git a/src/or/config.c b/src/or/config.c index 34208e85bf..b2bc9f3e9a 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -38,6 +38,8 @@ #include #endif +#include "procmon.h" + /** Enumeration of types which option values can take */ typedef enum config_type_t { CONFIG_TYPE_STRING = 0, /**< An arbitrary string. */ @@ -393,6 +395,7 @@ static config_var_t _option_vars[] = { VAR("__LeaveStreamsUnattached",BOOL, LeaveStreamsUnattached, "0"), VAR("__HashedControlSessionPassword", LINELIST, HashedControlSessionPassword, NULL), + VAR("__OwningControllerProcess",STRING,OwningControllerProcess, NULL), V(MinUptimeHidServDirectoryV2, INTERVAL, "24 hours"), V(_UsingTestNetworkDefaults, BOOL, "0"), @@ -1229,6 +1232,11 @@ options_act(or_options_t *old_options) return -1; } + if (monitor_owning_controller_process(options->OwningControllerProcess)) { + log_warn(LD_CONFIG, "Error monitoring owning controller process"); + return -1; + } + /* reload keys as needed for rendezvous services. */ if (rend_service_load_keys()<0) { log_warn(LD_GENERAL,"Error loading rendezvous service keys"); @@ -3446,6 +3454,16 @@ options_validate(or_options_t *old_options, or_options_t *options, } } + if (options->OwningControllerProcess) { + const char *validate_pspec_msg = NULL; + if (tor_validate_process_specifier(options->OwningControllerProcess, + &validate_pspec_msg)) { + tor_asprintf(msg, "Bad OwningControllerProcess: %s", + validate_pspec_msg); + return -1; + } + } + if (options->ControlListenAddress) { int all_are_local = 1; config_line_t *ln; diff --git a/src/or/control.c b/src/or/control.c index 926a465203..3a96904438 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -32,6 +32,8 @@ #include "routerlist.h" #include "routerparse.h" +#include "procmon.h" + /** Yield true iff s is the state of a control_connection_t that has * finished authentication and is accepting commands. */ #define STATE_IS_OPEN(s) ((s) == CONTROL_CONN_STATE_OPEN) @@ -3779,6 +3781,90 @@ init_cookie_authentication(int enabled) return 0; } +/** A copy of the process specifier of Tor's owning controller, or + * NULL if this Tor instance is not currently owned by a process. */ +static char *owning_controller_process_spec = NULL; + +/** A process-termination monitor for Tor's owning controller, or NULL + * if this Tor instance is not currently owned by a process. */ +static tor_process_monitor_t *owning_controller_process_monitor = NULL; + +/** Process-termination monitor callback for Tor's owning controller + * process. */ +static void +owning_controller_procmon_cb(void *unused) +{ + int shutdown_slowly = server_mode(get_options()); + + (void)unused; + + log_notice(LD_CONTROL, "Owning controller process has vanished -- " + "%s.", + shutdown_slowly ? "shutting down" : "exiting now"); + + /* XXXX This chunk of code should be a separate function, called + * here and by process_signal(SIGINT). */ + + if (!shutdown_slowly) { + tor_cleanup(); + exit(0); + } + /* XXXX This will close all listening sockets except control-port + * listeners. Perhaps we should close those too. */ + hibernate_begin_shutdown(); +} + +/** Set process_spec as Tor's owning controller process. + * Return 0 on success, -1 on failure. */ +int +monitor_owning_controller_process(const char *process_spec) +{ + const char *msg; + + tor_assert((owning_controller_process_spec == NULL) == + (owning_controller_process_monitor == NULL)); + + if (owning_controller_process_spec != NULL) { + if ((process_spec != NULL) && !strcmp(process_spec, + owning_controller_process_spec)) { + /* Same process -- return now, instead of disposing of and + * recreating the process-termination monitor. */ + return 0; + } + + /* We are currently owned by a process, and we should no longer be + * owned by it. Free the process-termination monitor. */ + tor_process_monitor_free(owning_controller_process_monitor); + owning_controller_process_monitor = NULL; + + tor_free(owning_controller_process_spec); + owning_controller_process_spec = NULL; + } + + tor_assert((owning_controller_process_spec == NULL) && + (owning_controller_process_monitor == NULL)); + + if (process_spec == NULL) + return 0; + + owning_controller_process_spec = tor_strdup(process_spec); + owning_controller_process_monitor = + tor_process_monitor_new(tor_libevent_get_base(), + owning_controller_process_spec, + LD_CONTROL, + owning_controller_procmon_cb, NULL, + &msg); + + if (owning_controller_process_monitor == NULL) { + log_warn(LD_CONTROL, "Couldn't create process-termination monitor for " + "owning controller: %s", + msg); + return -1; + } + + return 0; +} + /** Convert the name of a bootstrapping phase s into strings * tag and summary suitable for display by the controller. */ static int diff --git a/src/or/control.h b/src/or/control.h index 2ae96b4b8a..81c23010d2 100644 --- a/src/or/control.h +++ b/src/or/control.h @@ -70,6 +70,8 @@ smartlist_t *decode_hashed_passwords(config_line_t *passwords); void disable_control_logging(void); void enable_control_logging(void); +int monitor_owning_controller_process(const char *process_spec); + void control_event_bootstrap(bootstrap_status_t status, int progress); void control_event_bootstrap_problem(const char *warn, int reason); diff --git a/src/or/or.h b/src/or/or.h index d667358eb0..546c38a9a8 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2669,6 +2669,11 @@ typedef struct { int DisablePredictedCircuits; /**< Boolean: does Tor preemptively * make circuits in the background (0), * or not (1)? */ + + /** Process specifier for a controller that ‘owns’ this Tor + * instance. Tor will terminate if its owning controller does. */ + char *OwningControllerProcess; + int ShutdownWaitLength; /**< When we get a SIGINT and we're a server, how * long do we wait before exiting? */ char *SafeLogging; /**< Contains "relay", "1", "0" (meaning no scrubbing). */ From 0caa37db4df76fc50af48a107a14e4f139b7fa55 Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Sun, 15 May 2011 08:23:29 -0700 Subject: [PATCH 05/22] Fix some comments --- src/common/log.c | 2 +- src/common/torlog.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/common/log.c b/src/common/log.c index d14563c885..ac98f13539 100644 --- a/src/common/log.c +++ b/src/common/log.c @@ -390,7 +390,7 @@ logv(int severity, log_domain_mask_t domain, const char *funcname, /** Output a message to the log. It gets logged to all logfiles that * care about messages with severity in domain. The content - * is formatted printf style basedc on format and extra arguments. + * is formatted printf-style based on format and extra arguments. * */ void tor_log(int severity, log_domain_mask_t domain, const char *format, ...) diff --git a/src/common/torlog.h b/src/common/torlog.h index 000e32ddab..541a0d1738 100644 --- a/src/common/torlog.h +++ b/src/common/torlog.h @@ -146,7 +146,6 @@ void change_callback_log_severity(int loglevelMin, int loglevelMax, void flush_pending_log_callbacks(void); void log_set_application_name(const char *name); -/* Outputs a message to stdout */ void tor_log(int severity, log_domain_mask_t domain, const char *format, ...) CHECK_PRINTF(3,4); #define log tor_log /* hack it so we don't conflict with log() as much */ From b3133d1cadec0540105a855b1fd2eb741d4eec9d Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Mon, 16 May 2011 10:25:59 -0700 Subject: [PATCH 06/22] Exit immediately if we can't monitor our owning controller process tor_process_monitor_new can't currently return NULL, but if it ever can, we want that to be an explicitly fatal error, without relying on the fact that monitor_owning_controller_process's chain of caller will exit if it fails. --- src/or/config.c | 5 +---- src/or/control.c | 20 ++++++++++---------- src/or/control.h | 2 +- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/or/config.c b/src/or/config.c index b2bc9f3e9a..0d1c37f6b6 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -1232,10 +1232,7 @@ options_act(or_options_t *old_options) return -1; } - if (monitor_owning_controller_process(options->OwningControllerProcess)) { - log_warn(LD_CONFIG, "Error monitoring owning controller process"); - return -1; - } + monitor_owning_controller_process(options->OwningControllerProcess); /* reload keys as needed for rendezvous services. */ if (rend_service_load_keys()<0) { diff --git a/src/or/control.c b/src/or/control.c index 3a96904438..67e8b00d19 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -3815,8 +3815,8 @@ owning_controller_procmon_cb(void *unused) } /** Set process_spec as Tor's owning controller process. - * Return 0 on success, -1 on failure. */ -int + * Exit on failure. */ +void monitor_owning_controller_process(const char *process_spec) { const char *msg; @@ -3829,7 +3829,7 @@ monitor_owning_controller_process(const char *process_spec) owning_controller_process_spec)) { /* Same process -- return now, instead of disposing of and * recreating the process-termination monitor. */ - return 0; + return; } /* We are currently owned by a process, and we should no longer be @@ -3845,7 +3845,7 @@ monitor_owning_controller_process(const char *process_spec) (owning_controller_process_monitor == NULL)); if (process_spec == NULL) - return 0; + return; owning_controller_process_spec = tor_strdup(process_spec); owning_controller_process_monitor = @@ -3856,13 +3856,13 @@ monitor_owning_controller_process(const char *process_spec) &msg); if (owning_controller_process_monitor == NULL) { - log_warn(LD_CONTROL, "Couldn't create process-termination monitor for " - "owning controller: %s", - msg); - return -1; + log_err(LD_BUG, "Couldn't create process-termination monitor for " + "owning controller: %s. Exiting.", + msg); + owning_controller_process_spec = NULL; + tor_cleanup(); + exit(0); } - - return 0; } /** Convert the name of a bootstrapping phase s into strings diff --git a/src/or/control.h b/src/or/control.h index 81c23010d2..a83e3747e6 100644 --- a/src/or/control.h +++ b/src/or/control.h @@ -70,7 +70,7 @@ smartlist_t *decode_hashed_passwords(config_line_t *passwords); void disable_control_logging(void); void enable_control_logging(void); -int monitor_owning_controller_process(const char *process_spec); +void monitor_owning_controller_process(const char *process_spec); void control_event_bootstrap(bootstrap_status_t status, int progress); void control_event_bootstrap_problem(const char *warn, int reason); From 90f810801e92e8ee5d0b1341172f83e844af56c8 Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Wed, 18 May 2011 04:13:21 -0700 Subject: [PATCH 07/22] Fix trailing asterisk in the output of "GETINFO info/names" --- changes/exit-policy-default-is-not-a-prefix | 5 +++++ src/or/control.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 changes/exit-policy-default-is-not-a-prefix diff --git a/changes/exit-policy-default-is-not-a-prefix b/changes/exit-policy-default-is-not-a-prefix new file mode 100644 index 0000000000..6eb1e8df99 --- /dev/null +++ b/changes/exit-policy-default-is-not-a-prefix @@ -0,0 +1,5 @@ + o Minor bugfixes: + - Remove a trailing asterisk from "exit-policy/default" in the + output of the control port command "GETINFO info/names". Bugfix + on 0.1.2.5-alpha. + diff --git a/src/or/control.c b/src/or/control.c index 67e8b00d19..f7ff92ab34 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -1907,8 +1907,8 @@ static const getinfo_item_t getinfo_items[] = { "v2 networkstatus docs as retrieved from a DirPort."), ITEM("dir/status-vote/current/consensus", dir, "v3 Networkstatus consensus as retrieved from a DirPort."), - PREFIX("exit-policy/default", policies, - "The default value appended to the configured exit policy."), + ITEM("exit-policy/default", policies, + "The default value appended to the configured exit policy."), PREFIX("ip-to-country/", geoip, "Perform a GEOIP lookup"), { NULL, NULL, NULL, 0 } }; From 36afdebe1ac08fe02c938a73270bd2f11999d677 Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Wed, 18 May 2011 04:33:48 -0700 Subject: [PATCH 08/22] Add an XXX --- src/or/control.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/or/control.c b/src/or/control.c index f7ff92ab34..47e7081825 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -2894,6 +2894,9 @@ connection_control_process_inbuf(control_connection_t *conn) return 0; } + /* XXXX Why is this not implemented as a table like the GETINFO + * items are? Even handling the plus signs at the beginnings of + * commands wouldn't be very hard with proper macros. */ cmd_data_len = (uint32_t)data_len; if (!strcasecmp(conn->incoming_cmd, "SETCONF")) { if (handle_control_setconf(conn, cmd_data_len, args)) From 86aeb152cab3d0c9d5d8b301e5eb5e3afe497ea9 Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Wed, 18 May 2011 04:35:20 -0700 Subject: [PATCH 09/22] Fix comment typo --- src/or/or.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/or/or.h b/src/or/or.h index 546c38a9a8..52da63a94d 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1009,7 +1009,7 @@ typedef struct connection_t { /* XXXX023 move this field, and all the listener-only fields (just socket_family, I think), into a new listener_connection_t subtype. */ /** If the connection is a CONN_TYPE_AP_DNS_LISTENER, this field points - * to the evdns_server_port is uses to listen to and answer connections. */ + * to the evdns_server_port it uses to listen to and answer connections. */ struct evdns_server_port *dns_server_port; /** Unique ID for measuring tunneled network status requests. */ From 338a0266101e3addecbaf5771f62a860244896b3 Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Thu, 19 May 2011 16:27:51 -0700 Subject: [PATCH 10/22] Split control connection cleanup out of connection_free --- src/or/connection.c | 3 +-- src/or/control.c | 10 ++++++++++ src/or/control.h | 2 ++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/or/connection.c b/src/or/connection.c index fc2097f9a9..24ab593fef 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -479,8 +479,7 @@ connection_free(connection_t *conn) } } if (conn->type == CONN_TYPE_CONTROL) { - TO_CONTROL_CONN(conn)->event_mask = 0; - control_update_global_event_mask(); + connection_control_closed(TO_CONTROL_CONN(conn)); } connection_unregister_events(conn); _connection_free(conn); diff --git a/src/or/control.c b/src/or/control.c index 47e7081825..0ddbee99c1 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -2739,6 +2739,16 @@ connection_control_reached_eof(control_connection_t *conn) return 0; } +/** Called when conn is being freed. */ +void +connection_control_closed(control_connection_t *conn) +{ + tor_assert(conn); + + conn->event_mask = 0; + control_update_global_event_mask(); +} + /** Return true iff cmd is allowable (or at least forgivable) at this * stage of the protocol. */ static int diff --git a/src/or/control.h b/src/or/control.h index a83e3747e6..6694c96438 100644 --- a/src/or/control.h +++ b/src/or/control.h @@ -25,6 +25,8 @@ void control_adjust_event_log_severity(void); int connection_control_finished_flushing(control_connection_t *conn); int connection_control_reached_eof(control_connection_t *conn); +void connection_control_closed(control_connection_t *conn); + int connection_control_process_inbuf(control_connection_t *conn); #define EVENT_AUTHDIR_NEWDESCS 0x000D From bb860cedb29be0d95740bcf50577ae96bf666a18 Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Thu, 19 May 2011 16:34:40 -0700 Subject: [PATCH 11/22] Implement TAKEOWNERSHIP command --- src/or/control.c | 44 +++++++++++++++++++++++++++++++++++++++++++- src/or/or.h | 3 +++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/src/or/control.c b/src/or/control.c index 0ddbee99c1..b6f802d763 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -1230,6 +1230,26 @@ handle_control_signal(control_connection_t *conn, uint32_t len, return 0; } +/** Called when we get a TAKEOWNERSHIP command. Mark this connection + * as an owning connection, so that we will exit if the connection + * closes. */ +static int +handle_control_takeownership(control_connection_t *conn, uint32_t len, + const char *body) +{ + (void)len; + (void)body; + + conn->is_owning_control_connection = 1; + + log_info(LD_CONTROL, "Control connection %d has taken ownership of this " + "Tor instance.", + (int)(conn->_base.s)); + + send_control_done(conn); + return 0; +} + /** Called when we get a MAPADDRESS command; try to bind all listed addresses, * and report success or failure. */ static int @@ -2747,6 +2767,25 @@ connection_control_closed(control_connection_t *conn) conn->event_mask = 0; control_update_global_event_mask(); + + if (conn->is_owning_control_connection) { + int shutdown_slowly = server_mode(get_options()); + + log_notice(LD_CONTROL, "Owning controller connection has closed -- %s.", + shutdown_slowly ? "shutting down" : "exiting now"); + + /* XXXX This chunk of code should be a separate function, called + * here, in owning_controller_procmon_cb, and by + * process_signal(SIGINT). */ + + if (!shutdown_slowly) { + tor_cleanup(); + exit(0); + } + /* XXXX This will close all listening sockets except control-port + * listeners. Perhaps we should close those too. */ + hibernate_begin_shutdown(); + } } /** Return true iff cmd is allowable (or at least forgivable) at this @@ -2932,6 +2971,9 @@ connection_control_process_inbuf(control_connection_t *conn) } else if (!strcasecmp(conn->incoming_cmd, "SIGNAL")) { if (handle_control_signal(conn, cmd_data_len, args)) return -1; + } else if (!strcasecmp(conn->incoming_cmd, "TAKEOWNERSHIP")) { + if (handle_control_takeownership(conn, cmd_data_len, args)) + return -1; } else if (!strcasecmp(conn->incoming_cmd, "MAPADDRESS")) { if (handle_control_mapaddress(conn, cmd_data_len, args)) return -1; @@ -3816,7 +3858,7 @@ owning_controller_procmon_cb(void *unused) shutdown_slowly ? "shutting down" : "exiting now"); /* XXXX This chunk of code should be a separate function, called - * here and by process_signal(SIGINT). */ + * here, in connection_control_closed, and by process_signal(SIGINT). */ if (!shutdown_slowly) { tor_cleanup(); diff --git a/src/or/or.h b/src/or/or.h index 52da63a94d..cbfe362597 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1242,6 +1242,9 @@ typedef struct control_connection_t { /** True if we have sent a protocolinfo reply on this connection. */ unsigned int have_sent_protocolinfo:1; + /** True if we have received a takeownership command on this + * connection. */ + unsigned int is_owning_control_connection:1; /** Amount of space allocated in incoming_cmd. */ uint32_t incoming_cmd_len; From 76093af02ddd0d91225ec6ca064580f9d52fd644 Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Thu, 19 May 2011 16:45:09 -0700 Subject: [PATCH 12/22] Add changes file for #3049 --- changes/feature3049 | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 changes/feature3049 diff --git a/changes/feature3049 b/changes/feature3049 new file mode 100644 index 0000000000..7960a1f475 --- /dev/null +++ b/changes/feature3049 @@ -0,0 +1,6 @@ + o Major features: + - Add an __OwningControllerProcess configuration option and a + TAKEOWNERSHIP control-port command, so that a Tor controller can + ensure that when it exits, Tor will shut down. Implements + feature 3049. + From 7b34e3a9659a0f992dc43a568c2ea8af57e9c6d3 Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Fri, 20 May 2011 08:21:11 -0700 Subject: [PATCH 13/22] Split out owning-controller-loss shutdown code into a function --- src/or/control.c | 57 +++++++++++++++++++++--------------------------- 1 file changed, 25 insertions(+), 32 deletions(-) diff --git a/src/or/control.c b/src/or/control.c index b6f802d763..b7e90473bd 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -2759,6 +2759,29 @@ connection_control_reached_eof(control_connection_t *conn) return 0; } +/** Shut down this Tor instance in the same way that SIGINT would, but + * with a log message appropriate for the loss of an owning controller. */ +static void +lost_owning_controller(const char *owner_type, const char *loss_manner) +{ + int shutdown_slowly = server_mode(get_options()); + + log_notice(LD_CONTROL, "Owning controller %s has %s -- %s.", + owner_type, loss_manner, + shutdown_slowly ? "shutting down" : "exiting now"); + + /* XXXX Perhaps this chunk of code should be a separate function, + * called here and by process_signal(SIGINT). */ + + if (!shutdown_slowly) { + tor_cleanup(); + exit(0); + } + /* XXXX This will close all listening sockets except control-port + * listeners. Perhaps we should close those too. */ + hibernate_begin_shutdown(); +} + /** Called when conn is being freed. */ void connection_control_closed(control_connection_t *conn) @@ -2769,22 +2792,7 @@ connection_control_closed(control_connection_t *conn) control_update_global_event_mask(); if (conn->is_owning_control_connection) { - int shutdown_slowly = server_mode(get_options()); - - log_notice(LD_CONTROL, "Owning controller connection has closed -- %s.", - shutdown_slowly ? "shutting down" : "exiting now"); - - /* XXXX This chunk of code should be a separate function, called - * here, in owning_controller_procmon_cb, and by - * process_signal(SIGINT). */ - - if (!shutdown_slowly) { - tor_cleanup(); - exit(0); - } - /* XXXX This will close all listening sockets except control-port - * listeners. Perhaps we should close those too. */ - hibernate_begin_shutdown(); + lost_owning_controller("connection", "closed"); } } @@ -3849,24 +3857,9 @@ static tor_process_monitor_t *owning_controller_process_monitor = NULL; static void owning_controller_procmon_cb(void *unused) { - int shutdown_slowly = server_mode(get_options()); - (void)unused; - log_notice(LD_CONTROL, "Owning controller process has vanished -- " - "%s.", - shutdown_slowly ? "shutting down" : "exiting now"); - - /* XXXX This chunk of code should be a separate function, called - * here, in connection_control_closed, and by process_signal(SIGINT). */ - - if (!shutdown_slowly) { - tor_cleanup(); - exit(0); - } - /* XXXX This will close all listening sockets except control-port - * listeners. Perhaps we should close those too. */ - hibernate_begin_shutdown(); + lost_owning_controller("process", "vanished"); } /** Set process_spec as Tor's owning controller process. From 6b54edef4f93748e8247067242aad7158e82a148 Mon Sep 17 00:00:00 2001 From: Roger Dingledine Date: Sat, 21 May 2011 18:34:55 -0400 Subject: [PATCH 14/22] finish a comment nickm started in 8ebceeb3 --- src/or/router.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/or/router.c b/src/or/router.c index 0beb960f6d..777441affb 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -503,7 +503,8 @@ init_keys(void) if (!key_lock) key_lock = tor_mutex_new(); - /* There are a couple of paths that put us here before */ + /* There are a couple of paths that put us here before we've asked + * openssl to initialize itself. */ if (crypto_global_init(get_options()->HardwareAccel, get_options()->AccelName, get_options()->AccelDir)) { From 1ba1bdee4bd8f3c00e603fe9b0fd2f14eeb60466 Mon Sep 17 00:00:00 2001 From: Roger Dingledine Date: Sat, 21 May 2011 18:55:23 -0400 Subject: [PATCH 15/22] naked constants are ugly --- src/or/router.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/or/router.c b/src/or/router.c index 777441affb..184715b750 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -490,8 +490,8 @@ init_keys(void) char fingerprint_line[MAX_NICKNAME_LEN+FINGERPRINT_LEN+3]; const char *mydesc; crypto_pk_env_t *prkey; - char digest[20]; - char v3_digest[20]; + char digest[DIGEST_LEN]; + char v3_digest[DIGEST_LEN]; char *cp; or_options_t *options = get_options(); authority_type_t type; From 93b699e1ea5f4107f545cca97de627a3746e1daf Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 23 May 2011 01:10:49 -0400 Subject: [PATCH 16/22] Appease make check-spaces wrt procmon.h --- src/common/procmon.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/common/procmon.h b/src/common/procmon.h index f8c7444d5e..02eb2da61c 100644 --- a/src/common/procmon.h +++ b/src/common/procmon.h @@ -27,3 +27,4 @@ tor_process_monitor_t *tor_process_monitor_new(struct event_base *base, void tor_process_monitor_free(tor_process_monitor_t *procmon); #endif + From 1e69c60dccc358a7146c2b5e7825ea729498b41b Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 23 May 2011 01:12:00 -0400 Subject: [PATCH 17/22] The first argument for a libevent callback should be evutil_socket_t --- src/common/procmon.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/common/procmon.c b/src/common/procmon.c index cee956a52f..bd25bc10e3 100644 --- a/src/common/procmon.c +++ b/src/common/procmon.c @@ -34,7 +34,7 @@ typedef int pid_t; /* Currently we need to poll in some way on all systems. */ #ifdef PROCMON_POLLS -static void tor_process_monitor_poll_cb(int unused1, short unused2, +static void tor_process_monitor_poll_cb(evutil_socket_t unused1, short unused2, void *procmon_); #endif @@ -232,7 +232,8 @@ tor_process_monitor_new(struct event_base *base, /** Libevent callback to poll for the existence of the process * monitored by procmon_. */ static void -tor_process_monitor_poll_cb(int unused1, short unused2, void *procmon_) +tor_process_monitor_poll_cb(evutil_socket_t unused1, short unused2, + void *procmon_) { tor_process_monitor_t *procmon = (tor_process_monitor_t *)(procmon_); int its_dead_jim; From 6cac100b13794b74db8e831bed56df2f0443ea13 Mon Sep 17 00:00:00 2001 From: Robert Ransom Date: Sun, 22 May 2011 22:54:02 -0700 Subject: [PATCH 18/22] Unbreak the build on libevent 1.x systems --- src/common/procmon.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/common/procmon.c b/src/common/procmon.c index bd25bc10e3..8fcc1afb7c 100644 --- a/src/common/procmon.c +++ b/src/common/procmon.c @@ -152,7 +152,11 @@ tor_validate_process_specifier(const char *process_spec, #define PERIODIC_TIMER_FLAGS (0) #endif -static const struct timeval poll_interval_tv = {15, 0}; +static struct timeval poll_interval_tv = {15, 0}; +/* Note: If you port this file to plain Libevent 2, you can make + * poll_interval_tv const. It has to be non-const here because in + * libevent 1.x, event_add expects a pointer to a non-const struct + * timeval. */ /** Create a process-termination monitor for the process specifier * given in process_spec. Return a newly allocated From 57810c333a38c72c1e361c02e31de7712d1f221a Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 23 May 2011 16:59:41 -0400 Subject: [PATCH 19/22] Remove the -F option from tor-resolve. It used to mean "Force": it would tell tor-resolve to ask tor to resolve an address even if it ended with .onion. But when AutomapHostsOnResolve was added, automatically refusing to resolve .onion hosts stopped making sense. So in 0.2.1.16-rc (commit 298dc95dfd8), we made tor-resolve happy to resolve anything. The -F option stayed in, though, even though it didn't do anything. Oddly, it never got documented. Found while fixing GCC 4.6 "set, unused variable" warnings. --- changes/bug3208 | 4 ++++ src/tools/tor-resolve.c | 4 +--- 2 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 changes/bug3208 diff --git a/changes/bug3208 b/changes/bug3208 new file mode 100644 index 0000000000..731c96e20a --- /dev/null +++ b/changes/bug3208 @@ -0,0 +1,4 @@ + o Removed options: + - Remove undocumented option "-F" from tor-resolve: it hasn't done + anything since 0.2.1.16-rc. + diff --git a/src/tools/tor-resolve.c b/src/tools/tor-resolve.c index 12349d9d12..8c4d3f6483 100644 --- a/src/tools/tor-resolve.c +++ b/src/tools/tor-resolve.c @@ -319,7 +319,7 @@ main(int argc, char **argv) { uint32_t sockshost; uint16_t socksport = 0, port_option = 0; - int isSocks4 = 0, isVerbose = 0, isReverse = 0, force = 0; + int isSocks4 = 0, isVerbose = 0, isReverse = 0; char **arg; int n_args; struct in_addr a; @@ -349,8 +349,6 @@ main(int argc, char **argv) isSocks4 = 0; else if (!strcmp("-x", arg[0])) isReverse = 1; - else if (!strcmp("-F", arg[0])) - force = 1; else if (!strcmp("-p", arg[0])) { int p; if (n_args < 2) { From a5232e0c4c572cdff85701f698b8b90c9443d7e4 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 23 May 2011 17:04:38 -0400 Subject: [PATCH 20/22] Fix GCC 4.6's new -Wunused-but-set-variable warnings. Most instances were dead code; for those, I removed the assignments. Some were pieces of info we don't currently plan to use, but which we might in the future. For those, I added an explicit cast-to-void to indicate that we know that the thing's unused. Finally, one was a case where we were testing the wrong variable in a unit test. That one I fixed. This resolves bug 3208. --- changes/bug3208 | 2 ++ src/or/circuitbuild.c | 3 --- src/or/command.c | 1 + src/or/control.c | 2 -- src/or/directory.c | 2 -- src/or/dirvote.c | 3 +-- src/or/eventdns.c | 3 +++ src/test/test_crypto.c | 4 +++- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/changes/bug3208 b/changes/bug3208 index 731c96e20a..fd737ba695 100644 --- a/changes/bug3208 +++ b/changes/bug3208 @@ -2,3 +2,5 @@ - Remove undocumented option "-F" from tor-resolve: it hasn't done anything since 0.2.1.16-rc. + o Minor bugfixes: + - Fix warnings from GCC 4.6's "-Wunused-but-set-variable" option. diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 08bfb98815..108007e384 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -3766,7 +3766,6 @@ void entry_guards_compute_status(or_options_t *options, time_t now) { int changed = 0; - int severity = LOG_DEBUG; digestmap_t *reasons; if (! entry_guards) @@ -3793,8 +3792,6 @@ entry_guards_compute_status(or_options_t *options, time_t now) if (remove_dead_entry_guards(now)) changed = 1; - severity = changed ? LOG_DEBUG : LOG_INFO; - if (changed) { SMARTLIST_FOREACH_BEGIN(entry_guards, entry_guard_t *, entry) { const char *reason = digestmap_get(reasons, entry->identity); diff --git a/src/or/command.c b/src/or/command.c index 00d9af33fa..e377f4fb67 100644 --- a/src/or/command.c +++ b/src/or/command.c @@ -645,6 +645,7 @@ command_process_netinfo_cell(cell_t *cell, or_connection_t *conn) /* XXX maybe act on my_apparent_addr, if the source is sufficiently * trustworthy. */ + (void)my_apparent_addr; if (connection_or_set_state_open(conn)<0) connection_mark_for_close(TO_CONN(conn)); diff --git a/src/or/control.c b/src/or/control.c index 0dad1b9dfa..f75ac67758 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -3142,7 +3142,6 @@ control_event_circuit_status(origin_circuit_t *circ, circuit_status_event_t tp, { const char *status; char extended_buf[96]; - int providing_reason=0; if (!EVENT_IS_INTERESTING(EVENT_CIRCUIT_STATUS)) return 0; tor_assert(circ); @@ -3166,7 +3165,6 @@ control_event_circuit_status(origin_circuit_t *circ, circuit_status_event_t tp, const char *reason_str = circuit_end_reason_to_control_string(reason_code); char *reason = NULL; size_t n=strlen(extended_buf); - providing_reason=1; if (!reason_str) { reason = tor_malloc(16); tor_snprintf(reason, 16, "UNKNOWN_%d", reason_code); diff --git a/src/or/directory.c b/src/or/directory.c index eb99e9d081..ff0a5a427b 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -1900,7 +1900,6 @@ connection_dir_client_reached_eof(dir_connection_t *conn) router_get_trusteddirserver_by_digest(conn->identity_digest); char *rejected_hdr = http_get_header(headers, "X-Descriptor-Not-New: "); - int rejected = 0; if (rejected_hdr) { if (!strcmp(rejected_hdr, "Yes")) { log_info(LD_GENERAL, @@ -1913,7 +1912,6 @@ connection_dir_client_reached_eof(dir_connection_t *conn) * last descriptor, not on the published time of the last * descriptor. If those are different, that's a bad thing to * do. -NM */ - rejected = 1; } tor_free(rejected_hdr); } diff --git a/src/or/dirvote.c b/src/or/dirvote.c index 96e3df5cec..c6ce9f6776 100644 --- a/src/or/dirvote.c +++ b/src/or/dirvote.c @@ -1592,7 +1592,7 @@ networkstatus_compute_consensus(smartlist_t *votes, * is the same flag as votes[j]->known_flags[b]. */ int *named_flag; /* Index of the flag "Named" for votes[j] */ int *unnamed_flag; /* Index of the flag "Unnamed" for votes[j] */ - int chosen_named_idx, chosen_unnamed_idx; + int chosen_named_idx; strmap_t *name_to_id_map = strmap_new(); char conflict[DIGEST_LEN]; @@ -1610,7 +1610,6 @@ networkstatus_compute_consensus(smartlist_t *votes, for (i = 0; i < smartlist_len(votes); ++i) unnamed_flag[i] = named_flag[i] = -1; chosen_named_idx = smartlist_string_pos(flags, "Named"); - chosen_unnamed_idx = smartlist_string_pos(flags, "Unnamed"); /* Build the flag index. */ SMARTLIST_FOREACH(votes, networkstatus_t *, v, diff --git a/src/or/eventdns.c b/src/or/eventdns.c index fc005df2d7..b7cc2929ae 100644 --- a/src/or/eventdns.c +++ b/src/or/eventdns.c @@ -1028,6 +1028,9 @@ request_parse(u8 *packet, ssize_t length, struct evdns_server_port *port, struct GET16(answers); GET16(authority); GET16(additional); + (void)additional; + (void)authority; + (void)answers; if (flags & 0x8000) return -1; /* Must not be an answer. */ flags &= 0x0110; /* Only RD and CD get preserved. */ diff --git a/src/test/test_crypto.c b/src/test/test_crypto.c index 781081a4ad..bf2cc48174 100644 --- a/src/test/test_crypto.c +++ b/src/test/test_crypto.c @@ -69,7 +69,7 @@ test_crypto_rng(void) uint64_t big; char *host; j = crypto_rand_int(100); - if (i < 0 || i >= 100) + if (j < 0 || j >= 100) allok = 0; big = crypto_rand_uint64(U64_LITERAL(1)<<40); if (big >= (U64_LITERAL(1)<<40)) @@ -240,11 +240,13 @@ test_crypto_sha(void) /* Test SHA-1 with a test vector from the specification. */ i = crypto_digest(data, "abc", 3); test_memeq_hex(data, "A9993E364706816ABA3E25717850C26C9CD0D89D"); + tt_int_op(i, ==, 0); /* Test SHA-256 with a test vector from the specification. */ i = crypto_digest256(data, "abc", 3, DIGEST_SHA256); test_memeq_hex(data, "BA7816BF8F01CFEA414140DE5DAE2223B00361A3" "96177A9CB410FF61F20015AD"); + tt_int_op(i, ==, 0); /* Test HMAC-SHA-1 with test cases from RFC2202. */ From be76850995f337337dd94be66a9f03b35d8b1412 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 23 May 2011 17:42:38 -0400 Subject: [PATCH 21/22] Work correctly if your nameserver is ::1 We had all the code in place to handle this right... except that we were unconditionally opening a PF_INET socket instead of looking at sa_family. Ow. Fixes bug 2574; not a bugfix on any particular version, since this never worked before. --- changes/bug2574 | 2 ++ src/or/eventdns.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 changes/bug2574 diff --git a/changes/bug2574 b/changes/bug2574 new file mode 100644 index 0000000000..32f4ae4a92 --- /dev/null +++ b/changes/bug2574 @@ -0,0 +1,2 @@ + o Minor features: + - Allow nameserves with IPv6 address. Fixes bug 2574. diff --git a/src/or/eventdns.c b/src/or/eventdns.c index 2777f90989..adab22bba6 100644 --- a/src/or/eventdns.c +++ b/src/or/eventdns.c @@ -2320,7 +2320,7 @@ _evdns_nameserver_add_impl(const struct sockaddr *address, memset(ns, 0, sizeof(struct nameserver)); ns->timeout_event_deleted = __LINE__; - ns->socket = socket(PF_INET, SOCK_DGRAM, 0); + ns->socket = socket(address->sa_family, SOCK_DGRAM, 0); if (ns->socket < 0) { err = 1; goto out1; } #ifdef WIN32 { From f43aceb0f1b10d71d2e99e323668ac35327e286b Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Sat, 28 May 2011 02:13:04 -0400 Subject: [PATCH 22/22] Fix typo in changes/bug2574. Thanks, rransom --- changes/bug2574 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/changes/bug2574 b/changes/bug2574 index 32f4ae4a92..5cf2daebfa 100644 --- a/changes/bug2574 +++ b/changes/bug2574 @@ -1,2 +1,3 @@ o Minor features: - - Allow nameserves with IPv6 address. Fixes bug 2574. + - Allow nameservers with IPv6 address. Fixes bug 2574. +