summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/compat.h5
-rw-r--r--src/common/crypto.c11
-rw-r--r--src/common/log.c7
-rw-r--r--src/common/util.h6
-rw-r--r--src/or/command.c16
-rw-r--r--src/or/config.c3
-rw-r--r--src/or/connection.c23
-rw-r--r--src/or/connection.h3
-rw-r--r--src/or/control.c23
-rw-r--r--src/or/dns.c4
-rw-r--r--src/or/main.c2
-rw-r--r--src/or/routerlist.c11
-rw-r--r--src/test/test_pt.c6
13 files changed, 87 insertions, 33 deletions
diff --git a/src/common/compat.h b/src/common/compat.h
index b0ef63badf..7edd889ee3 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -259,11 +259,12 @@ void tor_munmap_file(tor_mmap_t *handle) ATTR_NONNULL((1));
int tor_snprintf(char *str, size_t size, const char *format, ...)
CHECK_PRINTF(3,4) ATTR_NONNULL((1,3));
int tor_vsnprintf(char *str, size_t size, const char *format, va_list args)
- ATTR_NONNULL((1,3));
+ CHECK_PRINTF(3,0) ATTR_NONNULL((1,3));
int tor_asprintf(char **strp, const char *fmt, ...)
CHECK_PRINTF(2,3);
-int tor_vasprintf(char **strp, const char *fmt, va_list args);
+int tor_vasprintf(char **strp, const char *fmt, va_list args)
+ CHECK_PRINTF(2,0);
const void *tor_memmem(const void *haystack, size_t hlen, const void *needle,
size_t nlen) ATTR_NONNULL((1,3));
diff --git a/src/common/crypto.c b/src/common/crypto.c
index f82598fab2..8feac95acf 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -1806,7 +1806,6 @@ crypto_get_stored_dynamic_dh_modulus(const char *fname)
char *contents = NULL;
const char *contents_tmp = NULL;
int dh_codes;
- char *fname_new = NULL;
DH *stored_dh = NULL;
BIGNUM *dynamic_dh_modulus = NULL;
int length = 0;
@@ -1881,12 +1880,10 @@ crypto_get_stored_dynamic_dh_modulus(const char *fname)
err:
- { /* move broken prime to $filename.broken */
- fname_new = tor_malloc(strlen(fname) + 8);
-
- /* no can do if these functions return error */
- strlcpy(fname_new, fname, strlen(fname) + 8);
- strlcat(fname_new, ".broken", strlen(fname) + 8);
+ {
+ /* move broken prime to $filename.broken */
+ char *fname_new=NULL;
+ tor_asprintf(&fname_new, "%s.broken", fname);
log_warn(LD_CRYPTO, "Moving broken dynamic DH prime to '%s'.", fname_new);
diff --git a/src/common/log.c b/src/common/log.c
index df27066f92..f509ddcd6e 100644
--- a/src/common/log.c
+++ b/src/common/log.c
@@ -137,6 +137,13 @@ static void close_log(logfile_t *victim);
static char *domain_to_string(log_domain_mask_t domain,
char *buf, size_t buflen);
+static INLINE char *format_msg(char *buf, size_t buf_len,
+ log_domain_mask_t domain, int severity, const char *funcname,
+ const char *format, va_list ap, size_t *msg_len_out)
+ CHECK_PRINTF(6,0);
+static void logv(int severity, log_domain_mask_t domain, const char *funcname,
+ const char *format, va_list ap)
+ CHECK_PRINTF(4,0);
/** Name of the application: used to generate the message we write at the
* start of each new log. */
diff --git a/src/common/util.h b/src/common/util.h
index 567efaafef..36601fa790 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -213,7 +213,11 @@ const char *escaped(const char *string);
struct smartlist_t;
void wrap_string(struct smartlist_t *out, const char *string, size_t width,
const char *prefix0, const char *prefixRest);
-int tor_vsscanf(const char *buf, const char *pattern, va_list ap);
+int tor_vsscanf(const char *buf, const char *pattern, va_list ap)
+#ifdef __GNUC__
+ __attribute__((format(scanf, 2, 0)))
+#endif
+ ;
int tor_sscanf(const char *buf, const char *pattern, ...)
#ifdef __GNUC__
__attribute__((format(scanf, 2, 3)))
diff --git a/src/or/command.c b/src/or/command.c
index ca3c341037..4e56edd5db 100644
--- a/src/or/command.c
+++ b/src/or/command.c
@@ -160,9 +160,11 @@ command_process_cell(cell_t *cell, or_connection_t *conn)
if (handshaking && cell->command != CELL_VERSIONS &&
cell->command != CELL_NETINFO) {
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
- "Received unexpected cell command %d in state %s; ignoring it.",
+ "Received unexpected cell command %d in state %s; closing the "
+ "connection.",
(int)cell->command,
conn_state_to_string(CONN_TYPE_OR,conn->_base.state));
+ connection_mark_for_close(TO_CONN(conn));
return;
}
@@ -258,8 +260,15 @@ command_process_var_cell(var_cell_t *cell, or_connection_t *conn)
switch (conn->_base.state)
{
case OR_CONN_STATE_OR_HANDSHAKING_V2:
- if (cell->command != CELL_VERSIONS)
+ if (cell->command != CELL_VERSIONS) {
+ log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
+ "Received a cell with command %d in state %s; "
+ "closing the connection.",
+ (int)cell->command,
+ conn_state_to_string(CONN_TYPE_OR,conn->_base.state));
+ connection_mark_for_close(TO_CONN(conn));
return;
+ }
break;
case OR_CONN_STATE_TLS_HANDSHAKING:
/* If we're using bufferevents, it's entirely possible for us to
@@ -272,9 +281,10 @@ command_process_var_cell(var_cell_t *cell, or_connection_t *conn)
if (! command_allowed_before_handshake(cell->command)) {
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
"Received a cell with command %d in state %s; "
- "ignoring it.",
+ "closing the connection.",
(int)cell->command,
conn_state_to_string(CONN_TYPE_OR,conn->_base.state));
+ connection_mark_for_close(TO_CONN(conn));
return;
} else {
if (enter_v3_handshake_with_cell(cell, conn)<0)
diff --git a/src/or/config.c b/src/or/config.c
index 27aa8a2f23..8a19ed6d44 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -1138,7 +1138,8 @@ options_act_reversible(const or_options_t *old_options, char **msg)
* networking is disabled, this will close all but the control listeners,
* but disable those. */
if (!we_are_hibernating()) {
- if (retry_all_listeners(replaced_listeners, new_listeners) < 0) {
+ if (retry_all_listeners(replaced_listeners, new_listeners,
+ options->DisableNetwork) < 0) {
*msg = tor_strdup("Failed to bind one of the listener ports.");
goto rollback;
}
diff --git a/src/or/connection.c b/src/or/connection.c
index 0c970cc3b4..eb8b840eb7 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -1812,17 +1812,28 @@ connection_read_proxy_handshake(connection_t *conn)
* entry in <b>ports</b>. Add to <b>new_conns</b> new every connection we
* launch.
*
+ * If <b>control_listeners_only</b> is true, then we only open control
+ * listeners, and we do not remove any noncontrol listeners from old_conns.
+ *
* Return 0 on success, -1 on failure.
**/
static int
retry_listener_ports(smartlist_t *old_conns,
const smartlist_t *ports,
- smartlist_t *new_conns)
+ smartlist_t *new_conns,
+ int control_listeners_only)
{
smartlist_t *launch = smartlist_new();
int r = 0;
- smartlist_add_all(launch, ports);
+ if (control_listeners_only) {
+ SMARTLIST_FOREACH(ports, port_cfg_t *, p, {
+ if (p->type == CONN_TYPE_CONTROL_LISTENER)
+ smartlist_add(launch, p);
+ });
+ } else {
+ smartlist_add_all(launch, ports);
+ }
/* Iterate through old_conns, comparing it to launch: remove from both lists
* each pair of elements that corresponds to the same port. */
@@ -1922,10 +1933,13 @@ retry_listener_ports(smartlist_t *old_conns,
*
* Add all old conns that should be closed to <b>replaced_conns</b>.
* Add all new connections to <b>new_conns</b>.
+ *
+ * If <b>close_all_noncontrol</b> is true, then we only open control
+ * listeners, and we close all other listeners.
*/
int
retry_all_listeners(smartlist_t *replaced_conns,
- smartlist_t *new_conns)
+ smartlist_t *new_conns, int close_all_noncontrol)
{
smartlist_t *listeners = smartlist_new();
const or_options_t *options = get_options();
@@ -1940,7 +1954,8 @@ retry_all_listeners(smartlist_t *replaced_conns,
if (retry_listener_ports(listeners,
get_configured_ports(),
- new_conns) < 0)
+ new_conns,
+ close_all_noncontrol) < 0)
retval = -1;
/* Any members that were still in 'listeners' don't correspond to
diff --git a/src/or/connection.h b/src/or/connection.h
index c4b8bf8abe..bdeefa2549 100644
--- a/src/or/connection.h
+++ b/src/or/connection.h
@@ -64,7 +64,8 @@ int get_proxy_addrport(tor_addr_t *addr, uint16_t *port, int *proxy_type,
const connection_t *conn);
int retry_all_listeners(smartlist_t *replaced_conns,
- smartlist_t *new_conns);
+ smartlist_t *new_conns,
+ int close_all_noncontrol);
void connection_mark_all_noncontrol_listeners(void);
void connection_mark_all_noncontrol_connections(void);
diff --git a/src/or/control.c b/src/or/control.c
index ec018ffc23..91d94fd665 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -30,6 +30,7 @@
#include "nodelist.h"
#include "policies.h"
#include "reasons.h"
+#include "rephist.h"
#include "router.h"
#include "routerlist.h"
#include "routerparse.h"
@@ -135,6 +136,13 @@ typedef int event_format_t;
static void connection_printf_to_buf(control_connection_t *conn,
const char *format, ...)
CHECK_PRINTF(2,3);
+static void send_control_event_impl(uint16_t event, event_format_t which,
+ const char *format, va_list ap)
+ CHECK_PRINTF(3,0);
+static int control_event_status(int type, int severity, const char *format,
+ va_list args)
+ CHECK_PRINTF(3,0);
+
static void send_control_done(control_connection_t *conn);
static void send_control_event(uint16_t event, event_format_t which,
const char *format, ...)
@@ -1397,6 +1405,9 @@ getinfo_helper_misc(control_connection_t *conn, const char *question,
*answer = options_dump(get_options(), 1);
} else if (!strcmp(question, "info/names")) {
*answer = list_getinfo_options();
+ } else if (!strcmp(question, "dormant")) {
+ int dormant = rep_hist_circbuilding_dormant(time(NULL));
+ *answer = tor_strdup(dormant ? "1" : "0");
} else if (!strcmp(question, "events/names")) {
int i;
smartlist_t *event_names = smartlist_new();
@@ -2138,12 +2149,13 @@ static const getinfo_item_t getinfo_items[] = {
"Brief summary of router status by nickname (v2 directory format)."),
PREFIX("ns/purpose/", networkstatus,
"Brief summary of router status by purpose (v2 directory format)."),
-
ITEM("network-status", dir,
"Brief summary of router status (v1 directory format)"),
ITEM("circuit-status", events, "List of current circuits originating here."),
ITEM("stream-status", events,"List of current streams."),
ITEM("orconn-status", events, "A list of current OR connections."),
+ ITEM("dormant", misc,
+ "Is Tor dormant (not building circuits because it's idle)?"),
PREFIX("address-mappings/", events, NULL),
DOC("address-mappings/all", "Current address mappings."),
DOC("address-mappings/cache", "Current cached DNS replies."),
@@ -4203,6 +4215,7 @@ control_event_my_descriptor_changed(void)
static int
control_event_status(int type, int severity, const char *format, va_list args)
{
+ char *user_buf = NULL;
char format_buf[160];
const char *status, *sev;
@@ -4234,13 +4247,15 @@ control_event_status(int type, int severity, const char *format, va_list args)
log_warn(LD_BUG, "Unrecognized status severity %d", severity);
return -1;
}
- if (tor_snprintf(format_buf, sizeof(format_buf), "650 %s %s %s\r\n",
- status, sev, format)<0) {
+ if (tor_snprintf(format_buf, sizeof(format_buf), "650 %s %s\r\n",
+ status, sev)<0) {
log_warn(LD_BUG, "Format string too long.");
return -1;
}
+ tor_vasprintf(&user_buf, format, args);
- send_control_event_impl(type, ALL_FORMATS, format_buf, args);
+ send_control_event(type, ALL_FORMATS, "%s %s", format_buf, user_buf);
+ tor_free(user_buf);
return 0;
}
diff --git a/src/or/dns.c b/src/or/dns.c
index 2b7d3e3506..b349f02f68 100644
--- a/src/or/dns.c
+++ b/src/or/dns.c
@@ -1389,7 +1389,7 @@ evdns_callback(int result, char type, int count, int ttl, void *addresses,
static int
launch_resolve(edge_connection_t *exitconn)
{
- char *addr = tor_strdup(exitconn->_base.address);
+ char *addr;
struct evdns_request *req = NULL;
tor_addr_t a;
int r;
@@ -1408,6 +1408,8 @@ launch_resolve(edge_connection_t *exitconn)
}
}
+ addr = tor_strdup(exitconn->_base.address);
+
r = tor_addr_parse_PTR_name(
&a, exitconn->_base.address, AF_UNSPEC, 0);
diff --git a/src/or/main.c b/src/or/main.c
index 8308b3a238..ab537728f2 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -1428,7 +1428,7 @@ run_scheduled_events(time_t now)
/** 3d. And every 60 seconds, we relaunch listeners if any died. */
if (!net_is_disabled() && time_to_check_listeners < now) {
- retry_all_listeners(NULL, NULL);
+ retry_all_listeners(NULL, NULL, 0);
time_to_check_listeners = now+60;
}
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 0abc2e9bcf..36a282a30f 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -5004,7 +5004,14 @@ update_router_have_minimum_dir_info(void)
count_usable_descriptors(&num_exit_present, &num_exit_usable,
consensus, options, now, options->ExitNodes, 1);
- if (num_present < num_usable/4) {
+/* What fraction of desired server descriptors do we need before we will
+ * build circuits? */
+#define FRACTION_USABLE_NEEDED .75
+/* What fraction of desired _exit_ server descriptors do we need before we
+ * will build circuits? */
+#define FRACTION_EXIT_USABLE_NEEDED .5
+
+ if (num_present < num_usable * FRACTION_USABLE_NEEDED) {
tor_snprintf(dir_info_status, sizeof(dir_info_status),
"We have only %d/%d usable %sdescriptors.",
num_present, num_usable, using_md ? "micro" : "");
@@ -5017,7 +5024,7 @@ update_router_have_minimum_dir_info(void)
num_present, using_md ? "micro" : "", num_present ? "" : "s");
res = 0;
goto done;
- } else if (num_exit_present < num_exit_usable / 3) {
+ } else if (num_exit_present < num_exit_usable * FRACTION_EXIT_USABLE_NEEDED) {
tor_snprintf(dir_info_status, sizeof(dir_info_status),
"We have only %d/%d usable exit node descriptors.",
num_exit_present, num_exit_usable);
diff --git a/src/test/test_pt.c b/src/test/test_pt.c
index 201f78ea50..fde64ab28e 100644
--- a/src/test/test_pt.c
+++ b/src/test/test_pt.c
@@ -99,12 +99,6 @@ test_pt_protocol(void)
/* various wrong protocol runs: */
- strcpy(line, "TEST TEST");
- handle_proxy_line(line, mp);
- test_assert(mp->conf_state == PT_PROTO_BROKEN);
-
- reset_mp(mp);
-
strcpy(line,"VERSION 1");
handle_proxy_line(line, mp);
test_assert(mp->conf_state == PT_PROTO_ACCEPTING_METHODS);