aboutsummaryrefslogtreecommitdiff
path: root/src/or
diff options
context:
space:
mode:
Diffstat (limited to 'src/or')
-rw-r--r--src/or/buffers.c2
-rw-r--r--src/or/circuituse.c28
-rw-r--r--src/or/config.c158
-rw-r--r--src/or/config.h23
-rw-r--r--src/or/connection.c14
-rw-r--r--src/or/connection_edge.c27
-rw-r--r--src/or/connection_or.c4
-rw-r--r--src/or/directory.c33
-rw-r--r--src/or/directory.h28
-rw-r--r--src/or/dirserv.c21
-rw-r--r--src/or/dirvote.c3
-rw-r--r--src/or/dirvote.h1
-rw-r--r--src/or/entrynodes.c2
-rw-r--r--src/or/ext_orport.c2
-rw-r--r--src/or/fallback_dirs.inc207
-rw-r--r--src/or/geoip.c2
-rw-r--r--src/or/hibernate.c20
-rw-r--r--src/or/hibernate.h1
-rw-r--r--src/or/include.am7
-rw-r--r--src/or/main.c21
-rw-r--r--src/or/networkstatus.c32
-rw-r--r--src/or/networkstatus.h4
-rw-r--r--src/or/nodelist.c17
-rw-r--r--src/or/or.h64
-rw-r--r--src/or/relay.c2
-rw-r--r--src/or/rendclient.c15
-rw-r--r--src/or/rendmid.c9
-rw-r--r--src/or/rendservice.c4
-rw-r--r--src/or/router.c140
-rw-r--r--src/or/router.h1
-rw-r--r--src/or/routerlist.c29
-rw-r--r--src/or/routerlist.h3
-rw-r--r--src/or/routerparse.c15
-rw-r--r--src/or/status.c22
-rw-r--r--src/or/transports.c2
35 files changed, 742 insertions, 221 deletions
diff --git a/src/or/buffers.c b/src/or/buffers.c
index 4696bec8f4..cdb499b8da 100644
--- a/src/or/buffers.c
+++ b/src/or/buffers.c
@@ -1945,7 +1945,7 @@ parse_socks(const char *data, size_t datalen, socks_request_t *req,
log_warn(LD_PROTOCOL,
"Your application (using socks4 to port %d) gave Tor "
"a malformed hostname: %s. Rejecting the connection.",
- req->port, escaped(req->address));
+ req->port, escaped_safe_str_client(req->address));
return -1;
}
if (authend != authstart) {
diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index 4831f2be76..5ffd1f68c7 100644
--- a/src/or/circuituse.c
+++ b/src/or/circuituse.c
@@ -92,7 +92,7 @@ circuit_is_acceptable(const origin_circuit_t *origin_circ,
/* decide if this circ is suitable for this conn */
/* for rend circs, circ->cpath->prev is not the last router in the
- * circuit, it's the magical extra bob hop. so just check the nickname
+ * circuit, it's the magical extra service hop. so just check the nickname
* of the one we meant to finish at.
*/
build_state = origin_circ->build_state;
@@ -1493,11 +1493,11 @@ circuit_has_opened(origin_circuit_t *circ)
circuit_try_attaching_streams(circ);
break;
case CIRCUIT_PURPOSE_S_ESTABLISH_INTRO:
- /* at Bob, waiting for introductions */
+ /* at the service, waiting for introductions */
rend_service_intro_has_opened(circ);
break;
case CIRCUIT_PURPOSE_S_CONNECT_REND:
- /* at Bob, connecting to rend point */
+ /* at the service, connecting to rend point */
rend_service_rendezvous_has_opened(circ);
break;
case CIRCUIT_PURPOSE_TESTING:
@@ -1617,32 +1617,32 @@ circuit_build_failed(origin_circuit_t *circ)
circuit_testing_failed(circ, failed_at_last_hop);
break;
case CIRCUIT_PURPOSE_S_ESTABLISH_INTRO:
- /* at Bob, waiting for introductions */
+ /* at the service, waiting for introductions */
if (circ->base_.state != CIRCUIT_STATE_OPEN) {
circuit_increment_failure_count();
}
- /* no need to care here, because bob will rebuild intro
+ /* no need to care here, because the service will rebuild intro
* points periodically. */
break;
case CIRCUIT_PURPOSE_C_INTRODUCING:
- /* at Alice, connecting to intro point */
- /* Don't increment failure count, since Bob may have picked
+ /* at the client, connecting to intro point */
+ /* Don't increment failure count, since the service may have picked
* the introduction point maliciously */
- /* Alice will pick a new intro point when this one dies, if
+ /* The client will pick a new intro point when this one dies, if
* the stream in question still cares. No need to act here. */
break;
case CIRCUIT_PURPOSE_C_ESTABLISH_REND:
- /* at Alice, waiting for Bob */
+ /* at the client, waiting for the service */
circuit_increment_failure_count();
- /* Alice will pick a new rend point when this one dies, if
+ /* the client will pick a new rend point when this one dies, if
* the stream in question still cares. No need to act here. */
break;
case CIRCUIT_PURPOSE_S_CONNECT_REND:
- /* at Bob, connecting to rend point */
- /* Don't increment failure count, since Alice may have picked
+ /* at the service, connecting to rend point */
+ /* Don't increment failure count, since the client may have picked
* the rendezvous point maliciously */
log_info(LD_REND,
- "Couldn't connect to Alice's chosen rend point %s "
+ "Couldn't connect to the client's chosen rend point %s "
"(%s hop failed).",
escaped(build_state_get_exit_nickname(circ->build_state)),
failed_at_last_hop?"last":"non-last");
@@ -2246,7 +2246,7 @@ consider_recording_trackhost(const entry_connection_t *conn,
char fp[HEX_DIGEST_LEN+1];
/* Search the addressmap for this conn's destination. */
- /* If he's not in the address map.. */
+ /* If they're not in the address map.. */
if (!options->TrackHostExits ||
addressmap_have_mapping(conn->socks_request->address,
options->TrackHostExitsExpire))
diff --git a/src/or/config.c b/src/or/config.c
index b9d9fb2d9a..d71cf6dec7 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -224,6 +224,7 @@ static config_var_t option_vars_[] = {
V(DirPortFrontPage, FILENAME, NULL),
VAR("DirReqStatistics", BOOL, DirReqStatistics_option, "1"),
VAR("DirAuthority", LINELIST, DirAuthorities, NULL),
+ V(DirCache, BOOL, "1"),
V(DirAuthorityFallbackRate, DOUBLE, "1.0"),
V(DisableAllSwap, BOOL, "0"),
V(DisableDebuggerAttachment, BOOL, "1"),
@@ -591,7 +592,6 @@ static const config_var_t testing_tor_network_defaults[] = {
static char *get_windows_conf_root(void);
#endif
static int options_act_reversible(const or_options_t *old_options, char **msg);
-static int options_act(const or_options_t *old_options);
static int options_transition_allowed(const or_options_t *old,
const or_options_t *new,
char **msg);
@@ -672,9 +672,9 @@ get_dirportfrontpage, (void))
return global_dirfrontpagecontents;
}
-/** Return the currently configured options. */
-or_options_t *
-get_options_mutable(void)
+/** Returns the currently configured options. */
+MOCK_IMPL(or_options_t *,
+get_options_mutable, (void))
{
tor_assert(global_options);
return global_options;
@@ -834,7 +834,6 @@ config_free_all(void)
tor_free(torrc_fname);
tor_free(torrc_defaults_fname);
- tor_free(the_tor_version);
tor_free(global_dirfrontpagecontents);
tor_free(the_short_tor_version);
@@ -918,7 +917,7 @@ static const char *default_authorities[] = {
"ipv6=[2001:638:a000:4140::ffff:189]:443 "
"131.188.40.189:80 F204 4413 DAC2 E02E 3D6B CF47 35A1 9BCA 1DE9 7281",
"dannenberg orport=443 "
- "v3ident=585769C78764D58426B8B52B6651A5A71137189A "
+ "v3ident=0232AF901C31A04EE9848595AF9BB7620D4C5B2E "
"193.23.244.244:80 7BE6 83E6 5D48 1413 21C5 ED92 F075 C553 64AC 7123",
"urras orport=80 "
"v3ident=80550987E1D626E3EBA5E5E75A458DE0626D088C "
@@ -939,6 +938,14 @@ static const char *default_authorities[] = {
NULL
};
+/** List of fallback directory authorities. The list is generated by opt-in of
+ * relays that meet certain stability criteria.
+ */
+static const char *default_fallbacks[] = {
+#include "fallback_dirs.inc"
+ NULL
+};
+
/** Add the default directory authorities directly into the trusted dir list,
* but only add them insofar as they share bits with <b>type</b>.
* Each authority's bits are restricted to the bits shared with <b>type</b>.
@@ -961,14 +968,10 @@ MOCK_IMPL(void,
add_default_fallback_dir_servers,(void))
{
int i;
- const char *fallback[] = {
-#include "fallback_dirs.inc"
- NULL
- };
- for (i=0; fallback[i]; i++) {
- if (parse_dir_fallback_line(fallback[i], 0)<0) {
+ for (i=0; default_fallbacks[i]; i++) {
+ if (parse_dir_fallback_line(default_fallbacks[i], 0)<0) {
log_err(LD_BUG, "Couldn't parse internal FallbackDir line %s",
- fallback[i]);
+ default_fallbacks[i]);
}
}
}
@@ -1443,7 +1446,7 @@ options_transition_requires_fresh_tls_context(const or_options_t *old_options,
* Note: We haven't moved all the "act on new configuration" logic
* here yet. Some is still in do_hup() and other places.
*/
-static int
+STATIC int
options_act(const or_options_t *old_options)
{
config_line_t *cl;
@@ -1465,10 +1468,12 @@ options_act(const or_options_t *old_options)
if (options->DisableDebuggerAttachment && !disabled_debugger_attach &&
running_tor) {
int ok = tor_disable_debugger_attach();
+ /* LCOV_EXCL_START the warned_debugger_attach is 0 can't reach inside. */
if (warned_debugger_attach && ok == 1) {
log_notice(LD_CONFIG, "Disabled attaching debuggers for unprivileged "
"users.");
}
+ /* LCOV_EXCL_STOP */
disabled_debugger_attach = (ok == 1);
} else if (!options->DisableDebuggerAttachment &&
!warned_debugger_attach) {
@@ -1495,12 +1500,14 @@ options_act(const or_options_t *old_options)
#endif
#ifdef ENABLE_TOR2WEB_MODE
+/* LCOV_EXCL_START */
if (!options->Tor2webMode) {
log_err(LD_CONFIG, "This copy of Tor was compiled to run in "
"'tor2web mode'. It can only be run with the Tor2webMode torrc "
"option enabled.");
return -1;
}
+/* LCOV_EXCL_STOP */
#else
if (options->Tor2webMode) {
log_err(LD_CONFIG, "This copy of Tor was not compiled to run in "
@@ -1512,7 +1519,7 @@ options_act(const or_options_t *old_options)
#endif
/* If we are a bridge with a pluggable transport proxy but no
- Extended ORPort, inform the user that she is missing out. */
+ Extended ORPort, inform the user that they are missing out. */
if (server_mode(options) && options->ServerTransportPlugin &&
!options->ExtORPort_lines) {
log_notice(LD_CONFIG, "We use pluggable transports but the Extended "
@@ -1764,8 +1771,8 @@ options_act(const or_options_t *old_options)
if (revise_trackexithosts)
addressmap_clear_excluded_trackexithosts(options);
- if (!options->AutomapHostsOnResolve) {
- if (old_options->AutomapHostsOnResolve)
+ if (!options->AutomapHostsOnResolve &&
+ old_options->AutomapHostsOnResolve) {
revise_automap_entries = 1;
} else {
if (!smartlist_strings_eq(old_options->AutomapHostsSuffixes,
@@ -1904,8 +1911,8 @@ options_act(const or_options_t *old_options)
print_notice = 1;
}
if (print_notice)
- log_notice(LD_CONFIG, "Configured to measure statistics. Look for "
- "the *-stats files that will first be written to the "
+ log_notice(LD_CONFIG, "Configured to measure statistics. Look for "
+ "the *-stats files that will first be written to the "
"data directory in 24 hours from now.");
}
@@ -3473,8 +3480,30 @@ options_validate(or_options_t *old_options, or_options_t *options,
options->AccountingRule = ACCT_SUM;
else if (!strcmp(options->AccountingRule_option, "max"))
options->AccountingRule = ACCT_MAX;
+ else if (!strcmp(options->AccountingRule_option, "in"))
+ options->AccountingRule = ACCT_IN;
+ else if (!strcmp(options->AccountingRule_option, "out"))
+ options->AccountingRule = ACCT_OUT;
else
- REJECT("AccountingRule must be 'sum' or 'max'");
+ REJECT("AccountingRule must be 'sum', 'max', 'in', or 'out'");
+ }
+
+ if (options->DirPort_set && !options->DirCache) {
+ REJECT("DirPort configured but DirCache disabled. DirPort requires "
+ "DirCache.");
+ }
+
+ if (options->BridgeRelay && !options->DirCache) {
+ REJECT("We're a bridge but DirCache is disabled. BridgeRelay requires "
+ "DirCache.");
+ }
+
+ if (server_mode(options)) {
+ char *msg = NULL;
+ if (have_enough_mem_for_dircache(options, 0, &msg)) {
+ log_warn(LD_CONFIG, "%s", msg);
+ tor_free(msg);
+ }
}
if (options->HTTPProxy) { /* parse it now */
@@ -4085,6 +4114,52 @@ compute_real_max_mem_in_queues(const uint64_t val, int log_guess)
}
}
+/* If we have less than 300 MB suggest disabling dircache */
+#define DIRCACHE_MIN_MB_BANDWIDTH 300
+#define DIRCACHE_MIN_BANDWIDTH (DIRCACHE_MIN_MB_BANDWIDTH*ONE_MEGABYTE)
+#define STRINGIFY(val) #val
+
+/** Create a warning message for emitting if we are a dircache but may not have
+ * enough system memory, or if we are not a dircache but probably should be.
+ * Return -1 when a message is returned in *msg*, else return 0. */
+STATIC int
+have_enough_mem_for_dircache(const or_options_t *options, size_t total_mem,
+ char **msg)
+{
+ *msg = NULL;
+ /* XXX We should possibly be looking at MaxMemInQueues here
+ * unconditionally. Or we should believe total_mem unconditionally. */
+ if (total_mem == 0) {
+ if (get_total_system_memory(&total_mem) < 0) {
+ total_mem = options->MaxMemInQueues >= SIZE_MAX ?
+ SIZE_MAX : (size_t)options->MaxMemInQueues;
+ }
+ }
+ if (options->DirCache) {
+ if (total_mem < DIRCACHE_MIN_BANDWIDTH) {
+ if (options->BridgeRelay) {
+ *msg = strdup("Running a Bridge with less than "
+ STRINGIFY(DIRCACHE_MIN_MB_BANDWIDTH) " MB of memory is "
+ "not recommended.");
+ } else {
+ *msg = strdup("Being a directory cache (default) with less than "
+ STRINGIFY(DIRCACHE_MIN_MB_BANDWIDTH) " MB of memory is "
+ "not recommended and may consume most of the available "
+ "resources, consider disabling this functionality by "
+ "setting the DirCache option to 0.");
+ }
+ }
+ } else {
+ if (total_mem >= DIRCACHE_MIN_BANDWIDTH) {
+ *msg = strdup("DirCache is disabled and we are configured as a "
+ "relay. This may disqualify us from becoming a guard in the "
+ "future.");
+ }
+ }
+ return *msg == NULL ? 0 : -1;
+}
+#undef STRINGIFY
+
/** Helper: return true iff s1 and s2 are both NULL, or both non-NULL
* equal strings. */
static int
@@ -4273,7 +4348,8 @@ options_transition_affects_descriptor(const or_options_t *old_options,
!opt_streq(old_options->MyFamily, new_options->MyFamily) ||
!opt_streq(old_options->AccountingStart, new_options->AccountingStart) ||
old_options->AccountingMax != new_options->AccountingMax ||
- public_server_mode(old_options) != public_server_mode(new_options))
+ public_server_mode(old_options) != public_server_mode(new_options) ||
+ old_options->DirCache != new_options->DirCache)
return 1;
return 0;
@@ -6018,15 +6094,6 @@ warn_nonlocal_controller_ports(smartlist_t *ports, unsigned forbid_nonlocal)
} SMARTLIST_FOREACH_END(port);
}
-#define CL_PORT_NO_STREAM_OPTIONS (1u<<0)
-#define CL_PORT_WARN_NONLOCAL (1u<<1)
-#define CL_PORT_ALLOW_EXTRA_LISTENADDR (1u<<2)
-#define CL_PORT_SERVER_OPTIONS (1u<<3)
-#define CL_PORT_FORBID_NONLOCAL (1u<<4)
-#define CL_PORT_TAKES_HOSTNAMES (1u<<5)
-#define CL_PORT_IS_UNIXSOCKET (1u<<6)
-#define CL_PORT_DFLT_GROUP_WRITABLE (1u<<7)
-
#ifdef HAVE_SYS_UN_H
/** Parse the given <b>addrport</b> and set <b>path_out</b> if a Unix socket
@@ -6114,7 +6181,7 @@ config_parse_unix_port(const char *addrport, char **path_out)
* <b>out</b> for every port that the client should listen on. Return 0
* on success, -1 on failure.
*/
-static int
+STATIC int
parse_port_config(smartlist_t *out,
const config_line_t *ports,
const config_line_t *listenaddrs,
@@ -6320,7 +6387,7 @@ parse_port_config(smartlist_t *out,
}
port = ptmp;
} else {
- log_warn(LD_CONFIG, "Couldn't parse address '%s' for %sPort",
+ log_warn(LD_CONFIG, "Couldn't parse address %s for %sPort",
escaped(addrport), portname);
goto err;
}
@@ -7344,7 +7411,7 @@ getinfo_helper_config(control_connection_t *conn,
smartlist_free(sl);
} else if (!strcmp(question, "config/defaults")) {
smartlist_t *sl = smartlist_new();
- int i, dirauth_lines_seen = 0;
+ int i, dirauth_lines_seen = 0, fallback_lines_seen = 0;
for (i = 0; option_vars_[i].name; ++i) {
const config_var_t *var = &option_vars_[i];
if (var->initvalue != NULL) {
@@ -7355,6 +7422,13 @@ getinfo_helper_config(control_connection_t *conn,
*/
++dirauth_lines_seen;
}
+ if (strcmp(option_vars_[i].name, "FallbackDir") == 0) {
+ /*
+ * Similarly count fallback lines, so that we can decided later
+ * to add the defaults manually.
+ */
+ ++fallback_lines_seen;
+ }
char *val = esc_for_log(var->initvalue);
smartlist_add_asprintf(sl, "%s %s\n",var->name,val);
tor_free(val);
@@ -7380,6 +7454,24 @@ getinfo_helper_config(control_connection_t *conn,
}
}
+ if (fallback_lines_seen == 0 &&
+ get_options()->UseDefaultFallbackDirs == 1) {
+ /*
+ * We didn't see any explicitly configured fallback mirrors,
+ * so add the defaults to the list manually.
+ *
+ * default_fallbacks is included earlier in this file and
+ * is a const char ** NULL-terminated array of fallback config lines.
+ */
+ const char **i;
+
+ for (i = default_fallbacks; *i != NULL; ++i) {
+ char *val = esc_for_log(*i);
+ smartlist_add_asprintf(sl, "FallbackDir %s\n", val);
+ tor_free(val);
+ }
+ }
+
*answer = smartlist_join_strings(sl, "", 0, NULL);
SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
smartlist_free(sl);
diff --git a/src/or/config.h b/src/or/config.h
index bfdd1694eb..c7ce57d2aa 100644
--- a/src/or/config.h
+++ b/src/or/config.h
@@ -16,7 +16,7 @@
MOCK_DECL(const char*, get_dirportfrontpage, (void));
MOCK_DECL(const or_options_t *, get_options, (void));
-or_options_t *get_options_mutable(void);
+MOCK_DECL(or_options_t *, get_options_mutable, (void));
int set_options(or_options_t *new_val, char **msg);
void config_free_all(void);
const char *safe_str_client(const char *address);
@@ -136,6 +136,17 @@ smartlist_t *get_options_from_transport_options_line(const char *line,
smartlist_t *get_options_for_server_transport(const char *transport);
#ifdef CONFIG_PRIVATE
+
+#define CL_PORT_NO_STREAM_OPTIONS (1u<<0)
+#define CL_PORT_WARN_NONLOCAL (1u<<1)
+#define CL_PORT_ALLOW_EXTRA_LISTENADDR (1u<<2)
+#define CL_PORT_SERVER_OPTIONS (1u<<3)
+#define CL_PORT_FORBID_NONLOCAL (1u<<4)
+#define CL_PORT_TAKES_HOSTNAMES (1u<<5)
+#define CL_PORT_IS_UNIXSOCKET (1u<<6)
+#define CL_PORT_DFLT_GROUP_WRITABLE (1u<<7)
+
+STATIC int options_act(const or_options_t *old_options);
#ifdef TOR_UNIT_TESTS
extern struct config_format_t options_format;
#endif
@@ -158,6 +169,16 @@ STATIC int parse_dir_authority_line(const char *line,
dirinfo_type_t required_type,
int validate_only);
STATIC int parse_dir_fallback_line(const char *line, int validate_only);
+STATIC int have_enough_mem_for_dircache(const or_options_t *options,
+ size_t total_mem, char **msg);
+STATIC int parse_port_config(smartlist_t *out,
+ const config_line_t *ports,
+ const config_line_t *listenaddrs,
+ const char *portname,
+ int listener_type,
+ const char *defaultaddr,
+ int defaultport,
+ const unsigned flags);
#endif
#endif
diff --git a/src/or/connection.c b/src/or/connection.c
index 63bfb2e01e..a8ce220c60 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -1138,11 +1138,12 @@ connection_listener_new(const struct sockaddr *listensockaddr,
tor_socket_strerror(errno));
}
-#if defined USE_TRANSPARENT && defined(IP_TRANSPARENT)
+#if defined(USE_TRANSPARENT) && defined(IP_TRANSPARENT)
if (options->TransProxyType_parsed == TPT_TPROXY &&
type == CONN_TYPE_AP_TRANS_LISTENER) {
int one = 1;
- if (setsockopt(s, SOL_IP, IP_TRANSPARENT, &one, sizeof(one)) < 0) {
+ if (setsockopt(s, SOL_IP, IP_TRANSPARENT, (void*)&one,
+ (socklen_t)sizeof(one)) < 0) {
const char *extra = "";
int e = tor_socket_errno(s);
if (e == EPERM)
@@ -1156,16 +1157,11 @@ connection_listener_new(const struct sockaddr *listensockaddr,
#ifdef IPV6_V6ONLY
if (listensockaddr->sa_family == AF_INET6) {
-#ifdef _WIN32
- /* In Redmond, this kind of thing passes for standards-conformance. */
- DWORD one = 1;
-#else
int one = 1;
-#endif
/* We need to set IPV6_V6ONLY so that this socket can't get used for
* IPv4 connections. */
if (setsockopt(s,IPPROTO_IPV6, IPV6_V6ONLY,
- (void*)&one, sizeof(one)) < 0) {
+ (void*)&one, (socklen_t)sizeof(one)) < 0) {
int e = tor_socket_errno(s);
log_warn(LD_NET, "Error setting IPV6_V6ONLY flag: %s",
tor_socket_strerror(e));
@@ -1447,7 +1443,7 @@ connection_handle_listener_read(connection_t *conn, int new_type)
if (!SOCKET_OK(news)) { /* accept() error */
int e = tor_socket_errno(conn->s);
if (ERRNO_IS_ACCEPT_EAGAIN(e)) {
- return 0; /* he hung up before we could accept(). that's fine. */
+ return 0; /* they hung up before we could accept(). that's fine. */
} else if (ERRNO_IS_RESOURCE_LIMIT(e)) {
warn_too_many_conns();
return 0;
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 8a3beb3ce9..758d583c39 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -800,20 +800,23 @@ connection_ap_attach_pending(int retry)
if (untried_pending_connections == 0 && !retry)
return;
- SMARTLIST_FOREACH_BEGIN(pending_entry_connections,
+ /* Don't allow modifications to pending_entry_connections while we are
+ * iterating over it. */
+ smartlist_t *pending = pending_entry_connections;
+ pending_entry_connections = smartlist_new();
+
+ SMARTLIST_FOREACH_BEGIN(pending,
entry_connection_t *, entry_conn) {
connection_t *conn = ENTRY_TO_CONN(entry_conn);
tor_assert(conn && entry_conn);
if (conn->marked_for_close) {
UNMARK();
- SMARTLIST_DEL_CURRENT(pending_entry_connections, entry_conn);
continue;
}
if (conn->magic != ENTRY_CONNECTION_MAGIC) {
log_warn(LD_BUG, "%p has impossible magic value %u.",
entry_conn, (unsigned)conn->magic);
UNMARK();
- SMARTLIST_DEL_CURRENT(pending_entry_connections, entry_conn);
continue;
}
if (conn->state != AP_CONN_STATE_CIRCUIT_WAIT) {
@@ -822,7 +825,6 @@ connection_ap_attach_pending(int retry)
entry_conn,
conn_state_to_string(conn->type, conn->state));
UNMARK();
- SMARTLIST_DEL_CURRENT(pending_entry_connections, entry_conn);
continue;
}
@@ -832,18 +834,19 @@ connection_ap_attach_pending(int retry)
END_STREAM_REASON_CANT_ATTACH);
}
- if (conn->marked_for_close ||
- conn->type != CONN_TYPE_AP ||
- conn->state != AP_CONN_STATE_CIRCUIT_WAIT) {
- UNMARK();
- SMARTLIST_DEL_CURRENT(pending_entry_connections, entry_conn);
- continue;
+ if (! conn->marked_for_close &&
+ conn->type == CONN_TYPE_AP &&
+ conn->state == AP_CONN_STATE_CIRCUIT_WAIT) {
+ if (!smartlist_contains(pending_entry_connections, entry_conn)) {
+ smartlist_add(pending_entry_connections, entry_conn);
+ continue;
+ }
}
- tor_assert(conn->magic == ENTRY_CONNECTION_MAGIC);
-
+ UNMARK();
} SMARTLIST_FOREACH_END(entry_conn);
+ smartlist_free(pending);
untried_pending_connections = 0;
}
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index 73e4d19369..d778eb3b4f 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -1581,7 +1581,7 @@ connection_or_nonopen_was_started_here(or_connection_t *conn)
}
/** <b>Conn</b> just completed its handshake. Return 0 if all is well, and
- * return -1 if he is lying, broken, or otherwise something is wrong.
+ * return -1 if they are lying, broken, or otherwise something is wrong.
*
* If we initiated this connection (<b>started_here</b> is true), make sure
* the other side sent a correctly formed certificate. If I initiated the
@@ -1754,7 +1754,7 @@ connection_or_client_used(or_connection_t *conn)
*
* Make sure we are happy with the person we just handshaked with.
*
- * If he initiated the connection, make sure he's not already connected,
+ * If they initiated the connection, make sure they're not already connected,
* then initialize conn from the information in router.
*
* If all is successful, call circuit_n_conn_done() to handle events
diff --git a/src/or/directory.c b/src/or/directory.c
index b3a2f36f20..9419f2a590 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -144,7 +144,7 @@ purpose_needs_anonymity(uint8_t dir_purpose, uint8_t router_purpose)
/** Return a newly allocated string describing <b>auth</b>. Only describes
* authority features. */
-static char *
+STATIC char *
authdir_type_to_string(dirinfo_type_t auth)
{
char *result;
@@ -163,7 +163,7 @@ authdir_type_to_string(dirinfo_type_t auth)
}
/** Return a string describing a given directory connection purpose. */
-static const char *
+STATIC const char *
dir_conn_purpose_to_string(int purpose)
{
switch (purpose)
@@ -371,7 +371,7 @@ directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose,
/** Return true iff, according to the values in <b>options</b>, we should be
* using directory guards for direct downloads of directory information. */
-static int
+STATIC int
should_use_directory_guards(const or_options_t *options)
{
/* Public (non-bridge) servers never use directory guards. */
@@ -766,15 +766,15 @@ directory_initiate_command_routerstatus_rend(const routerstatus_t *status,
* When fetching a rendezvous descriptor, <b>resource</b> is the service ID we
* want to fetch.
*/
-void
-directory_initiate_command_routerstatus(const routerstatus_t *status,
- uint8_t dir_purpose,
- uint8_t router_purpose,
- dir_indirection_t indirection,
- const char *resource,
- const char *payload,
- size_t payload_len,
- time_t if_modified_since)
+MOCK_IMPL(void, directory_initiate_command_routerstatus,
+ (const routerstatus_t *status,
+ uint8_t dir_purpose,
+ uint8_t router_purpose,
+ dir_indirection_t indirection,
+ const char *resource,
+ const char *payload,
+ size_t payload_len,
+ time_t if_modified_since))
{
directory_initiate_command_routerstatus_rend(status, dir_purpose,
router_purpose,
@@ -812,7 +812,7 @@ connection_dir_request_failed(dir_connection_t *conn)
return; /* this was a test fetch. don't retry. */
}
if (!entry_list_is_constrained(get_options()))
- router_set_status(conn->identity_digest, 0); /* don't try him again */
+ router_set_status(conn->identity_digest, 0); /* don't try this one again */
if (conn->base_.purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
conn->base_.purpose == DIR_PURPOSE_FETCH_EXTRAINFO) {
log_info(LD_DIR, "Giving up on serverdesc/extrainfo fetch from "
@@ -2742,7 +2742,7 @@ client_likes_consensus(networkstatus_t *v, const char *want_url)
/** Return the compression level we should use for sending a compressed
* response of size <b>n_bytes</b>. */
-static zlib_compression_level_t
+STATIC zlib_compression_level_t
choose_compression_level(ssize_t n_bytes)
{
if (! have_been_under_memory_pressure()) {
@@ -3811,11 +3811,10 @@ connection_dir_finished_connecting(dir_connection_t *conn)
* Then return a list of int pointers defining download delays in seconds.
* Helper function for download_status_increment_failure(),
* download_status_reset(), and download_status_increment_attempt(). */
-static const smartlist_t *
+STATIC const smartlist_t *
find_dl_schedule(download_status_t *dls, const or_options_t *options)
{
- /* XX/teor Replace with dir_server_mode from #12538 */
- const int dir_server = options->DirPort_set;
+ const int dir_server = dir_server_mode(options);
const int multi_d = networkstatus_consensus_can_use_multiple_directories(
options);
const int we_are_bootstrapping = networkstatus_consensus_is_boostrapping(
diff --git a/src/or/directory.h b/src/or/directory.h
index 61c29baf06..2630705fdb 100644
--- a/src/or/directory.h
+++ b/src/or/directory.h
@@ -39,14 +39,16 @@ typedef enum {
DIRIND_ANON_DIRPORT,
} dir_indirection_t;
-void directory_initiate_command_routerstatus(const routerstatus_t *status,
- uint8_t dir_purpose,
- uint8_t router_purpose,
- dir_indirection_t indirection,
- const char *resource,
- const char *payload,
- size_t payload_len,
- time_t if_modified_since);
+MOCK_DECL(void, directory_initiate_command_routerstatus,
+ (const routerstatus_t *status,
+ uint8_t dir_purpose,
+ uint8_t router_purpose,
+ dir_indirection_t indirection,
+ const char *resource,
+ const char *payload,
+ size_t payload_len,
+ time_t if_modified_since));
+
void directory_initiate_command_routerstatus_rend(const routerstatus_t *status,
uint8_t dir_purpose,
uint8_t router_purpose,
@@ -101,7 +103,8 @@ time_t download_status_increment_attempt(download_status_t *dls,
* the optional status code <b>sc</b>. */
#define download_status_failed(dls, sc) \
download_status_increment_failure((dls), (sc), NULL, \
- get_options()->DirPort_set, time(NULL))
+ dir_server_mode(get_options()), \
+ time(NULL))
void download_status_reset(download_status_t *dls);
static int download_status_is_ready(download_status_t *dls, time_t now,
@@ -146,6 +149,13 @@ STATIC int connection_dir_would_close_consensus_conn_helper(void);
STATIC int download_status_schedule_get_delay(download_status_t *dls,
const smartlist_t *schedule,
time_t now);
+
+STATIC char* authdir_type_to_string(dirinfo_type_t auth);
+STATIC const char * dir_conn_purpose_to_string(int purpose);
+STATIC int should_use_directory_guards(const or_options_t *options);
+STATIC zlib_compression_level_t choose_compression_level(ssize_t n_bytes);
+STATIC const smartlist_t *find_dl_schedule(download_status_t *dls,
+ const or_options_t *options);
#endif
#endif
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index 39563c3932..620d324704 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -1091,13 +1091,13 @@ directory_fetches_from_authorities(const or_options_t *options)
return 1; /* we don't know our IP address; ask an authority. */
refuseunknown = ! router_my_exit_policy_is_reject_star() &&
should_refuse_unknown_exits(options);
- if (!options->DirPort_set && !refuseunknown)
+ if (!dir_server_mode(options) && !refuseunknown)
return 0;
if (!server_mode(options) || !advertised_server_mode())
return 0;
me = router_get_my_routerinfo();
- if (!me || (!me->dir_port && !refuseunknown))
- return 0; /* if dirport not advertised, return 0 too */
+ if (!me || (!me->supports_tunnelled_dir_requests && !refuseunknown))
+ return 0; /* if we don't service directory requests, return 0 too */
return 1;
}
@@ -1128,7 +1128,7 @@ directory_fetches_dir_info_later(const or_options_t *options)
int
directory_caches_unknown_auth_certs(const or_options_t *options)
{
- return options->DirPort_set || options->BridgeRelay;
+ return dir_server_mode(options) || options->BridgeRelay;
}
/** Return 1 if we want to keep descriptors, networkstatuses, etc around
@@ -1137,7 +1137,7 @@ directory_caches_unknown_auth_certs(const or_options_t *options)
int
directory_caches_dir_info(const or_options_t *options)
{
- if (options->BridgeRelay || options->DirPort_set)
+ if (options->BridgeRelay || dir_server_mode(options))
return 1;
if (!server_mode(options) || !advertised_server_mode())
return 0;
@@ -1153,7 +1153,7 @@ directory_caches_dir_info(const or_options_t *options)
int
directory_permits_begindir_requests(const or_options_t *options)
{
- return options->BridgeRelay != 0 || options->DirPort_set;
+ return options->BridgeRelay != 0 || dir_server_mode(options);
}
/** Return 1 if we have no need to fetch new descriptors. This generally
@@ -1350,8 +1350,9 @@ dirserv_thinks_router_is_unreliable(time_t now,
}
/** Return true iff <b>router</b> should be assigned the "HSDir" flag.
+ *
* Right now this means it advertises support for it, it has a high uptime,
- * it has a DirPort open, it has the Stable and Fast flag and it's currently
+ * it's a directory cache, it has the Stable and Fast flags, and it's currently
* considered Running.
*
* This function needs to be called after router-\>is_running has
@@ -1378,7 +1379,8 @@ dirserv_thinks_router_is_hs_dir(const routerinfo_t *router,
else
uptime = real_uptime(router, now);
- return (router->wants_to_be_hs_dir && router->dir_port &&
+ return (router->wants_to_be_hs_dir &&
+ router->supports_tunnelled_dir_requests &&
node->is_stable && node->is_fast &&
uptime >= get_options()->MinUptimeHidServDirectoryV2 &&
router_is_active(router, node, now));
@@ -1921,7 +1923,7 @@ routerstatus_format_entry(const routerstatus_t *rs, const char *version,
rs->is_hs_dir?" HSDir":"",
rs->is_flagged_running?" Running":"",
rs->is_stable?" Stable":"",
- (rs->dir_port!=0)?" V2Dir":"",
+ rs->is_v2_dir?" V2Dir":"",
rs->is_valid?" Valid":"");
/* length of "opt v \n" */
@@ -2185,6 +2187,7 @@ set_routerstatus_from_routerinfo(routerstatus_t *rs,
strlcpy(rs->nickname, ri->nickname, sizeof(rs->nickname));
rs->or_port = ri->or_port;
rs->dir_port = ri->dir_port;
+ rs->is_v2_dir = ri->supports_tunnelled_dir_requests;
if (options->AuthDirHasIPv6Connectivity == 1 &&
!tor_addr_is_null(&ri->ipv6_addr) &&
node->last_reachable6 >= now - REACHABLE_TIMEOUT) {
diff --git a/src/or/dirvote.c b/src/or/dirvote.c
index 0449e9d8d9..b61b33af79 100644
--- a/src/or/dirvote.c
+++ b/src/or/dirvote.c
@@ -54,7 +54,6 @@ static int dirvote_perform_vote(void);
static void dirvote_clear_votes(int all_votes);
static int dirvote_compute_consensuses(void);
static int dirvote_publish_consensus(void);
-static char *make_consensus_method_list(int low, int high, const char *sep);
/* =====
* Voting
@@ -564,7 +563,7 @@ consensus_method_is_supported(int method)
/** Return a newly allocated string holding the numbers between low and high
* (inclusive) that are supported consensus methods. */
-static char *
+STATIC char *
make_consensus_method_list(int low, int high, const char *separator)
{
char *list;
diff --git a/src/or/dirvote.h b/src/or/dirvote.h
index 966d163088..cc526ea34e 100644
--- a/src/or/dirvote.h
+++ b/src/or/dirvote.h
@@ -177,6 +177,7 @@ STATIC char *format_networkstatus_vote(crypto_pk_t *private_key,
STATIC char *dirvote_compute_params(smartlist_t *votes, int method,
int total_authorities);
STATIC char *compute_consensus_package_lines(smartlist_t *votes);
+STATIC char *make_consensus_method_list(int low, int high, const char *sep);
#endif
#endif
diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c
index 1ce44d1026..d6bef658ff 100644
--- a/src/or/entrynodes.c
+++ b/src/or/entrynodes.c
@@ -1156,7 +1156,7 @@ choose_random_entry_impl(cpath_build_state_t *state, int for_directory,
} else {
/* Try to have at least 2 choices available. This way we don't
* get stuck with a single live-but-crummy entry and just keep
- * using him.
+ * using it.
* (We might get 2 live-but-crummy entry guards, but so be it.) */
preferred_min = 2;
}
diff --git a/src/or/ext_orport.c b/src/or/ext_orport.c
index f159f7d0a6..810fa0d9aa 100644
--- a/src/or/ext_orport.c
+++ b/src/or/ext_orport.c
@@ -151,7 +151,7 @@ init_ext_or_cookie_authentication(int is_enabled)
}
/** Read data from <b>conn</b> and see if the client sent us the
- * authentication type that she prefers to use in this session.
+ * authentication type that they prefer to use in this session.
*
* Return -1 if we received corrupted data or if we don't support the
* authentication type. Return 0 if we need more data in
diff --git a/src/or/fallback_dirs.inc b/src/or/fallback_dirs.inc
index d9214cb884..d05f16f4ea 100644
--- a/src/or/fallback_dirs.inc
+++ b/src/or/fallback_dirs.inc
@@ -1 +1,206 @@
-/* This list will be empty until opt-ins are finalised. */
+/* Trial fallbacks for 0.2.8.1-alpha with ADDRESS_AND_PORT_STABLE_DAYS = 30
+ * This works around an issue where relays post a descriptor without a DirPort
+ * when restarted. If these relays stay up, they will have been up for 120 days
+ * by the 0.2.8 stable release -- teor */
+/* Whitelist & blacklist excluded 1070 of 1091 candidates. */
+/*
+Fallback Directory Summary
+Final Count: 21 (Eligible 21, Usable 21, Target 290 (1454 * 0.200000), Clamped to 500)
+*/
+/* Ignore low fallback numbers in alpha builds -- teor
+#error Fallback Count 21 is too low. Must be at least 100 for diversity. Try adding entries to the whitelist, or setting INCLUDE_UNLISTED_ENTRIES = True.
+*/
+/*
+Final Weight: 491920 (Eligible 546000)
+Max Weight: 43680 (8.879%) (Clamped to 10.000%)
+Min Weight: 8080 (1.643%) (Clamped to 0.100%)
+Clamped: 54080 (10.994%) Excess Weight, 4 High Weight Fallbacks (19.0%)
+*/
+/*
+Onionoo Source: details Date: 2016-01-18 00:00:00 Version: 3.0
+URL: https://onionoo.torproject.org/details?fields=fingerprint%2Cnickname%2Ccontact%2Clast_changed_address_or_port%2Cconsensus_weight%2Cor_addresses%2Cdir_address%2Crecommended_version%2Cflags&flag=V2Dir&type=relay&last_seen_days=-7&first_seen_days=30-
+*/
+/*
+Onionoo Source: uptime Date: 2016-01-18 00:00:00 Version: 3.0
+URL: https://onionoo.torproject.org/uptime?first_seen_days=30-&flag=V2Dir&type=relay&last_seen_days=-7
+*/
+/*
+wagner
+Flags: Fast Guard Running Stable V2Dir Valid
+Fallback Weight: 43680 / 491920 (8.879%)
+Consensus Weight: 62600 / 546000 (11.465%)
+Rarely used email <trff914 AT gmail DOT com>
+*/
+"5.175.233.86:80 orport=443 id=5525D0429BFE5DC4F1B0E9DE47A4CFA169661E33"
+" weight=43680",
+/*
+kitten2
+Flags: Fast Guard HSDir Running Stable V2Dir Valid
+Fallback Weight: 43680 / 491920 (8.879%)
+Consensus Weight: 59100 / 546000 (10.824%)
+0xEFB74277ECE4E222 Aeris <aeris+tor AT imirhil DOT fr> - 1aerisnnLWPchhDSXpxWGYWwLiSFUVFnd
+*/
+"62.210.124.124:9130 orport=9101 id=2EBD117806EE43C3CC885A8F1E4DC60F207E7D3E"
+" ipv6=[2001:bc8:3f23:100::1]:9101"
+" weight=43680",
+/*
+kitten1
+Flags: Fast Guard HSDir Running Stable V2Dir Valid
+Fallback Weight: 43680 / 491920 (8.879%)
+Consensus Weight: 57600 / 546000 (10.549%)
+0xEFB74277ECE4E222 Aeris <aeris+tor AT imirhil DOT fr> - 1aerisnnLWPchhDSXpxWGYWwLiSFUVFnd
+*/
+"62.210.124.124:9030 orport=9001 id=86E78DD3720C78DA8673182EF96C54B162CD660C"
+" ipv6=[2001:bc8:3f23:100::1]:9001"
+" weight=43680",
+/*
+fluxe4
+Flags: Fast Guard HSDir Running Stable V2Dir Valid
+Fallback Weight: 43680 / 491920 (8.879%)
+Consensus Weight: 49500 / 546000 (9.066%)
+Sebastian <tor@sebastianhahn.net> - 12NbRAjAG5U3LLWETSF7fSTcdaz32Mu5CN
+*/
+"131.188.40.188:443 orport=80 id=EBE718E1A49EE229071702964F8DB1F318075FF8"
+" weight=43680",
+/*
+BabylonNetwork03
+Flags: Exit Fast Guard HSDir Running Stable V2Dir Valid
+Fallback Weight: 38700 / 491920 (7.867%)
+Babylon Network | noc <AT> babylon <DOT> network | PGP 0x2A540FA5 | 1HiSG8pia5DdDLUMyYNkF9sicGozojZLnH
+*/
+"193.111.136.162:80 orport=443 id=C79552275DFCD486B942510EF663ED36ACA1A84B"
+" ipv6=[2001:4ba0:cafe:10d0::1]:443"
+" weight=38700",
+/*
+tornoderdednl
+Flags: Fast Guard Running Stable V2Dir Valid
+Fallback Weight: 33000 / 491920 (6.708%)
+0x4871E82F Thom Wiggers <thom @AT@ RDED POINT NL> BTC 1DLyDFV13zhCWJYHMh5bk5C58yYvpxqxfQ
+*/
+"178.62.199.226:80 orport=443 id=CBEFF7BA4A4062045133C053F2D70524D8BBE5BE"
+" ipv6=[2a03:b0c0:2:d0::b7:5001]:443"
+" weight=33000",
+/*
+fluxe3
+Flags: Fast Guard HSDir Running Stable V2Dir Valid
+Fallback Weight: 31500 / 491920 (6.403%)
+Sebastian <tor@sebastianhahn.net> - 12NbRAjAG5U3LLWETSF7fSTcdaz32Mu5CN
+*/
+"78.47.18.110:443 orport=80 id=F8D27B163B9247B232A2EEE68DD8B698695C28DE"
+" weight=31500",
+/*
+BabylonNetwork02
+Flags: Exit Fast Guard HSDir Running Stable V2Dir Valid
+Fallback Weight: 27300 / 491920 (5.550%)
+Babylon Network | noc <AT> babylon <DOT> network | PGP 0x2A540FA5 | 1HiSG8pia5DdDLUMyYNkF9sicGozojZLnH
+*/
+"149.202.98.161:80 orport=443 id=54660C671B47E6986B465B80444414BD19E5A34B"
+" ipv6=[2001:41d0:8:4528::161]:443"
+" weight=27300",
+/*
+coby
+Flags: Fast Guard HSDir Running Stable V2Dir Valid
+Fallback Weight: 20400 / 491920 (4.147%)
+c0by <coby AT 127001 dot ovh>
+*/
+"51.255.33.237:9091 orport=9001 id=A360C21FA87FFA2046D92C17086A6B47E5C68109"
+" weight=20400",
+/*
+kili
+Flags: Fast Guard HSDir Running Stable V2Dir Valid
+Fallback Weight: 19300 / 491920 (3.923%)
+0x49CBC553 Joost Rijneveld <joost AT joostrijneveld dot nl>
+*/
+"178.62.173.203:9030 orport=9001 id=DD85503F2D1F52EF9EAD621E942298F46CD2FC10"
+" ipv6=[2a03:b0c0:0:1010::a4:b001]:9001"
+" weight=19300",
+/*
+Logforme
+Flags: Fast Guard HSDir Running Stable V2Dir Valid
+Fallback Weight: 18600 / 491920 (3.781%)
+Logforme <m7527 AT abc dot se>
+*/
+"84.219.173.60:9030 orport=443 id=855BC2DABE24C861CD887DB9B2E950424B49FC34"
+" weight=18600",
+/*
+eriador
+Flags: Fast Guard HSDir Running Stable V2Dir Valid
+Fallback Weight: 17400 / 491920 (3.537%)
+hwertiout695@safe-mail.net
+*/
+"85.25.138.93:9030 orport=4029 id=6DE61A6F72C1E5418A66BFED80DFB63E4C77668F"
+" weight=17400",
+/*
+Doedel24
+Flags: Fast Guard HSDir Running Stable V2Dir Valid
+Fallback Weight: 17000 / 491920 (3.456%)
+Felix <zwiebel ta quantentunnel tod de>
+*/
+"178.254.20.134:9030 orport=9001 id=2CE96A8A1DA032664C90F574AFFBECE18A6E8DFC"
+" weight=17000",
+/*
+GrmmlLitavis
+Flags: Fast Guard HSDir Running Stable V2Dir Valid
+Fallback Weight: 15500 / 491920 (3.151%)
+<tor AT grmml DOT eu>
+*/
+"5.39.88.19:9030 orport=9001 id=7CB8C31432A796731EA7B6BF4025548DFEB25E0C"
+" ipv6=[2001:41d0:8:9a13::1]:9050"
+" weight=15500",
+/*
+Doedel21
+Flags: Fast Guard HSDir Running Stable V2Dir Valid
+Fallback Weight: 13800 / 491920 (2.805%)
+Felix <zwiebel ta quantentunnel tod de>
+*/
+"178.254.44.135:80 orport=443 id=AE6A8C18E7499B586CD36246AC4BCAFFBBF93AB2"
+" weight=13800",
+/*
+Unnamed
+Flags: Fast Guard HSDir Running Stable V2Dir Valid
+Fallback Weight: 13400 / 491920 (2.724%)
+monitor0penmailbox0rg
+*/
+"217.12.199.208:80 orport=443 id=DF3AED4322B1824BF5539AE54B2D1B38E080FF05"
+" weight=13400",
+/*
+Doedel26
+Flags: Fast Guard HSDir Running Stable V2Dir Valid
+Fallback Weight: 12800 / 491920 (2.602%)
+Felix <zwiebel ta quantentunnel tod de>
+*/
+"178.254.20.134:80 orport=443 id=9F5068310818ED7C70B0BC4087AB55CB12CB4377"
+" weight=12800",
+/*
+Doedel22
+Flags: Fast Guard HSDir Running Stable V2Dir Valid
+Fallback Weight: 12000 / 491920 (2.439%)
+Felix <zwiebel ta quantentunnel tod de>
+*/
+"178.254.44.135:9030 orport=9001 id=8FA37B93397015B2BC5A525C908485260BE9F422"
+" weight=12000",
+/*
+kitten4
+Flags: Fast Guard HSDir Running Stable V2Dir Valid
+Fallback Weight: 10100 / 491920 (2.053%)
+0xEFB74277ECE4E222 Aeris <aeris+tor AT imirhil DOT fr> - 1aerisnnLWPchhDSXpxWGYWwLiSFUVFnd
+*/
+"212.47.237.95:9130 orport=9101 id=6FB38EB22E57EF7ED5EF00238F6A48E553735D88"
+" weight=10100",
+/*
+Binnacle
+Flags: Fast Guard HSDir Running Stable V2Dir Valid
+Fallback Weight: 8320 / 491920 (1.691%)
+starlight dot YYYYqQ at binnacle dot cx
+*/
+"108.53.208.157:80 orport=443 id=4F0DB7E687FC7C0AE55C8F243DA8B0EB27FBF1F2"
+" weight=8320",
+/*
+PedicaboMundi
+Flags: Fast Guard HSDir Running Stable V2Dir Valid
+Fallback Weight: 8080 / 491920 (1.643%)
+0x43DE8191 - 12LiRiasTEL346ZFjgCh5e3nBexQuvDBTg
+*/
+"144.76.14.145:110 orport=143 id=14419131033443AE6E21DA82B0D307F7CAE42BDB"
+" ipv6=[2a01:4f8:190:9490::dead]:443"
+" weight=8080",
diff --git a/src/or/geoip.c b/src/or/geoip.c
index 3ef1672f52..26030ae52a 100644
--- a/src/or/geoip.c
+++ b/src/or/geoip.c
@@ -1279,6 +1279,8 @@ geoip_dirreq_stats_write(time_t now)
/* Generate history string .*/
str = geoip_format_dirreq_stats(now);
+ if (! str)
+ goto done;
/* Write dirreq-stats string to disk. */
if (!check_or_create_data_subdir("stats")) {
diff --git a/src/or/hibernate.c b/src/or/hibernate.c
index 5f727e27d4..7f8530b221 100644
--- a/src/or/hibernate.c
+++ b/src/or/hibernate.c
@@ -412,11 +412,15 @@ configure_accounting(time_t now)
/** Return the relevant number of bytes sent/received this interval
* based on the set AccountingRule */
-static uint64_t
+uint64_t
get_accounting_bytes(void)
{
if (get_options()->AccountingRule == ACCT_SUM)
return n_bytes_read_in_interval+n_bytes_written_in_interval;
+ else if (get_options()->AccountingRule == ACCT_IN)
+ return n_bytes_read_in_interval;
+ else if (get_options()->AccountingRule == ACCT_OUT)
+ return n_bytes_written_in_interval;
else
return MAX(n_bytes_read_in_interval, n_bytes_written_in_interval);
}
@@ -1010,7 +1014,7 @@ getinfo_helper_accounting(control_connection_t *conn,
else
*answer = tor_strdup("awake");
} else if (!strcmp(question, "accounting/bytes")) {
- tor_asprintf(answer, U64_FORMAT" "U64_FORMAT,
+ tor_asprintf(answer, U64_FORMAT" "U64_FORMAT,
U64_PRINTF_ARG(n_bytes_read_in_interval),
U64_PRINTF_ARG(n_bytes_written_in_interval));
} else if (!strcmp(question, "accounting/bytes-left")) {
@@ -1022,6 +1026,18 @@ getinfo_helper_accounting(control_connection_t *conn,
total_left = limit - total_bytes;
tor_asprintf(answer, U64_FORMAT" "U64_FORMAT,
U64_PRINTF_ARG(total_left), U64_PRINTF_ARG(total_left));
+ } else if (get_options()->AccountingRule == ACCT_IN) {
+ uint64_t read_left = 0;
+ if (n_bytes_read_in_interval < limit)
+ read_left = limit - n_bytes_read_in_interval;
+ tor_asprintf(answer, U64_FORMAT" "U64_FORMAT,
+ U64_PRINTF_ARG(read_left), U64_PRINTF_ARG(limit));
+ } else if (get_options()->AccountingRule == ACCT_OUT) {
+ uint64_t write_left = 0;
+ if (n_bytes_written_in_interval < limit)
+ write_left = limit - n_bytes_written_in_interval;
+ tor_asprintf(answer, U64_FORMAT" "U64_FORMAT,
+ U64_PRINTF_ARG(limit), U64_PRINTF_ARG(write_left));
} else {
uint64_t read_left = 0, write_left = 0;
if (n_bytes_read_in_interval < limit)
diff --git a/src/or/hibernate.h b/src/or/hibernate.h
index b9e619c5ad..e0d0c29bdb 100644
--- a/src/or/hibernate.h
+++ b/src/or/hibernate.h
@@ -19,6 +19,7 @@ MOCK_DECL(int, accounting_is_enabled, (const or_options_t *options));
int accounting_get_interval_length(void);
MOCK_DECL(time_t, accounting_get_end_time, (void));
void configure_accounting(time_t now);
+uint64_t get_accounting_bytes(void);
void accounting_run_housekeeping(time_t now);
void accounting_add_bytes(size_t n_read, size_t n_written, int seconds);
int accounting_record_bandwidth_usage(time_t now, or_state_t *state);
diff --git a/src/or/include.am b/src/or/include.am
index 5ec96e5a93..712ae18406 100644
--- a/src/or/include.am
+++ b/src/or/include.am
@@ -93,7 +93,8 @@ src_or_libtor_testing_a_SOURCES = $(LIBTOR_A_SOURCES)
src_or_tor_SOURCES = src/or/tor_main.c
AM_CPPFLAGS += -I$(srcdir)/src/or -Isrc/or
-src/or/tor_main.o: micro-revision.i
+src/or/tor_main.$(OBJEXT) \
+ src/or/src_or_tor_cov-tor_main.$(OBJEXT): micro-revision.i
AM_CPPFLAGS += -DSHARE_DATADIR="\"$(datadir)\"" \
-DLOCALSTATEDIR="\"$(localstatedir)\"" \
@@ -109,7 +110,7 @@ src_or_libtor_testing_a_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS)
src_or_tor_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ @TOR_LDFLAGS_libevent@
src_or_tor_LDADD = src/or/libtor.a src/common/libor.a \
- src/common/libor-crypto.a $(LIBDONNA) \
+ src/common/libor-crypto.a $(LIBKECCAK_TINY) $(LIBDONNA) \
src/common/libor-event.a src/trunnel/libor-trunnel.a \
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ @TOR_OPENSSL_LIBS@ \
@TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ @TOR_SYSTEMD_LIBS@
@@ -120,7 +121,7 @@ src_or_tor_cov_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_CPPFLAGS)
src_or_tor_cov_CFLAGS = $(AM_CFLAGS) $(TEST_CFLAGS)
src_or_tor_cov_LDFLAGS = @TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ @TOR_LDFLAGS_libevent@
src_or_tor_cov_LDADD = src/or/libtor-testing.a src/common/libor-testing.a \
- src/common/libor-crypto-testing.a $(LIBDONNA) \
+ src/common/libor-crypto-testing.a $(LIBKECCAK_TINY) $(LIBDONNA) \
src/common/libor-event-testing.a src/trunnel/libor-trunnel-testing.a \
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ @TOR_LIBEVENT_LIBS@ @TOR_OPENSSL_LIBS@ \
@TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ @TOR_SYSTEMD_LIBS@
diff --git a/src/or/main.c b/src/or/main.c
index 455cba4513..bd4f7eaa71 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -225,11 +225,13 @@ set_buffer_lengths_to_zero(tor_socket_t s)
{
int zero = 0;
int r = 0;
- if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, (void*)&zero, sizeof(zero))) {
+ if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, (void*)&zero,
+ (socklen_t)sizeof(zero))) {
log_warn(LD_NET, "Unable to clear SO_SNDBUF");
r = -1;
}
- if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, (void*)&zero, sizeof(zero))) {
+ if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, (void*)&zero,
+ (socklen_t)sizeof(zero))) {
log_warn(LD_NET, "Unable to clear SO_RCVBUF");
r = -1;
}
@@ -1299,7 +1301,7 @@ static periodic_event_item_t periodic_events[] = {
/* These are pointers to members of periodic_events[] that are used to
* 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 reasaonable way. */
+ * 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;
@@ -2067,8 +2069,9 @@ second_elapsed_callback(periodic_timer_t *timer, void *arg)
if (me && !check_whether_orport_reachable()) {
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. Please check your firewalls, ports, "
- "address, /etc/hosts file, etc.",
+ "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",
@@ -2080,8 +2083,9 @@ second_elapsed_callback(periodic_timer_t *timer, void *arg)
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. Please check your firewalls, ports, "
- "address, /etc/hosts file, etc.",
+ "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",
@@ -3460,6 +3464,9 @@ sandbox_init_filter(void)
".tmp");
OPEN_DATADIR2_SUFFIX("keys", "ed25519_master_id_public_key", ".tmp");
OPEN_DATADIR2_SUFFIX("keys", "ed25519_signing_secret_key", ".tmp");
+ OPEN_DATADIR2_SUFFIX("keys", "ed25519_signing_secret_key_encrypted",
+ ".tmp");
+ OPEN_DATADIR2_SUFFIX("keys", "ed25519_signing_public_key", ".tmp");
OPEN_DATADIR2_SUFFIX("keys", "ed25519_signing_cert", ".tmp");
OPEN_DATADIR2_SUFFIX("stats", "bridge-stats", ".tmp");
diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c
index 0cf8873f03..f3a8276689 100644
--- a/src/or/networkstatus.c
+++ b/src/or/networkstatus.c
@@ -1461,6 +1461,38 @@ networkstatus_copy_old_consensus_info(networkstatus_t *new_c,
} SMARTLIST_FOREACH_JOIN_END(rs_old, rs_new);
}
+#ifdef TOR_UNIT_TESTS
+/**Accept a <b>flavor</b> consensus <b>c</b> without any additional
+ * validation. This is exclusively for unit tests.
+ * We copy any ancillary information from a pre-existing consensus
+ * and then free the current one and replace it with the newly
+ * provided instance. Returns -1 on unrecognized flavor, 0 otherwise.
+ */
+int
+networkstatus_set_current_consensus_from_ns(networkstatus_t *c,
+ const char *flavor)
+{
+ int flav = networkstatus_parse_flavor_name(flavor);
+ switch (flav) {
+ case FLAV_NS:
+ if (current_ns_consensus) {
+ networkstatus_copy_old_consensus_info(c, current_ns_consensus);
+ networkstatus_vote_free(current_ns_consensus);
+ }
+ current_ns_consensus = c;
+ break;
+ case FLAV_MICRODESC:
+ if (current_md_consensus) {
+ networkstatus_copy_old_consensus_info(c, current_md_consensus);
+ networkstatus_vote_free(current_md_consensus);
+ }
+ current_md_consensus = c;
+ break;
+ }
+ return current_md_consensus ? 0 : -1;
+}
+#endif //TOR_UNIT_TESTS
+
/** Try to replace the current cached v3 networkstatus with the one in
* <b>consensus</b>. If we don't have enough certificates to validate it,
* store it in consensus_waiting_for_certs and launch a certificate fetch.
diff --git a/src/or/networkstatus.h b/src/or/networkstatus.h
index 4cb33c3fc0..4eab4d83f8 100644
--- a/src/or/networkstatus.h
+++ b/src/or/networkstatus.h
@@ -114,6 +114,10 @@ int networkstatus_get_weight_scale_param(networkstatus_t *ns);
#ifdef NETWORKSTATUS_PRIVATE
STATIC void vote_routerstatus_free(vote_routerstatus_t *rs);
+#ifdef TOR_UNIT_TESTS
+STATIC int networkstatus_set_current_consensus_from_ns(networkstatus_t *c,
+ const char *flavor);
+#endif // TOR_UNIT_TESTS
#endif
#endif
diff --git a/src/or/nodelist.c b/src/or/nodelist.c
index 28d874133c..d7cada94d3 100644
--- a/src/or/nodelist.c
+++ b/src/or/nodelist.c
@@ -643,12 +643,19 @@ node_is_named(const node_t *node)
int
node_is_dir(const node_t *node)
{
- if (node->rs)
- return node->rs->dir_port != 0;
- else if (node->ri)
- return node->ri->dir_port != 0;
- else
+ if (node->rs) {
+ routerstatus_t * rs = node->rs;
+ /* This is true if supports_tunnelled_dir_requests is true which
+ * indicates that we support directory request tunnelled or through the
+ * DirPort. */
+ return rs->is_v2_dir;
+ } else if (node->ri) {
+ routerinfo_t * ri = node->ri;
+ /* Both tunnelled request is supported or DirPort is set. */
+ return ri->supports_tunnelled_dir_requests;
+ } else {
return 0;
+ }
}
/** Return true iff <b>node</b> has either kind of usable descriptor -- that
diff --git a/src/or/or.h b/src/or/or.h
index 79b1c95ff0..697c576873 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -458,9 +458,11 @@ typedef enum {
#define CIRCUIT_PURPOSE_OR_MIN_ 1
/** OR-side circuit purpose: normal circuit, at OR. */
#define CIRCUIT_PURPOSE_OR 1
-/** OR-side circuit purpose: At OR, from Bob, waiting for intro from Alices. */
+/** OR-side circuit purpose: At OR, from the service, waiting for intro from
+ * clients. */
#define CIRCUIT_PURPOSE_INTRO_POINT 2
-/** OR-side circuit purpose: At OR, from Alice, waiting for Bob. */
+/** OR-side circuit purpose: At OR, from the client, waiting for the service.
+ */
#define CIRCUIT_PURPOSE_REND_POINT_WAITING 3
/** OR-side circuit purpose: At OR, both circuits have this purpose. */
#define CIRCUIT_PURPOSE_REND_ESTABLISHED 4
@@ -479,43 +481,47 @@ typedef enum {
* to becoming open, or they are open and have sent the
* establish_rendezvous cell but haven't received an ack.
* circuits that are c_rend_ready are open and have received a
- * rend ack, but haven't heard from bob yet. if they have a
+ * rend ack, but haven't heard from the service yet. if they have a
* buildstate->pending_final_cpath then they're expecting a
- * cell from bob, else they're not.
+ * cell from the service, else they're not.
* circuits that are c_rend_ready_intro_acked are open, and
* some intro circ has sent its intro and received an ack.
* circuits that are c_rend_joined are open, have heard from
- * bob, and are talking to him.
+ * the service, and are talking to it.
*/
/** Client-side circuit purpose: Normal circuit, with cpath. */
#define CIRCUIT_PURPOSE_C_GENERAL 5
-/** Client-side circuit purpose: at Alice, connecting to intro point. */
+/** Client-side circuit purpose: at the client, connecting to intro point. */
#define CIRCUIT_PURPOSE_C_INTRODUCING 6
-/** Client-side circuit purpose: at Alice, sent INTRODUCE1 to intro point,
+/** Client-side circuit purpose: at the client, sent INTRODUCE1 to intro point,
* waiting for ACK/NAK. */
#define CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT 7
-/** Client-side circuit purpose: at Alice, introduced and acked, closing. */
+/** Client-side circuit purpose: at the client, introduced and acked, closing.
+ */
#define CIRCUIT_PURPOSE_C_INTRODUCE_ACKED 8
-/** Client-side circuit purpose: at Alice, waiting for ack. */
+/** Client-side circuit purpose: at the client, waiting for ack. */
#define CIRCUIT_PURPOSE_C_ESTABLISH_REND 9
-/** Client-side circuit purpose: at Alice, waiting for Bob. */
+/** Client-side circuit purpose: at the client, waiting for the service. */
#define CIRCUIT_PURPOSE_C_REND_READY 10
-/** Client-side circuit purpose: at Alice, waiting for Bob, INTRODUCE
- * has been acknowledged. */
+/** Client-side circuit purpose: at the client, waiting for the service,
+ * INTRODUCE has been acknowledged. */
#define CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED 11
-/** Client-side circuit purpose: at Alice, rendezvous established. */
+/** Client-side circuit purpose: at the client, rendezvous established. */
#define CIRCUIT_PURPOSE_C_REND_JOINED 12
/** This circuit is used for build time measurement only */
#define CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT 13
#define CIRCUIT_PURPOSE_C_MAX_ 13
-/** Hidden-service-side circuit purpose: at Bob, waiting for introductions. */
+/** Hidden-service-side circuit purpose: at the service, waiting for
+ * introductions. */
#define CIRCUIT_PURPOSE_S_ESTABLISH_INTRO 14
-/** Hidden-service-side circuit purpose: at Bob, successfully established
- * intro. */
+/** Hidden-service-side circuit purpose: at the service, successfully
+ * established intro. */
#define CIRCUIT_PURPOSE_S_INTRO 15
-/** Hidden-service-side circuit purpose: at Bob, connecting to rend point. */
+/** Hidden-service-side circuit purpose: at the service, connecting to rend
+ * point. */
#define CIRCUIT_PURPOSE_S_CONNECT_REND 16
-/** Hidden-service-side circuit purpose: at Bob, rendezvous established. */
+/** Hidden-service-side circuit purpose: at the service, rendezvous
+ * established. */
#define CIRCUIT_PURPOSE_S_REND_JOINED 17
/** A testing circuit; not meant to be used for actual traffic. */
#define CIRCUIT_PURPOSE_TESTING 18
@@ -2147,6 +2153,11 @@ typedef struct {
* tests for it. */
unsigned int needs_retest_if_added:1;
+ /** True iff this router included "tunnelled-dir-server" in its descriptor,
+ * implying it accepts tunnelled directory requests, or it advertised
+ * dir_port > 0. */
+ unsigned int supports_tunnelled_dir_requests:1;
+
/** Tor can use this router for general positions in circuits; we got it
* from a directory server as usual, or we're an authority and a server
* uploaded it. */
@@ -2224,6 +2235,9 @@ typedef struct routerstatus_t {
* an exit node. */
unsigned int is_hs_dir:1; /**< True iff this router is a v2-or-later hidden
* service directory. */
+ unsigned int is_v2_dir:1; /** True iff this router publishes an open DirPort
+ * or it claims to accept tunnelled dir requests.
+ */
/** True iff we know version info for this router. (i.e., a "v" entry was
* included.) We'll replace all these with a big tor_version_t or a char[]
* if the number of traits we care about ever becomes incredibly big. */
@@ -2325,7 +2339,7 @@ typedef struct microdesc_t {
curve25519_public_key_t *onion_curve25519_pkey;
/** Ed25519 identity key, if included. */
ed25519_public_key_t *ed25519_identity_pkey;
- /** As routerinfo_t.ipv6_add */
+ /** As routerinfo_t.ipv6_addr */
tor_addr_t ipv6_addr;
/** As routerinfo_t.ipv6_orport */
uint16_t ipv6_orport;
@@ -2343,7 +2357,7 @@ typedef struct microdesc_t {
* Specifically, a node_t is a Tor router as we are using it: a router that
* we are considering for circuits, connections, and so on. A node_t is a
* thin wrapper around the routerstatus, routerinfo, and microdesc for a
- * single wrapper, and provides a consistent interface for all of them.
+ * single router, and provides a consistent interface for all of them.
*
* Also, a node_t has mutable state. While a routerinfo, a routerstatus,
* and a microdesc have[*] only the information read from a router
@@ -3886,9 +3900,11 @@ typedef struct {
* hibernate." */
/** How do we determine when our AccountingMax has been reached?
* "max" for when in or out reaches AccountingMax
- * "sum" for when in plus out reaches AccountingMax */
+ * "sum" for when in plus out reaches AccountingMax
+ * "in" for when in reaches AccountingMax
+ * "out" for when out reaches AccountingMax */
char *AccountingRule_option;
- enum { ACCT_MAX, ACCT_SUM } AccountingRule;
+ enum { ACCT_MAX, ACCT_SUM, ACCT_IN, ACCT_OUT } AccountingRule;
/** Base64-encoded hash of accepted passwords for the control system. */
config_line_t *HashedControlPassword;
@@ -3962,6 +3978,10 @@ typedef struct {
/** Should we fetch our dir info at the start of the consensus period? */
int FetchDirInfoExtraEarly;
+ int DirCache; /**< Cache all directory documents and accept requests via
+ * tunnelled dir conns from clients. If 1, enabled (default);
+ * If 0, disabled. */
+
char *VirtualAddrNetworkIPv4; /**< Address and mask to hand out for virtual
* MAPADDRESS requests for IPv4 addresses */
char *VirtualAddrNetworkIPv6; /**< Address and mask to hand out for virtual
diff --git a/src/or/relay.c b/src/or/relay.c
index ee2f041dbd..aea51a165b 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -833,7 +833,7 @@ connection_ap_process_end_not_open(
}
}
}
- /* check if he *ought* to have allowed it */
+ /* check if the exit *ought* to have allowed it */
adjust_exit_policy_from_exitpolicy_failure(circ,
conn,
diff --git a/src/or/rendclient.c b/src/or/rendclient.c
index dc05d6f2ed..b822295832 100644
--- a/src/or/rendclient.c
+++ b/src/or/rendclient.c
@@ -182,7 +182,7 @@ rend_client_send_introduction(origin_circuit_t *introcirc,
goto cleanup;
}
- /* first 20 bytes of payload are the hash of Bob's pk */
+ /* first 20 bytes of payload are the hash of the service's pk */
intro_key = NULL;
SMARTLIST_FOREACH(entry->parsed->intro_nodes, rend_intro_point_t *,
intro, {
@@ -1096,9 +1096,9 @@ rend_client_rendezvous_acked(origin_circuit_t *circ, const uint8_t *request,
circ->base_.timestamp_dirty = time(NULL);
/* From a path bias point of view, this circuit is now successfully used.
- * Waiting any longer opens us up to attacks from Bob. He could induce
- * Alice to attempt to connect to his hidden service and never reply
- * to her rend requests */
+ * Waiting any longer opens us up to attacks from malicious hidden services.
+ * They could induce the client to attempt to connect to their hidden
+ * service and never reply to the client's rend requests */
pathbias_mark_use_success(circ);
/* XXXX This is a pretty brute-force approach. It'd be better to
@@ -1110,7 +1110,7 @@ rend_client_rendezvous_acked(origin_circuit_t *circ, const uint8_t *request,
return 0;
}
-/** Bob sent us a rendezvous cell; join the circuits. */
+/** The service sent us a rendezvous cell; join the circuits. */
int
rend_client_receive_rendezvous(origin_circuit_t *circ, const uint8_t *request,
size_t request_len)
@@ -1135,7 +1135,8 @@ rend_client_receive_rendezvous(origin_circuit_t *circ, const uint8_t *request,
log_info(LD_REND,"Got RENDEZVOUS2 cell from hidden service.");
- /* first DH_KEY_LEN bytes are g^y from bob. Finish the dh handshake...*/
+ /* first DH_KEY_LEN bytes are g^y from the service. Finish the dh
+ * handshake...*/
tor_assert(circ->build_state);
tor_assert(circ->build_state->pending_final_cpath);
hop = circ->build_state->pending_final_cpath;
@@ -1164,7 +1165,7 @@ rend_client_receive_rendezvous(origin_circuit_t *circ, const uint8_t *request,
circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_C_REND_JOINED);
hop->state = CPATH_STATE_OPEN;
/* set the windows to default. these are the windows
- * that alice thinks bob has.
+ * that the client thinks the service has.
*/
hop->package_window = circuit_initial_package_window();
hop->deliver_window = CIRCWINDOW_START;
diff --git a/src/or/rendmid.c b/src/or/rendmid.c
index 2451acb514..cbfbcbe051 100644
--- a/src/or/rendmid.c
+++ b/src/or/rendmid.c
@@ -80,7 +80,7 @@ rend_mid_establish_intro(or_circuit_t *circ, const uint8_t *request,
goto err;
}
- /* The request is valid. First, compute the hash of Bob's PK.*/
+ /* The request is valid. First, compute the hash of the service's PK.*/
if (crypto_pk_get_digest(pk, pk_digest)<0) {
log_warn(LD_BUG, "Internal error: couldn't hash public key.");
goto err;
@@ -178,7 +178,8 @@ rend_mid_introduce(or_circuit_t *circ, const uint8_t *request,
base32_encode(serviceid, REND_SERVICE_ID_LEN_BASE32+1,
(char*)request, REND_SERVICE_ID_LEN);
- /* The first 20 bytes are all we look at: they have a hash of Bob's PK. */
+ /* The first 20 bytes are all we look at: they have a hash of the service's
+ * PK. */
intro_circ = circuit_get_intro_point((const uint8_t*)request);
if (!intro_circ) {
log_info(LD_REND,
@@ -202,7 +203,7 @@ rend_mid_introduce(or_circuit_t *circ, const uint8_t *request,
"Unable to send INTRODUCE2 cell to Tor client.");
goto err;
}
- /* And send an ack down Alice's circuit. Empty body means succeeded. */
+ /* And send an ack down the client's circuit. Empty body means succeeded. */
if (relay_send_command_from_edge(0,TO_CIRCUIT(circ),
RELAY_COMMAND_INTRODUCE_ACK,
NULL,0,NULL)) {
@@ -337,7 +338,7 @@ rend_mid_rendezvous(or_circuit_t *circ, const uint8_t *request,
circ->circuit_carries_hs_traffic_stats = 1;
}
- /* Send the RENDEZVOUS2 cell to Alice. */
+ /* Send the RENDEZVOUS2 cell to the client. */
if (relay_send_command_from_edge(0, TO_CIRCUIT(rend_circ),
RELAY_COMMAND_RENDEZVOUS2,
(char*)(request+REND_COOKIE_LEN),
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index 15d98bfde5..7471c6252f 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -1676,7 +1676,7 @@ rend_service_receive_introduction(origin_circuit_t *circuit,
/* help predict this next time */
rep_hist_note_used_internal(now, circ_needs_uptime, 1);
- /* Launch a circuit to alice's chosen rendezvous point.
+ /* Launch a circuit to the client's chosen rendezvous point.
*/
for (i=0;i<MAX_REND_FAILURES;i++) {
int flags = CIRCLAUNCH_NEED_CAPACITY | CIRCLAUNCH_IS_INTERNAL;
@@ -2970,7 +2970,7 @@ rend_service_rendezvous_has_opened(origin_circuit_t *circuit)
/* Append the cpath entry. */
hop->state = CPATH_STATE_OPEN;
/* set the windows to default. these are the windows
- * that bob thinks alice has.
+ * that the service thinks the client has.
*/
hop->package_window = circuit_initial_package_window();
hop->deliver_window = CIRCWINDOW_START;
diff --git a/src/or/router.c b/src/or/router.c
index d4131992aa..c4a805ff39 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -1099,43 +1099,47 @@ check_whether_dirport_reachable(void)
can_reach_dir_port;
}
-/** Look at a variety of factors, and return 0 if we don't want to
- * advertise the fact that we have a DirPort open. Else return the
- * DirPort we want to advertise.
- *
- * Log a helpful message if we change our mind about whether to publish
- * a DirPort.
+/** The lower threshold of remaining bandwidth required to advertise (or
+ * automatically provide) directory services */
+/* XXX Should this be increased? */
+#define MIN_BW_TO_ADVERTISE_DIRSERVER 51200
+
+/** Return true iff we have enough configured bandwidth to cache directory
+ * information. */
+static int
+router_has_bandwidth_to_be_dirserver(const or_options_t *options)
+{
+ if (options->BandwidthRate < MIN_BW_TO_ADVERTISE_DIRSERVER) {
+ return 0;
+ }
+ if (options->RelayBandwidthRate > 0 &&
+ options->RelayBandwidthRate < MIN_BW_TO_ADVERTISE_DIRSERVER) {
+ return 0;
+ }
+ return 1;
+}
+
+/** Helper: Return 1 if we have sufficient resources for serving directory
+ * requests, return 0 otherwise.
+ * dir_port is either 0 or the configured DirPort number.
+ * If AccountingMax is set less than our advertised bandwidth, then don't
+ * serve requests. Likewise, if our advertised bandwidth is less than
+ * MIN_BW_TO_ADVERTISE_DIRSERVER, don't bother trying to serve requests.
*/
static int
-decide_to_advertise_dirport(const or_options_t *options, uint16_t dir_port)
+router_should_be_directory_server(const or_options_t *options, int dir_port)
{
static int advertising=1; /* start out assuming we will advertise */
int new_choice=1;
const char *reason = NULL;
- /* Section one: reasons to publish or not publish that aren't
- * worth mentioning to the user, either because they're obvious
- * or because they're normal behavior. */
-
- if (!dir_port) /* short circuit the rest of the function */
- return 0;
- if (authdir_mode(options)) /* always publish */
- return dir_port;
- if (net_is_disabled())
- return 0;
- if (!check_whether_dirport_reachable())
- return 0;
- if (!router_get_advertised_dir_port(options, dir_port))
- return 0;
-
- /* Section two: reasons to publish or not publish that the user
- * might find surprising. These are generally config options that
- * make us choose not to publish. */
-
- if (accounting_is_enabled(options)) {
+ if (accounting_is_enabled(options) &&
+ get_options()->AccountingRule != ACCT_IN) {
/* Don't spend bytes for directory traffic if we could end up hibernating,
* but allow DirPort otherwise. Some people set AccountingMax because
- * they're confused or to get statistics. */
+ * they're confused or to get statistics. Directory traffic has a much
+ * larger effect on output than input so there is no reason to turn it
+ * off if using AccountingRule in. */
int interval_length = accounting_get_interval_length();
uint32_t effective_bw = get_effective_bwrate(options);
uint64_t acc_bytes;
@@ -1158,10 +1162,7 @@ decide_to_advertise_dirport(const or_options_t *options, uint16_t dir_port)
new_choice = 0;
reason = "AccountingMax enabled";
}
-#define MIN_BW_TO_ADVERTISE_DIRPORT 51200
- } else if (options->BandwidthRate < MIN_BW_TO_ADVERTISE_DIRPORT ||
- (options->RelayBandwidthRate > 0 &&
- options->RelayBandwidthRate < MIN_BW_TO_ADVERTISE_DIRPORT)) {
+ } else if (! router_has_bandwidth_to_be_dirserver(options)) {
/* if we're advertising a small amount */
new_choice = 0;
reason = "BandwidthRate under 50KB";
@@ -1169,15 +1170,63 @@ decide_to_advertise_dirport(const or_options_t *options, uint16_t dir_port)
if (advertising != new_choice) {
if (new_choice == 1) {
- log_notice(LD_DIR, "Advertising DirPort as %d", dir_port);
+ if (dir_port > 0)
+ log_notice(LD_DIR, "Advertising DirPort as %d", dir_port);
+ else
+ log_notice(LD_DIR, "Advertising directory service support");
} else {
tor_assert(reason);
- log_notice(LD_DIR, "Not advertising DirPort (Reason: %s)", reason);
+ log_notice(LD_DIR, "Not advertising Dir%s (Reason: %s)",
+ dir_port ? "Port" : "ectory Service support", reason);
}
advertising = new_choice;
}
- return advertising ? dir_port : 0;
+ return advertising;
+}
+
+/** Return 1 if we are configured to accept either relay or directory requests
+ * from clients and we aren't at risk of exceeding our bandwidth limits, thus
+ * we should be a directory server. If not, return 0.
+ */
+int
+dir_server_mode(const or_options_t *options)
+{
+ if (!options->DirCache)
+ return 0;
+ return options->DirPort_set ||
+ (server_mode(options) && router_has_bandwidth_to_be_dirserver(options));
+}
+
+/** Look at a variety of factors, and return 0 if we don't want to
+ * advertise the fact that we have a DirPort open, else return the
+ * DirPort we want to advertise.
+ *
+ * Log a helpful message if we change our mind about whether to publish
+ * a DirPort.
+ */
+static int
+decide_to_advertise_dirport(const or_options_t *options, uint16_t dir_port)
+{
+ /* Part one: reasons to publish or not publish that aren't
+ * worth mentioning to the user, either because they're obvious
+ * or because they're normal behavior. */
+
+ if (!dir_port) /* short circuit the rest of the function */
+ return 0;
+ if (authdir_mode(options)) /* always publish */
+ return dir_port;
+ if (net_is_disabled())
+ return 0;
+ if (!check_whether_dirport_reachable())
+ return 0;
+ if (!router_get_advertised_dir_port(options, dir_port))
+ return 0;
+
+ /* Part two: reasons to publish or not publish that the user
+ * might find surprising. router_should_be_directory_server()
+ * considers config options that make us choose not to publish. */
+ return router_should_be_directory_server(options, dir_port) ? dir_port : 0;
}
/** Allocate and return a new extend_info_t that can be used to build
@@ -1269,7 +1318,8 @@ router_orport_found_reachable(void)
char *address = tor_dup_ip(me->addr);
log_notice(LD_OR,"Self-testing indicates your ORPort is reachable from "
"the outside. Excellent.%s",
- get_options()->PublishServerDescriptor_ != NO_DIRINFO ?
+ get_options()->PublishServerDescriptor_ != NO_DIRINFO
+ && check_whether_dirport_reachable() ?
" Publishing server descriptor." : "");
can_reach_or_port = 1;
mark_my_descriptor_dirty("ORPort found reachable");
@@ -1293,7 +1343,10 @@ router_dirport_found_reachable(void)
if (!can_reach_dir_port && me) {
char *address = tor_dup_ip(me->addr);
log_notice(LD_DIRSERV,"Self-testing indicates your DirPort is reachable "
- "from the outside. Excellent.");
+ "from the outside. Excellent.%s",
+ get_options()->PublishServerDescriptor_ != NO_DIRINFO
+ && check_whether_orport_reachable() ?
+ " Publishing server descriptor." : "");
can_reach_dir_port = 1;
if (decide_to_advertise_dirport(get_options(), me->dir_port)) {
mark_my_descriptor_dirty("DirPort found reachable");
@@ -1496,7 +1549,8 @@ proxy_mode(const or_options_t *options)
* and
* - We have ORPort set
* and
- * - We believe we are reachable from the outside; or
+ * - We believe both our ORPort and DirPort (if present) are reachable from
+ * the outside; or
* - We are an authoritative directory server.
*/
static int
@@ -1515,7 +1569,7 @@ decide_if_publishable_server(void)
if (!router_get_advertised_or_port(options))
return 0;
- return check_whether_orport_reachable();
+ return check_whether_orport_reachable() && check_whether_dirport_reachable();
}
/** Initiate server descriptor upload as reasonable (if server is publishable,
@@ -1867,6 +1921,8 @@ router_build_fresh_descriptor(routerinfo_t **r, extrainfo_t **e)
ri->addr = addr;
ri->or_port = router_get_advertised_or_port(options);
ri->dir_port = router_get_advertised_dir_port(options, 0);
+ ri->supports_tunnelled_dir_requests = dir_server_mode(options) &&
+ router_should_be_directory_server(options, ri->dir_port);
ri->cache_info.published_on = time(NULL);
ri->onion_pkey = crypto_pk_dup_key(get_onion_key()); /* must invoke from
* main thread */
@@ -2320,7 +2376,7 @@ router_new_address_suggestion(const char *suggestion,
if (tor_addr_eq(&d_conn->base_.addr, &addr)) {
/* Don't believe anybody who says our IP is their IP. */
log_debug(LD_DIR, "A directory server told us our IP address is %s, "
- "but he's just reporting his own IP address. Ignoring.",
+ "but they are just reporting their own IP address. Ignoring.",
suggestion);
return;
}
@@ -2643,6 +2699,10 @@ router_dump_router_to_string(routerinfo_t *router,
tor_free(p6);
}
+ if (router->supports_tunnelled_dir_requests) {
+ smartlist_add(chunks, tor_strdup("tunnelled-dir-server\n"));
+ }
+
/* Sign the descriptor with Ed25519 */
if (emit_ed_sigs) {
smartlist_add(chunks, tor_strdup("router-sig-ed25519 "));
diff --git a/src/or/router.h b/src/or/router.h
index a4b3e9616c..ca590e3217 100644
--- a/src/or/router.h
+++ b/src/or/router.h
@@ -41,6 +41,7 @@ int init_keys_client(void);
int check_whether_orport_reachable(void);
int check_whether_dirport_reachable(void);
+int dir_server_mode(const or_options_t *options);
void consider_testing_reachability(int test_or, int test_dir);
void router_orport_found_reachable(void);
void router_dirport_found_reachable(void);
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 9b8885e9c9..f6662705dc 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -68,8 +68,6 @@ typedef struct cert_list_t cert_list_t;
static int compute_weighted_bandwidths(const smartlist_t *sl,
bandwidth_weight_rule_t rule,
u64_dbl_t **bandwidths_out);
-static const routerstatus_t *router_pick_directory_server_impl(
- dirinfo_type_t auth, int flags, int *n_busy_out);
static const routerstatus_t *router_pick_trusteddirserver_impl(
const smartlist_t *sourcelist, dirinfo_type_t auth,
int flags, int *n_busy_out);
@@ -1654,7 +1652,7 @@ router_skip_dir_reachability(const or_options_t *options, int try_ip_pref)
* directories that we excluded for no other reason than
* PDS_NO_EXISTING_SERVERDESC_FETCH or PDS_NO_EXISTING_MICRODESC_FETCH.
*/
-static const routerstatus_t *
+STATIC const routerstatus_t *
router_pick_directory_server_impl(dirinfo_type_t type, int flags,
int *n_busy_out)
{
@@ -1697,7 +1695,7 @@ router_pick_directory_server_impl(dirinfo_type_t type, int flags,
if (!status)
continue;
- if (!node->is_running || !status->dir_port || !node->is_valid)
+ if (!node->is_running || !node_is_dir(node) || !node->is_valid)
continue;
if (requireother && router_digest_is_me(node->identity))
continue;
@@ -3424,7 +3422,11 @@ routerlist_reparse_old(routerlist_t *rl, signed_descriptor_t *sd)
return ri;
}
-/** Free all memory held by the routerlist module. */
+/** Free all memory held by the routerlist module.
+ * Note: Calling routerlist_free_all() should always be paired with
+ * a call to nodelist_free_all(). These should only be called during
+ * cleanup.
+ */
void
routerlist_free_all(void)
{
@@ -4624,13 +4626,20 @@ static int
max_dl_per_request(const or_options_t *options, int purpose)
{
/* Since squid does not like URLs >= 4096 bytes we limit it to 96.
- * 4096 - strlen(http://255.255.255.255/tor/server/d/.z) == 4058
- * 4058/41 (40 for the hash and 1 for the + that separates them) => 98
+ * 4096 - strlen(http://[ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]:65535
+ * /tor/server/d/.z) == 4026
+ * 4026/41 (40 for the hash and 1 for the + that separates them) => 98
* So use 96 because it's a nice number.
+ *
+ * For microdescriptors, the calculation is
+ * 4096 - strlen(http://[ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff]:65535
+ * /tor/micro/d/.z) == 4027
+ * 4027/44 (43 for the hash and 1 for the - that separates them) => 91
+ * So use 90 because it's a nice number.
*/
int max = 96;
if (purpose == DIR_PURPOSE_FETCH_MICRODESC) {
- max = 92;
+ max = 90;
}
/* If we're going to tunnel our connections, we can ask for a lot more
* in a request. */
@@ -5088,7 +5097,9 @@ router_differences_are_cosmetic(const routerinfo_t *r1, const routerinfo_t *r2)
(r1->contact_info && r2->contact_info &&
strcasecmp(r1->contact_info, r2->contact_info)) ||
r1->is_hibernating != r2->is_hibernating ||
- cmp_addr_policies(r1->exit_policy, r2->exit_policy))
+ cmp_addr_policies(r1->exit_policy, r2->exit_policy) ||
+ (r1->supports_tunnelled_dir_requests !=
+ r2->supports_tunnelled_dir_requests))
return 0;
if ((r1->declared_family == NULL) != (r2->declared_family == NULL))
return 0;
diff --git a/src/or/routerlist.h b/src/or/routerlist.h
index ac286d904f..483dd06039 100644
--- a/src/or/routerlist.h
+++ b/src/or/routerlist.h
@@ -234,6 +234,9 @@ STATIC int choose_array_element_by_weight(const u64_dbl_t *entries,
int n_entries);
STATIC void scale_array_elements_to_u64(u64_dbl_t *entries, int n_entries,
uint64_t *total_out);
+STATIC const routerstatus_t *router_pick_directory_server_impl(
+ dirinfo_type_t auth, int flags,
+ int *n_busy_out);
MOCK_DECL(int, router_descriptor_is_older_than, (const routerinfo_t *router,
int seconds));
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index 3f794ad902..fafba96e95 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -35,8 +35,9 @@
/****************************************************************************/
/** Enumeration of possible token types. The ones starting with K_ correspond
- * to directory 'keywords'. ERR_ is an error in the tokenizing process, EOF_
- * is an end-of-file marker, and NIL_ is used to encode not-a-token.
+ * to directory 'keywords'. A_ is for an annotation, R or C is related to
+ * hidden services, ERR_ is an error in the tokenizing process, EOF_ is an
+ * end-of-file marker, and NIL_ is used to encode not-a-token.
*/
typedef enum {
K_ACCEPT = 0,
@@ -125,6 +126,7 @@ typedef enum {
K_DIR_KEY_CERTIFICATION,
K_DIR_KEY_CROSSCERT,
K_DIR_ADDRESS,
+ K_DIR_TUNNELLED,
K_VOTE_STATUS,
K_VALID_AFTER,
@@ -318,6 +320,7 @@ static token_rule_t routerdesc_token_table[] = {
T0N("opt", K_OPT, CONCAT_ARGS, OBJ_OK ),
T1( "bandwidth", K_BANDWIDTH, GE(3), NO_OBJ ),
A01("@purpose", A_PURPOSE, GE(1), NO_OBJ ),
+ T01("tunnelled-dir-server",K_DIR_TUNNELLED, NO_ARGS, NO_OBJ ),
END_OF_TABLE
};
@@ -1609,6 +1612,12 @@ router_parse_entry_from_string(const char *s, const char *end,
router->wants_to_be_hs_dir = 1;
}
+ /* This router accepts tunnelled directory requests via begindir if it has
+ * an open dirport or it included "tunnelled-dir-server". */
+ if (find_opt_by_keyword(tokens, K_DIR_TUNNELLED) || router->dir_port > 0) {
+ router->supports_tunnelled_dir_requests = 1;
+ }
+
tok = find_by_keyword(tokens, K_ROUTER_SIGNATURE);
note_crypto_pk_op(VERIFY_RTR);
#ifdef COUNT_DISTINCT_DIGESTS
@@ -2294,6 +2303,8 @@ routerstatus_parse_entry_from_string(memarea_t *area,
rs->is_unnamed = 1;
} else if (!strcmp(tok->args[i], "HSDir")) {
rs->is_hs_dir = 1;
+ } else if (!strcmp(tok->args[i], "V2Dir")) {
+ rs->is_v2_dir = 1;
}
}
}
diff --git a/src/or/status.c b/src/or/status.c
index 8f7be0aa3c..69d10721d2 100644
--- a/src/or/status.c
+++ b/src/or/status.c
@@ -164,24 +164,38 @@ log_accounting(const time_t now, const or_options_t *options)
or_state_t *state = get_or_state();
char *acc_rcvd = bytes_to_usage(state->AccountingBytesReadInInterval);
char *acc_sent = bytes_to_usage(state->AccountingBytesWrittenInInterval);
+ char *acc_used = bytes_to_usage(get_accounting_bytes());
uint64_t acc_bytes = options->AccountingMax;
char *acc_max;
time_t interval_end = accounting_get_end_time();
char end_buf[ISO_TIME_LEN + 1];
char *remaining = NULL;
- if (options->AccountingRule == ACCT_SUM)
- acc_bytes *= 2;
acc_max = bytes_to_usage(acc_bytes);
format_local_iso_time(end_buf, interval_end);
remaining = secs_to_uptime(interval_end - now);
+ const char *acc_rule;
+ switch (options->AccountingRule) {
+ case ACCT_MAX: acc_rule = "max";
+ break;
+ case ACCT_SUM: acc_rule = "sum";
+ break;
+ case ACCT_OUT: acc_rule = "out";
+ break;
+ case ACCT_IN: acc_rule = "in";
+ break;
+ default: acc_rule = "max";
+ break;
+ }
+
log_notice(LD_HEARTBEAT, "Heartbeat: Accounting enabled. "
- "Sent: %s / %s, Received: %s / %s. The "
+ "Sent: %s, Received: %s, Used: %s / %s, Rule: %s. The "
"current accounting interval ends on %s, in %s.",
- acc_sent, acc_max, acc_rcvd, acc_max, end_buf, remaining);
+ acc_sent, acc_rcvd, acc_used, acc_max, acc_rule, end_buf, remaining);
tor_free(acc_rcvd);
tor_free(acc_sent);
+ tor_free(acc_used);
tor_free(acc_max);
tor_free(remaining);
}
diff --git a/src/or/transports.c b/src/or/transports.c
index 81b8db2508..5a3af85be8 100644
--- a/src/or/transports.c
+++ b/src/or/transports.c
@@ -1100,7 +1100,7 @@ parse_smethod_line(const char *line, managed_proxy_t *mp)
smartlist_add(mp->transports, transport);
- /* For now, notify the user so that he knows where the server
+ /* For now, notify the user so that they know where the server
transport is listening. */
log_info(LD_CONFIG, "Server transport %s at %s:%d.",
method_name, address, (int)port);