summaryrefslogtreecommitdiff
path: root/src/or
diff options
context:
space:
mode:
Diffstat (limited to 'src/or')
-rw-r--r--src/or/circuitbuild.c81
-rw-r--r--src/or/circuitbuild.h9
-rw-r--r--src/or/circuitlist.c10
-rw-r--r--src/or/circuituse.c55
-rw-r--r--src/or/circuituse.h2
-rw-r--r--src/or/config.c104
-rw-r--r--src/or/connection.c136
-rw-r--r--src/or/connection_edge.c55
-rw-r--r--src/or/connection_edge.h1
-rw-r--r--src/or/connection_or.c13
-rw-r--r--src/or/control.c124
-rw-r--r--src/or/control.h2
-rw-r--r--src/or/directory.c40
-rw-r--r--src/or/dirserv.c23
-rw-r--r--src/or/dirvote.c59
-rw-r--r--src/or/eventdns.c4
-rw-r--r--src/or/main.c9
-rw-r--r--src/or/microdesc.c11
-rw-r--r--src/or/networkstatus.c42
-rw-r--r--src/or/onion.c4
-rw-r--r--src/or/or.h21
-rw-r--r--src/or/relay.c2
-rw-r--r--src/or/rendclient.c8
-rw-r--r--src/or/rendcommon.c8
-rw-r--r--src/or/rendmid.c2
-rw-r--r--src/or/rendservice.c16
-rw-r--r--src/or/rephist.c4
-rw-r--r--src/or/router.c44
-rw-r--r--src/or/router.h3
-rw-r--r--src/or/routerlist.c87
-rw-r--r--src/or/routerparse.c33
31 files changed, 707 insertions, 305 deletions
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index 0e033a5899..860cd27567 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -559,7 +559,9 @@ circuit_build_times_create_histogram(circuit_build_times_t *cbt,
* Return the Pareto start-of-curve parameter Xm.
*
* Because we are not a true Pareto curve, we compute this as the
- * weighted average of the N=3 most frequent build time bins.
+ * weighted average of the N most frequent build time bins. N is either
+ * 1 if we don't have enough circuit build time data collected, or
+ * determined by the consensus parameter cbtnummodes (default 3).
*/
static build_time_t
circuit_build_times_get_xm(circuit_build_times_t *cbt)
@@ -572,6 +574,9 @@ circuit_build_times_get_xm(circuit_build_times_t *cbt)
int n=0;
int num_modes = circuit_build_times_default_num_xm_modes();
+ tor_assert(nbins > 0);
+ tor_assert(num_modes > 0);
+
// Only use one mode if < 1000 buildtimes. Not enough data
// for multiple.
if (cbt->total_build_times < CBT_NCIRCUITS_TO_OBSERVE)
@@ -579,6 +584,7 @@ circuit_build_times_get_xm(circuit_build_times_t *cbt)
nth_max_bin = (build_time_t*)tor_malloc_zero(num_modes*sizeof(build_time_t));
+ /* Determine the N most common build times */
for (i = 0; i < nbins; i++) {
if (histogram[i] >= histogram[nth_max_bin[0]]) {
nth_max_bin[0] = i;
@@ -600,6 +606,10 @@ circuit_build_times_get_xm(circuit_build_times_t *cbt)
histogram[nth_max_bin[n]]);
}
+ /* The following assert is safe, because we don't get called when we
+ * haven't observed at least CBT_MIN_MIN_CIRCUITS_TO_OBSERVE circuits. */
+ tor_assert(bin_counts > 0);
+
ret /= bin_counts;
tor_free(histogram);
tor_free(nth_max_bin);
@@ -1813,7 +1823,7 @@ circuit_n_conn_done(or_connection_t *or_conn, int status)
continue;
} else {
/* We expected a key. See if it's the right one. */
- if (memcmp(or_conn->identity_digest,
+ if (tor_memneq(or_conn->identity_digest,
circ->n_hop->identity_digest, DIGEST_LEN))
continue;
}
@@ -2221,7 +2231,7 @@ circuit_extend(cell_t *cell, circuit_t *circ)
/* Next, check if we're being asked to connect to the hop that the
* extend cell came from. There isn't any reason for that, and it can
* assist circular-path attacks. */
- if (!memcmp(id_digest, TO_OR_CIRCUIT(circ)->p_conn->identity_digest,
+ if (tor_memeq(id_digest, TO_OR_CIRCUIT(circ)->p_conn->identity_digest,
DIGEST_LEN)) {
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
"Client asked me to extend back to the previous hop.");
@@ -3502,7 +3512,7 @@ static INLINE entry_guard_t *
is_an_entry_guard(const char *digest)
{
SMARTLIST_FOREACH(entry_guards, entry_guard_t *, entry,
- if (!memcmp(digest, entry->identity, DIGEST_LEN))
+ if (tor_memeq(digest, entry->identity, DIGEST_LEN))
return entry;
);
return NULL;
@@ -3834,7 +3844,7 @@ entry_guard_register_connect_status(const char *digest, int succeeded,
SMARTLIST_FOREACH(entry_guards, entry_guard_t *, e,
{
- if (!memcmp(e->identity, digest, DIGEST_LEN)) {
+ if (tor_memeq(e->identity, digest, DIGEST_LEN)) {
entry = e;
idx = e_sl_idx;
break;
@@ -4461,6 +4471,9 @@ typedef struct {
tor_addr_t addr;
/** TLS port for the bridge. */
uint16_t port;
+ /** Boolean: We are re-parsing our bridge list, and we are going to remove
+ * this one if we don't find it in the list of configured bridges. */
+ unsigned marked_for_removal : 1;
/** Expected identity digest, or all zero bytes if we don't know what the
* digest should be. */
char identity[DIGEST_LEN];
@@ -4469,11 +4482,39 @@ typedef struct {
} bridge_info_t;
/** A list of configured bridges. Whenever we actually get a descriptor
- * for one, we add it as an entry guard. */
+ * for one, we add it as an entry guard. Note that the order of bridges
+ * in this list does not necessarily correspond to the order of bridges
+ * in the torrc. */
static smartlist_t *bridge_list = NULL;
-/** Initialize the bridge list to empty, creating it if needed. */
+/** Mark every entry of the bridge list to be removed on our next call to
+ * sweep_bridge_list unless it has first been un-marked. */
void
+mark_bridge_list(void)
+{
+ if (!bridge_list)
+ bridge_list = smartlist_create();
+ SMARTLIST_FOREACH(bridge_list, bridge_info_t *, b,
+ b->marked_for_removal = 1);
+}
+
+/** Remove every entry of the bridge list that was marked with
+ * mark_bridge_list if it has not subsequently been un-marked. */
+void
+sweep_bridge_list(void)
+{
+ if (!bridge_list)
+ bridge_list = smartlist_create();
+ SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, b) {
+ if (b->marked_for_removal) {
+ SMARTLIST_DEL_CURRENT(bridge_list, b);
+ tor_free(b);
+ }
+ } SMARTLIST_FOREACH_END(b);
+}
+
+/** Initialize the bridge list to empty, creating it if needed. */
+static void
clear_bridge_list(void)
{
if (!bridge_list)
@@ -4486,7 +4527,8 @@ clear_bridge_list(void)
* (either by comparing keys if possible, else by comparing addr/port).
* Else return NULL. */
static bridge_info_t *
-get_configured_bridge_by_addr_port_digest(tor_addr_t *addr, uint16_t port,
+get_configured_bridge_by_addr_port_digest(const tor_addr_t *addr,
+ uint16_t port,
const char *digest)
{
if (!bridge_list)
@@ -4497,7 +4539,7 @@ get_configured_bridge_by_addr_port_digest(tor_addr_t *addr, uint16_t port,
!tor_addr_compare(&bridge->addr, addr, CMP_EXACT) &&
bridge->port == port)
return bridge;
- if (!memcmp(bridge->identity, digest, DIGEST_LEN))
+ if (tor_memeq(bridge->identity, digest, DIGEST_LEN))
return bridge;
}
SMARTLIST_FOREACH_END(bridge);
@@ -4527,7 +4569,8 @@ routerinfo_is_a_configured_bridge(routerinfo_t *ri)
* If it was a bridge, and we still don't know its digest, record it.
*/
void
-learned_router_identity(tor_addr_t *addr, uint16_t port, const char *digest)
+learned_router_identity(const tor_addr_t *addr, uint16_t port,
+ const char *digest)
{
bridge_info_t *bridge =
get_configured_bridge_by_addr_port_digest(addr, port, digest);
@@ -4539,11 +4582,20 @@ learned_router_identity(tor_addr_t *addr, uint16_t port, const char *digest)
}
/** Remember a new bridge at <b>addr</b>:<b>port</b>. If <b>digest</b>
- * is set, it tells us the identity key too. */
+ * is set, it tells us the identity key too. If we already had the
+ * bridge in our list, unmark it, and don't actually add anything new. */
void
-bridge_add_from_config(const tor_addr_t *addr, uint16_t port, char *digest)
+bridge_add_from_config(const tor_addr_t *addr, uint16_t port,
+ const char *digest)
{
- bridge_info_t *b = tor_malloc_zero(sizeof(bridge_info_t));
+ bridge_info_t *b;
+
+ if ((b = get_configured_bridge_by_addr_port_digest(addr, port, digest))) {
+ b->marked_for_removal = 0;
+ return;
+ }
+
+ b = tor_malloc_zero(sizeof(bridge_info_t));
tor_addr_copy(&b->addr, addr);
b->port = port;
if (digest)
@@ -4551,6 +4603,7 @@ bridge_add_from_config(const tor_addr_t *addr, uint16_t port, char *digest)
b->fetch_status.schedule = DL_SCHED_BRIDGE;
if (!bridge_list)
bridge_list = smartlist_create();
+
smartlist_add(bridge_list, b);
}
@@ -4578,7 +4631,7 @@ find_bridge_by_digest(const char *digest)
{
SMARTLIST_FOREACH(bridge_list, bridge_info_t *, bridge,
{
- if (!memcmp(bridge->identity, digest, DIGEST_LEN))
+ if (tor_memeq(bridge->identity, digest, DIGEST_LEN))
return bridge;
});
return NULL;
diff --git a/src/or/circuitbuild.h b/src/or/circuitbuild.h
index af24931878..0e673e1c05 100644
--- a/src/or/circuitbuild.h
+++ b/src/or/circuitbuild.h
@@ -62,12 +62,13 @@ int getinfo_helper_entry_guards(control_connection_t *conn,
const char *question, char **answer,
const char **errmsg);
-void clear_bridge_list(void);
+void mark_bridge_list(void);
+void sweep_bridge_list(void);
int routerinfo_is_a_configured_bridge(routerinfo_t *ri);
-void
-learned_router_identity(tor_addr_t *addr, uint16_t port, const char *digest);
+void learned_router_identity(const tor_addr_t *addr, uint16_t port,
+ const char *digest);
void bridge_add_from_config(const tor_addr_t *addr, uint16_t port,
- char *digest);
+ const char *digest);
void retry_bridge_descriptor_fetch_directly(const char *digest);
void fetch_bridge_descriptors(or_options_t *options, time_t now);
void learned_bridge_descriptor(routerinfo_t *ri, int from_cache);
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index 33dc8f09ad..8ec46186d9 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -256,7 +256,7 @@ circuit_get_all_pending_on_or_conn(smartlist_t *out, or_connection_t *or_conn)
continue;
} else {
/* We expected a key. See if it's the right one. */
- if (memcmp(or_conn->identity_digest,
+ if (tor_memneq(or_conn->identity_digest,
circ->n_hop->identity_digest, DIGEST_LEN))
continue;
}
@@ -719,7 +719,7 @@ circuit_dump_by_conn(connection_t *conn, int severity)
tor_addr_eq(&circ->n_hop->addr, &conn->addr) &&
circ->n_hop->port == conn->port &&
conn->type == CONN_TYPE_OR &&
- !memcmp(TO_OR_CONN(conn)->identity_digest,
+ tor_memeq(TO_OR_CONN(conn)->identity_digest,
circ->n_hop->identity_digest, DIGEST_LEN)) {
circuit_dump_details(severity, circ, conn->conn_array_index,
(circ->state == CIRCUIT_STATE_OPEN &&
@@ -913,7 +913,7 @@ circuit_get_next_by_pk_and_purpose(origin_circuit_t *start,
if (!digest)
return TO_ORIGIN_CIRCUIT(circ);
else if (TO_ORIGIN_CIRCUIT(circ)->rend_data &&
- !memcmp(TO_ORIGIN_CIRCUIT(circ)->rend_data->rend_pk_digest,
+ tor_memeq(TO_ORIGIN_CIRCUIT(circ)->rend_data->rend_pk_digest,
digest, DIGEST_LEN))
return TO_ORIGIN_CIRCUIT(circ);
}
@@ -931,7 +931,7 @@ circuit_get_by_rend_token_and_purpose(uint8_t purpose, const char *token,
for (circ = global_circuitlist; circ; circ = circ->next) {
if (! circ->marked_for_close &&
circ->purpose == purpose &&
- ! memcmp(TO_OR_CIRCUIT(circ)->rend_token, token, len))
+ tor_memeq(TO_OR_CIRCUIT(circ)->rend_token, token, len))
return TO_OR_CIRCUIT(circ);
}
return NULL;
@@ -1008,7 +1008,7 @@ circuit_find_to_cannibalize(uint8_t purpose, extend_info_t *info,
routerinfo_t *ri1 = router_get_by_digest(info->identity_digest);
do {
routerinfo_t *ri2;
- if (!memcmp(hop->extend_info->identity_digest,
+ if (tor_memeq(hop->extend_info->identity_digest,
info->identity_digest, DIGEST_LEN))
goto next;
if (ri1 &&
diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index fbe2e459a5..7289aa5c11 100644
--- a/src/or/circuituse.c
+++ b/src/or/circuituse.c
@@ -108,7 +108,7 @@ circuit_is_acceptable(circuit_t *circ, edge_connection_t *conn,
char digest[DIGEST_LEN];
if (hexdigest_to_digest(conn->chosen_exit_name, digest) < 0)
return 0; /* broken digest, we don't want it */
- if (memcmp(digest, build_state->chosen_exit->identity_digest,
+ if (tor_memneq(digest, build_state->chosen_exit->identity_digest,
DIGEST_LEN))
return 0; /* this is a circuit to somewhere else */
if (tor_digest_is_zero(digest)) {
@@ -1416,7 +1416,7 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
* a bad sign: we should tell the user. */
if (conn->num_circuits_launched < NUM_CIRCUITS_LAUNCHED_THRESHOLD &&
++conn->num_circuits_launched == NUM_CIRCUITS_LAUNCHED_THRESHOLD)
- log_warn(LD_BUG, "The application request to %s:%d has launched "
+ log_info(LD_CIRC, "The application request to %s:%d has launched "
"%d circuits without finding one it likes.",
escaped_safe_str_client(conn->socks_request->address),
conn->socks_request->port,
@@ -1485,15 +1485,35 @@ link_apconn_to_circ(edge_connection_t *apconn, origin_circuit_t *circ,
}
}
-/** If an exit wasn't specifically chosen, save the history for future
- * use. */
+/** Return true iff <b>address</b> is matched by one of the entries in
+ * TrackHostExits. */
+int
+hostname_in_track_host_exits(or_options_t *options, const char *address)
+{
+ if (!options->TrackHostExits)
+ return 0;
+ SMARTLIST_FOREACH_BEGIN(options->TrackHostExits, const char *, cp) {
+ if (cp[0] == '.') { /* match end */
+ if (cp[1] == '\0' ||
+ !strcasecmpend(address, cp) ||
+ !strcasecmp(address, &cp[1]))
+ return 1;
+ } else if (strcasecmp(cp, address) == 0) {
+ return 1;
+ }
+ } SMARTLIST_FOREACH_END(cp);
+ return 0;
+}
+
+/** If an exit wasn't explicitly specified for <b>conn</b>, consider saving
+ * the exit that we *did* choose for use by future connections to
+ * <b>conn</b>'s destination.
+ */
static void
consider_recording_trackhost(edge_connection_t *conn, origin_circuit_t *circ)
{
- int found_needle = 0;
or_options_t *options = get_options();
- size_t len;
- char *new_address;
+ char *new_address = NULL;
char fp[HEX_DIGEST_LEN+1];
/* Search the addressmap for this conn's destination. */
@@ -1503,18 +1523,8 @@ consider_recording_trackhost(edge_connection_t *conn, origin_circuit_t *circ)
options->TrackHostExitsExpire))
return; /* nothing to track, or already mapped */
- SMARTLIST_FOREACH(options->TrackHostExits, const char *, cp, {
- if (cp[0] == '.') { /* match end */
- if (cp[1] == '\0' ||
- !strcasecmpend(conn->socks_request->address, cp) ||
- !strcasecmp(conn->socks_request->address, &cp[1]))
- found_needle = 1;
- } else if (strcasecmp(cp, conn->socks_request->address) == 0) {
- found_needle = 1;
- }
- });
-
- if (!found_needle || !circ->build_state->chosen_exit)
+ if (!hostname_in_track_host_exits(options, conn->socks_request->address) ||
+ !circ->build_state->chosen_exit)
return;
/* write down the fingerprint of the chosen exit, not the nickname,
@@ -1523,12 +1533,7 @@ consider_recording_trackhost(edge_connection_t *conn, origin_circuit_t *circ)
circ->build_state->chosen_exit->identity_digest, DIGEST_LEN);
/* Add this exit/hostname pair to the addressmap. */
- len = strlen(conn->socks_request->address) + 1 /* '.' */ +
- strlen(fp) + 1 /* '.' */ +
- strlen("exit") + 1 /* '\0' */;
- new_address = tor_malloc(len);
-
- tor_snprintf(new_address, len, "%s.%s.exit",
+ tor_asprintf(&new_address, "%s.%s.exit",
conn->socks_request->address, fp);
addressmap_register(conn->socks_request->address, new_address,
diff --git a/src/or/circuituse.h b/src/or/circuituse.h
index 9f393ab378..bfeaea20dc 100644
--- a/src/or/circuituse.h
+++ b/src/or/circuituse.h
@@ -51,5 +51,7 @@ int connection_ap_handshake_attach_chosen_circuit(edge_connection_t *conn,
crypt_path_t *cpath);
int connection_ap_handshake_attach_circuit(edge_connection_t *conn);
+int hostname_in_track_host_exits(or_options_t *options, const char *address);
+
#endif
diff --git a/src/or/config.c b/src/or/config.c
index 666a1bdc34..614fc48c3e 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -43,6 +43,8 @@ typedef enum config_type_t {
CONFIG_TYPE_STRING = 0, /**< An arbitrary string. */
CONFIG_TYPE_FILENAME, /**< A filename: some prefixes get expanded. */
CONFIG_TYPE_UINT, /**< A non-negative integer less than MAX_INT */
+ CONFIG_TYPE_PORT, /**< A port from 1...65535, 0 for "not set", or
+ * "auto". */
CONFIG_TYPE_INTERVAL, /**< A number of seconds, with optional units*/
CONFIG_TYPE_MEMUNIT, /**< A number of bytes, with optional units*/
CONFIG_TYPE_DOUBLE, /**< A floating-point value */
@@ -203,8 +205,11 @@ static config_var_t _option_vars[] = {
V(ConstrainedSockSize, MEMUNIT, "8192"),
V(ContactInfo, STRING, NULL),
V(ControlListenAddress, LINELIST, NULL),
- V(ControlPort, UINT, "0"),
+ V(ControlPort, PORT, "0"),
+ V(ControlPortFileGroupReadable,BOOL, "0"),
+ V(ControlPortWriteToFile, FILENAME, NULL),
V(ControlSocket, LINELIST, NULL),
+ V(ControlSocketsGroupWritable, BOOL, "0"),
V(CookieAuthentication, BOOL, "0"),
V(CookieAuthFileGroupReadable, BOOL, "0"),
V(CookieAuthFile, STRING, NULL),
@@ -215,7 +220,7 @@ static config_var_t _option_vars[] = {
V(DirListenAddress, LINELIST, NULL),
OBSOLETE("DirFetchPeriod"),
V(DirPolicy, LINELIST, NULL),
- V(DirPort, UINT, "0"),
+ V(DirPort, PORT, "0"),
V(DirPortFrontPage, FILENAME, NULL),
OBSOLETE("DirPostPeriod"),
OBSOLETE("DirRecordUsageByCountry"),
@@ -225,7 +230,7 @@ static config_var_t _option_vars[] = {
V(DirReqStatistics, BOOL, "0"),
VAR("DirServer", LINELIST, DirServers, NULL),
V(DisableAllSwap, BOOL, "0"),
- V(DNSPort, UINT, "0"),
+ V(DNSPort, PORT, "0"),
V(DNSListenAddress, LINELIST, NULL),
V(DownloadExtraInfo, BOOL, "0"),
V(EnforceDistinctSubnets, BOOL, "1"),
@@ -255,6 +260,7 @@ static config_var_t _option_vars[] = {
V(FetchServerDescriptors, BOOL, "1"),
V(FetchHidServDescriptors, BOOL, "1"),
V(FetchUselessDescriptors, BOOL, "0"),
+ V(FetchV2Networkstatus, BOOL, "0"),
#ifdef WIN32
V(GeoIPFile, FILENAME, "<default>"),
#else
@@ -303,7 +309,7 @@ static config_var_t _option_vars[] = {
V(NewCircuitPeriod, INTERVAL, "30 seconds"),
VAR("NamingAuthoritativeDirectory",BOOL, NamingAuthoritativeDir, "0"),
V(NATDListenAddress, LINELIST, NULL),
- V(NATDPort, UINT, "0"),
+ V(NATDPort, PORT, "0"),
V(Nickname, STRING, NULL),
V(WarnUnsafeSocks, BOOL, "1"),
OBSOLETE("NoPublish"),
@@ -311,7 +317,7 @@ static config_var_t _option_vars[] = {
V(NumCPUs, UINT, "1"),
V(NumEntryGuards, UINT, "3"),
V(ORListenAddress, LINELIST, NULL),
- V(ORPort, UINT, "0"),
+ V(ORPort, PORT, "0"),
V(OutboundBindAddress, STRING, NULL),
OBSOLETE("PathlenCoinWeight"),
V(PerConnBWBurst, MEMUNIT, "0"),
@@ -354,7 +360,7 @@ static config_var_t _option_vars[] = {
V(ShutdownWaitLength, INTERVAL, "30 seconds"),
V(SocksListenAddress, LINELIST, NULL),
V(SocksPolicy, LINELIST, NULL),
- V(SocksPort, UINT, "9050"),
+ V(SocksPort, PORT, "9050"),
V(SocksTimeout, INTERVAL, "2 minutes"),
OBSOLETE("StatusFetchPeriod"),
V(StrictNodes, BOOL, "0"),
@@ -365,7 +371,7 @@ static config_var_t _option_vars[] = {
V(TrackHostExitsExpire, INTERVAL, "30 minutes"),
OBSOLETE("TrafficShaping"),
V(TransListenAddress, LINELIST, NULL),
- V(TransPort, UINT, "0"),
+ V(TransPort, PORT, "0"),
V(TunnelDirConns, BOOL, "1"),
V(UpdateBridgesFromAuthority, BOOL, "0"),
V(UseBridges, BOOL, "0"),
@@ -560,7 +566,7 @@ static int or_state_validate(or_state_t *old_options, or_state_t *options,
static int or_state_load(void);
static int options_init_logs(or_options_t *options, int validate_only);
-static int is_listening_on_low_port(uint16_t port_option,
+static int is_listening_on_low_port(int port_option,
const config_line_t *listen_options);
static uint64_t config_parse_memunit(const char *s, int *ok);
@@ -947,9 +953,15 @@ options_act_reversible(or_options_t *old_options, char **msg)
}
#ifndef HAVE_SYS_UN_H
- if (options->ControlSocket) {
- *msg = tor_strdup("Unix domain sockets (ControlSocket) not supported"
- " on this OS/with this build.");
+ if (options->ControlSocket || options->ControlSocketsGroupWritable) {
+ *msg = tor_strdup("Unix domain sockets (ControlSocket) not supported "
+ "on this OS/with this build.");
+ goto rollback;
+ }
+#else
+ if (options->ControlSocketsGroupWritable && !options->ControlSocket) {
+ *msg = tor_strdup("Setting ControlSocketGroupWritable without setting"
+ "a ControlSocket makes no sense.");
goto rollback;
}
#endif
@@ -1167,7 +1179,7 @@ options_act(or_options_t *old_options)
return -1;
if (options->Bridges) {
- clear_bridge_list();
+ mark_bridge_list();
for (cl = options->Bridges; cl; cl = cl->next) {
if (parse_bridge_line(cl->value, 0)<0) {
log_warn(LD_BUG,
@@ -1175,6 +1187,7 @@ options_act(or_options_t *old_options)
return -1;
}
}
+ sweep_bridge_list();
}
if (running_tor && rend_config_services(options, 0)<0) {
@@ -1259,6 +1272,8 @@ options_act(or_options_t *old_options)
/* Check for transitions that need action. */
if (old_options) {
+ int revise_trackexithosts = 0;
+ int revise_automap_entries = 0;
if ((options->UseEntryGuards && !old_options->UseEntryGuards) ||
!routerset_equal(old_options->ExcludeNodes,options->ExcludeNodes) ||
!routerset_equal(old_options->ExcludeExitNodes,
@@ -1271,9 +1286,31 @@ options_act(or_options_t *old_options)
"excluded node lists. Abandoning previous circuits.");
circuit_mark_all_unused_circs();
circuit_expire_all_dirty_circs();
+ revise_trackexithosts = 1;
+ }
+
+ if (!smartlist_strings_eq(old_options->TrackHostExits,
+ options->TrackHostExits))
+ revise_trackexithosts = 1;
+
+ if (revise_trackexithosts)
addressmap_clear_excluded_trackexithosts(options);
+
+ if (!options->AutomapHostsOnResolve) {
+ if (old_options->AutomapHostsOnResolve)
+ revise_automap_entries = 1;
+ } else {
+ if (!smartlist_strings_eq(old_options->AutomapHostsSuffixes,
+ options->AutomapHostsSuffixes))
+ revise_automap_entries = 1;
+ else if (!opt_streq(old_options->VirtualAddrNetwork,
+ options->VirtualAddrNetwork))
+ revise_automap_entries = 1;
}
+ if (revise_automap_entries)
+ addressmap_clear_invalid_automaps(options);
+
/* How long should we delay counting bridge stats after becoming a bridge?
* We use this so we don't count people who used our bridge thinking it is
* a relay. If you change this, don't forget to change the log message
@@ -1688,8 +1725,16 @@ config_assign_value(config_format_t *fmt, or_options_t *options,
switch (var->type) {
+ case CONFIG_TYPE_PORT:
+ if (!strcasecmp(c->value, "auto")) {
+ *(int *)lvalue = CFG_AUTO_PORT;
+ break;
+ }
+ /* fall through */
case CONFIG_TYPE_UINT:
- i = (int)tor_parse_long(c->value, 10, 0, INT_MAX, &ok, NULL);
+ i = (int)tor_parse_long(c->value, 10, 0,
+ var->type==CONFIG_TYPE_PORT ? 65535 : INT_MAX,
+ &ok, NULL);
if (!ok) {
tor_asprintf(msg,
"Int keyword '%s %s' is malformed or out of bounds.",
@@ -1997,6 +2042,12 @@ get_assigned_option(config_format_t *fmt, void *options,
}
escape_val = 0; /* Can't need escape. */
break;
+ case CONFIG_TYPE_PORT:
+ if (*(int*)value == CFG_AUTO_PORT) {
+ result->value = tor_strdup("auto");
+ escape_val = 0;
+ break;
+ }
case CONFIG_TYPE_INTERVAL:
case CONFIG_TYPE_UINT:
/* This means every or_options_t uint or bool element
@@ -2226,6 +2277,7 @@ option_clear(config_format_t *fmt, or_options_t *options, config_var_t *var)
break;
case CONFIG_TYPE_INTERVAL:
case CONFIG_TYPE_UINT:
+ case CONFIG_TYPE_PORT:
case CONFIG_TYPE_BOOL:
*(int*)lvalue = 0;
break;
@@ -2605,7 +2657,7 @@ options_init(or_options_t *options)
* it is, or 0 if it isn't or the concept of a low port isn't applicable for
* the platform we're on. */
static int
-is_listening_on_low_port(uint16_t port_option,
+is_listening_on_low_port(int port_option,
const config_line_t *listen_options)
{
#ifdef MS_WINDOWS
@@ -2850,9 +2902,6 @@ options_validate(or_options_t *old_options, or_options_t *options,
tor_assert(msg);
*msg = NULL;
- if (options->ORPort < 0 || options->ORPort > 65535)
- REJECT("ORPort option out of bounds.");
-
if (server_mode(options) &&
(!strcmpstart(uname, "Windows 95") ||
!strcmpstart(uname, "Windows 98") ||
@@ -2967,18 +3016,6 @@ options_validate(or_options_t *old_options, or_options_t *options,
REJECT("Can't use a relative path to torrc when RunAsDaemon is set.");
#endif
- if (options->SocksPort < 0 || options->SocksPort > 65535)
- REJECT("SocksPort option out of bounds.");
-
- if (options->DNSPort < 0 || options->DNSPort > 65535)
- REJECT("DNSPort option out of bounds.");
-
- if (options->TransPort < 0 || options->TransPort > 65535)
- REJECT("TransPort option out of bounds.");
-
- if (options->NATDPort < 0 || options->NATDPort > 65535)
- REJECT("NATDPort option out of bounds.");
-
if (options->SocksPort == 0 && options->TransPort == 0 &&
options->NATDPort == 0 && options->ORPort == 0 &&
options->DNSPort == 0 && !options->RendConfigLines)
@@ -2987,12 +3024,6 @@ options_validate(or_options_t *old_options, or_options_t *options,
"undefined, and there aren't any hidden services configured. "
"Tor will still run, but probably won't do anything.");
- if (options->ControlPort < 0 || options->ControlPort > 65535)
- REJECT("ControlPort option out of bounds.");
-
- if (options->DirPort < 0 || options->DirPort > 65535)
- REJECT("DirPort option out of bounds.");
-
#ifndef USE_TRANSPARENT
if (options->TransPort || options->TransListenAddress)
REJECT("TransPort and TransListenAddress are disabled in this build.");
@@ -4645,7 +4676,7 @@ write_configuration_file(const char *fname, or_options_t *options)
switch (file_status(fname)) {
case FN_FILE:
old_val = read_file_to_str(fname, 0, NULL);
- if (strcmpstart(old_val, GENERATED_FILE_PREFIX)) {
+ if (!old_val || strcmpstart(old_val, GENERATED_FILE_PREFIX)) {
rename_old = 1;
}
tor_free(old_val);
@@ -5237,6 +5268,7 @@ getinfo_helper_config(control_connection_t *conn,
case CONFIG_TYPE_STRING: type = "String"; break;
case CONFIG_TYPE_FILENAME: type = "Filename"; break;
case CONFIG_TYPE_UINT: type = "Integer"; break;
+ case CONFIG_TYPE_PORT: type = "Port"; break;
case CONFIG_TYPE_INTERVAL: type = "TimeInterval"; break;
case CONFIG_TYPE_MEMUNIT: type = "DataSize"; break;
case CONFIG_TYPE_DOUBLE: type = "Float"; break;
diff --git a/src/or/connection.c b/src/or/connection.c
index e90e13ffa0..5054909df9 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -37,7 +37,7 @@
#include "routerparse.h"
static connection_t *connection_create_listener(
- struct sockaddr *listensockaddr,
+ const struct sockaddr *listensockaddr,
socklen_t listensocklen, int type,
char* address);
static void connection_init(time_t now, connection_t *conn, int type,
@@ -759,7 +759,7 @@ connection_expire_held_open(void)
* The listenaddr struct has to be freed by the caller.
*/
static struct sockaddr_in *
-create_inet_sockaddr(const char *listenaddress, uint16_t listenport,
+create_inet_sockaddr(const char *listenaddress, int listenport,
char **readable_address, socklen_t *socklen_out) {
struct sockaddr_in *listenaddr = NULL;
uint32_t addr;
@@ -771,8 +771,10 @@ create_inet_sockaddr(const char *listenaddress, uint16_t listenport,
"Error parsing/resolving ListenAddress %s", listenaddress);
goto err;
}
- if (usePort==0)
- usePort = listenport;
+ if (usePort==0) {
+ if (listenport != CFG_AUTO_PORT)
+ usePort = listenport;
+ }
listenaddr = tor_malloc_zero(sizeof(struct sockaddr_in));
listenaddr->sin_addr.s_addr = htonl(addr);
@@ -851,6 +853,43 @@ warn_too_many_conns(void)
}
}
+#ifdef HAVE_SYS_UN_H
+/** Check whether we should be willing to open an AF_UNIX socket in
+ * <b>path</b>. Return 0 if we should go ahead and -1 if we shouldn't. */
+static int
+check_location_for_unix_socket(or_options_t *options, const char *path)
+{
+ int r = -1;
+ char *p = tor_strdup(path);
+ cpd_check_t flags = CPD_CHECK_MODE_ONLY;
+ if (get_parent_directory(p)<0)
+ goto done;
+
+ if (options->ControlSocketsGroupWritable)
+ flags |= CPD_GROUP_OK;
+
+ if (check_private_dir(p, flags) < 0) {
+ char *escpath, *escdir;
+ escpath = esc_for_log(path);
+ escdir = esc_for_log(p);
+ log_warn(LD_GENERAL, "Before Tor can create a control socket in %s, the "
+ "directory %s needs to exist, and to be accessible only by the "
+ "user%s account that is running Tor. (On some Unix systems, "
+ "anybody who can list a socket can conect to it, so Tor is "
+ "being careful.)", escpath, escdir,
+ options->ControlSocketsGroupWritable ? " and group" : "");
+ tor_free(escpath);
+ tor_free(escdir);
+ goto done;
+ }
+
+ r = 0;
+ done:
+ tor_free(p);
+ return r;
+}
+#endif
+
/** Tell the TCP stack that it shouldn't wait for a long time after
* <b>sock</b> has closed before reusing its port. */
static void
@@ -877,12 +916,13 @@ make_socket_reuseable(int sock)
* to the conn.
*/
static connection_t *
-connection_create_listener(struct sockaddr *listensockaddr, socklen_t socklen,
+connection_create_listener(const struct sockaddr *listensockaddr,
+ socklen_t socklen,
int type, char* address)
{
connection_t *conn;
int s; /* the socket we're going to make */
- uint16_t usePort = 0;
+ uint16_t usePort = 0, gotPort = 0;
int start_reading = 0;
if (get_n_open_sockets() >= get_options()->_ConnLimit-1) {
@@ -891,15 +931,15 @@ connection_create_listener(struct sockaddr *listensockaddr, socklen_t socklen,
}
if (listensockaddr->sa_family == AF_INET) {
+ tor_addr_t addr;
int is_tcp = (type != CONN_TYPE_AP_DNS_LISTENER);
if (is_tcp)
start_reading = 1;
- usePort = ntohs( (uint16_t)
- ((struct sockaddr_in *)listensockaddr)->sin_port);
+ tor_addr_from_sockaddr(&addr, listensockaddr, &usePort);
log_notice(LD_NET, "Opening %s on %s:%d",
- conn_type_to_string(type), address, usePort);
+ conn_type_to_string(type), fmt_addr(&addr), usePort);
s = tor_open_socket(PF_INET,
is_tcp ? SOCK_STREAM : SOCK_DGRAM,
@@ -930,6 +970,21 @@ connection_create_listener(struct sockaddr *listensockaddr, socklen_t socklen,
goto err;
}
}
+
+ if (usePort != 0) {
+ gotPort = usePort;
+ } else {
+ tor_addr_t addr2;
+ struct sockaddr_storage ss;
+ socklen_t ss_len=sizeof(ss);
+ if (getsockname(s, (struct sockaddr*)&ss, &ss_len)<0) {
+ log_warn(LD_NET, "getsockname() couldn't learn address for %s: %s",
+ conn_type_to_string(type),
+ tor_socket_strerror(tor_socket_errno(s)));
+ gotPort = 0;
+ }
+ tor_addr_from_sockaddr(&addr2, (struct sockaddr*)&ss, &gotPort);
+ }
#ifdef HAVE_SYS_UN_H
} else if (listensockaddr->sa_family == AF_UNIX) {
start_reading = 1;
@@ -938,6 +993,9 @@ connection_create_listener(struct sockaddr *listensockaddr, socklen_t socklen,
* and listeners at the same time */
tor_assert(type == CONN_TYPE_CONTROL_LISTENER);
+ if (check_location_for_unix_socket(get_options(), address) < 0)
+ goto err;
+
log_notice(LD_NET, "Opening %s on %s",
conn_type_to_string(type), address);
@@ -957,6 +1015,15 @@ connection_create_listener(struct sockaddr *listensockaddr, socklen_t socklen,
tor_socket_strerror(tor_socket_errno(s)));
goto err;
}
+ if (get_options()->ControlSocketsGroupWritable) {
+ /* We need to use chmod; fchmod doesn't work on sockets on all
+ * platforms. */
+ if (chmod(address, 0660) < 0) {
+ log_warn(LD_FS,"Unable to make %s group-writable.", address);
+ tor_close_socket(s);
+ goto err;
+ }
+ }
if (listen(s,SOMAXCONN) < 0) {
log_warn(LD_NET, "Could not listen on %s: %s", address,
@@ -977,7 +1044,7 @@ connection_create_listener(struct sockaddr *listensockaddr, socklen_t socklen,
conn->socket_family = listensockaddr->sa_family;
conn->s = s;
conn->address = tor_strdup(address);
- conn->port = usePort;
+ conn->port = gotPort;
if (connection_add(conn) < 0) { /* no space, forget it */
log_warn(LD_NET,"connection_add for listener failed. Giving up.");
@@ -985,8 +1052,12 @@ connection_create_listener(struct sockaddr *listensockaddr, socklen_t socklen,
goto err;
}
- log_debug(LD_NET,"%s listening on port %u.",
- conn_type_to_string(type), usePort);
+ log_fn(usePort==gotPort ? LOG_DEBUG : LOG_NOTICE, LD_NET,
+ "%s listening on port %u.",
+ conn_type_to_string(type), gotPort);
+
+ if (type == CONN_TYPE_CONTROL_LISTENER)
+ control_ports_write_to_file();
conn->state = LISTENER_STATE_READY;
if (start_reading) {
@@ -1250,7 +1321,7 @@ connection_connect(connection_t *conn, const char *address,
{
int s, inprogress = 0;
char addrbuf[256];
- struct sockaddr *dest_addr = (struct sockaddr*) addrbuf;
+ struct sockaddr *dest_addr;
socklen_t dest_addr_len;
or_options_t *options = get_options();
int protocol_family;
@@ -1516,10 +1587,20 @@ connection_read_https_proxy_response(connection_t *conn)
return 1;
}
/* else, bad news on the status code */
- log_warn(LD_NET,
- "The https proxy sent back an unexpected status code %d (%s). "
- "Closing.",
- status_code, escaped(reason));
+ switch (status_code) {
+ case 403:
+ log_warn(LD_NET,
+ "The https proxy refused to allow connection to %s "
+ "(status code %d, %s). Closing.",
+ conn->address, status_code, escaped(reason));
+ break;
+ default:
+ log_warn(LD_NET,
+ "The https proxy sent back an unexpected status code %d (%s). "
+ "Closing.",
+ status_code, escaped(reason));
+ break;
+ }
tor_free(reason);
return -1;
}
@@ -1755,10 +1836,23 @@ retry_listeners(int type, config_line_t *cfg,
if (!parse_addr_port(LOG_WARN,
wanted->value, &address, NULL, &port)) {
int addr_matches = !strcasecmp(address, conn->address);
+ int port_matches;
tor_free(address);
- if (! port)
- port = port_option;
- if (port == conn->port && addr_matches) {
+ if (port) {
+ /* The Listener line has a port */
+ port_matches = (port == conn->port);
+ } else if (port_option == CFG_AUTO_PORT) {
+ /* The Listener line has no port, and the Port line is "auto".
+ * "auto" matches anything; transitions from any port to
+ * "auto" succeed. */
+ port_matches = 1;
+ } else {
+ /* The Listener line has no port, and the Port line is "auto".
+ * "auto" matches anything; transitions from any port to
+ * "auto" succeed. */
+ port_matches = (port_option == conn->port);
+ }
+ if (port_matches && addr_matches) {
line = wanted;
break;
}
@@ -1806,7 +1900,7 @@ retry_listeners(int type, config_line_t *cfg,
case AF_INET:
listensockaddr = (struct sockaddr *)
create_inet_sockaddr(cfg_line->value,
- (uint16_t) port_option,
+ port_option,
&address, &listensocklen);
break;
case AF_UNIX:
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 2c1196c0cd..7828f16386 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -577,7 +577,7 @@ connection_ap_fail_onehop(const char *failed_digest,
if (!edge_conn->want_onehop)
continue;
if (hexdigest_to_digest(edge_conn->chosen_exit_name, digest) < 0 ||
- memcmp(digest, failed_digest, DIGEST_LEN))
+ tor_memneq(digest, failed_digest, DIGEST_LEN))
continue;
if (tor_digest_is_zero(digest)) {
/* we don't know the digest; have to compare addr:port */
@@ -810,7 +810,8 @@ clear_trackexithost_mappings(const char *exitname)
}
/** Remove all TRACKEXIT mappings from the addressmap for which the target
- * host is unknown or no longer allowed. */
+ * host is unknown or no longer allowed, or for which the source address
+ * is no longer in trackexithosts. */
void
addressmap_clear_excluded_trackexithosts(or_options_t *options)
{
@@ -851,7 +852,8 @@ addressmap_clear_excluded_trackexithosts(or_options_t *options)
tor_free(nodename);
if (!ri ||
(allow_nodes && !routerset_contains_router(allow_nodes, ri)) ||
- routerset_contains_router(exclude_nodes, ri)) {
+ routerset_contains_router(exclude_nodes, ri) ||
+ !hostname_in_track_host_exits(options, address)) {
/* We don't know this one, or we want to be rid of it. */
addressmap_ent_remove(address, ent);
MAP_DEL_CURRENT(address);
@@ -859,6 +861,49 @@ addressmap_clear_excluded_trackexithosts(or_options_t *options)
} STRMAP_FOREACH_END;
}
+/** Remove all AUTOMAP mappings from the addressmap for which the
+ * source address no longer matches AutomapHostsSuffixes, which is
+ * no longer allowed by AutomapHostsOnResolve, or for which the
+ * target address is no longer in the virtual network. */
+void
+addressmap_clear_invalid_automaps(or_options_t *options)
+{
+ int clear_all = !options->AutomapHostsOnResolve;
+ const smartlist_t *suffixes = options->AutomapHostsSuffixes;
+
+ if (!addressmap)
+ return;
+
+ if (!suffixes)
+ clear_all = 1; /* This should be impossible, but let's be sure. */
+
+ STRMAP_FOREACH_MODIFY(addressmap, src_address, addressmap_entry_t *, ent) {
+ int remove = clear_all;
+ if (ent->source != ADDRMAPSRC_AUTOMAP)
+ continue; /* not an automap mapping. */
+
+ if (!remove) {
+ int suffix_found = 0;
+ SMARTLIST_FOREACH(suffixes, const char *, suffix, {
+ if (!strcasecmpend(src_address, suffix)) {
+ suffix_found = 1;
+ break;
+ }
+ });
+ if (!suffix_found)
+ remove = 1;
+ }
+
+ if (!remove && ! address_is_in_virtual_range(ent->new_address))
+ remove = 1;
+
+ if (remove) {
+ addressmap_ent_remove(src_address, ent);
+ MAP_DEL_CURRENT(src_address);
+ }
+ } STRMAP_FOREACH_END;
+}
+
/** Remove all entries from the addressmap that were set via the
* configuration file or the command line. */
void
@@ -1370,7 +1415,7 @@ addressmap_register_virtual_address(int type, char *new_address)
log_info(LD_APP, "Registering map from %s to %s", *addrp, new_address);
if (vent_needs_to_be_added)
strmap_set(virtaddress_reversemap, new_address, vent);
- addressmap_register(*addrp, new_address, 2, ADDRMAPSRC_CONTROLLER);
+ addressmap_register(*addrp, new_address, 2, ADDRMAPSRC_AUTOMAP);
#if 0
{
@@ -3061,7 +3106,7 @@ connection_ap_can_use_exit(edge_connection_t *conn, routerinfo_t *exit)
if (conn->chosen_exit_name) {
routerinfo_t *chosen_exit =
router_get_by_nickname(conn->chosen_exit_name, 1);
- if (!chosen_exit || memcmp(chosen_exit->cache_info.identity_digest,
+ if (!chosen_exit || tor_memneq(chosen_exit->cache_info.identity_digest,
exit->cache_info.identity_digest, DIGEST_LEN)) {
/* doesn't match */
// log_debug(LD_APP,"Requested node '%s', considering node '%s'. No.",
diff --git a/src/or/connection_edge.h b/src/or/connection_edge.h
index 70d0dd2713..8ba2fafd08 100644
--- a/src/or/connection_edge.h
+++ b/src/or/connection_edge.h
@@ -62,6 +62,7 @@ int address_is_invalid_destination(const char *address, int client);
void addressmap_init(void);
void addressmap_clear_excluded_trackexithosts(or_options_t *options);
+void addressmap_clear_invalid_automaps(or_options_t *options);
void addressmap_clean(time_t now);
void addressmap_clear_configured(void);
void addressmap_clear_transient(void);
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index 4b932ec51e..ed174c922e 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -111,7 +111,7 @@ connection_or_set_identity_digest(or_connection_t *conn, const char *digest)
if (!orconn_identity_map)
orconn_identity_map = digestmap_new();
- if (!memcmp(conn->identity_digest, digest, DIGEST_LEN))
+ if (tor_memeq(conn->identity_digest, digest, DIGEST_LEN))
return;
/* If the identity was set previously, remove the old mapping. */
@@ -130,7 +130,7 @@ connection_or_set_identity_digest(or_connection_t *conn, const char *digest)
#if 1
/* Testing code to check for bugs in representation. */
for (; tmp; tmp = tmp->next_with_same_id) {
- tor_assert(!memcmp(tmp->identity_digest, digest, DIGEST_LEN));
+ tor_assert(tor_memeq(tmp->identity_digest, digest, DIGEST_LEN));
tor_assert(tmp != conn);
}
#endif
@@ -545,7 +545,7 @@ connection_or_get_for_extend(const char *digest,
for (; conn; conn = conn->next_with_same_id) {
tor_assert(conn->_base.magic == OR_CONNECTION_MAGIC);
tor_assert(conn->_base.type == CONN_TYPE_OR);
- tor_assert(!memcmp(conn->identity_digest, digest, DIGEST_LEN));
+ tor_assert(tor_memeq(conn->identity_digest, digest, DIGEST_LEN));
if (conn->_base.marked_for_close)
continue;
/* Never return a non-open connection. */
@@ -748,7 +748,7 @@ connection_or_set_bad_connections(const char *digest, int force)
return;
DIGESTMAP_FOREACH(orconn_identity_map, identity, or_connection_t *, conn) {
- if (!digest || !memcmp(digest, conn->identity_digest, DIGEST_LEN))
+ if (!digest || tor_memeq(digest, conn->identity_digest, DIGEST_LEN))
connection_or_group_set_badness(conn, force);
} DIGESTMAP_FOREACH_END;
}
@@ -1082,7 +1082,7 @@ connection_or_check_valid_tls_handshake(or_connection_t *conn,
int as_advertised = 1;
tor_assert(has_cert);
tor_assert(has_identity);
- if (memcmp(digest_rcvd_out, conn->identity_digest, DIGEST_LEN)) {
+ if (tor_memneq(digest_rcvd_out, conn->identity_digest, DIGEST_LEN)) {
/* I was aiming for a particular digest. I didn't get it! */
char seen[HEX_DIGEST_LEN+1];
char expected[HEX_DIGEST_LEN+1];
@@ -1414,9 +1414,8 @@ connection_or_send_netinfo(or_connection_t *conn)
len = append_address_to_payload(out, &my_addr);
if (len < 0)
return -1;
- out += len;
} else {
- *out++ = 0;
+ *out = 0;
}
connection_or_write_cell_to_buf(&cell, conn);
diff --git a/src/or/control.c b/src/or/control.c
index 9f7739a402..384e579f93 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -334,7 +334,7 @@ write_escaped_data(const char *data, size_t len, char **out)
}
*outp++ = *data++;
}
- if (outp < *out+2 || memcmp(outp-2, "\r\n", 2)) {
+ if (outp < *out+2 || fast_memcmp(outp-2, "\r\n", 2)) {
*outp++ = '\r';
*outp++ = '\n';
}
@@ -500,7 +500,7 @@ connection_printf_to_buf(control_connection_t *conn, const char *format, ...)
return;
}
len = strlen(buf);
- if (memcmp("\r\n\0", buf+len-2, 3)) {
+ if (fast_memcmp("\r\n\0", buf+len-2, 3)) {
buf[CONNECTION_PRINTF_TO_BUF_BUFFERSIZE-1] = '\0';
buf[CONNECTION_PRINTF_TO_BUF_BUFFERSIZE-2] = '\n';
buf[CONNECTION_PRINTF_TO_BUF_BUFFERSIZE-3] = '\r';
@@ -508,6 +508,53 @@ connection_printf_to_buf(control_connection_t *conn, const char *format, ...)
connection_write_to_buf(buf, len, TO_CONN(conn));
}
+/** Write all of the open control ports to ControlPortWriteToFile */
+void
+control_ports_write_to_file(void)
+{
+ smartlist_t *lines;
+ char *joined = NULL;
+ or_options_t *options = get_options();
+
+ if (!options->ControlPortWriteToFile)
+ return;
+
+ lines = smartlist_create();
+
+ SMARTLIST_FOREACH_BEGIN(get_connection_array(), const connection_t *, conn) {
+ char *port_str = NULL;
+ if (conn->type != CONN_TYPE_CONTROL_LISTENER || conn->marked_for_close)
+ continue;
+#ifdef AF_UNIX
+ if (conn->socket_family == AF_UNIX) {
+ tor_asprintf(&port_str, "UNIX_PORT=%s\n", conn->address);
+ smartlist_add(lines, port_str);
+ continue;
+ }
+#endif
+ tor_asprintf(&port_str, "PORT=%s:%d\n", conn->address, conn->port);
+ smartlist_add(lines, port_str);
+ } SMARTLIST_FOREACH_END(conn);
+
+ joined = smartlist_join_strings(lines, "", 0, NULL);
+
+ if (write_str_to_file(options->ControlPortWriteToFile, joined, 0) < 0) {
+ log_warn(LD_CONTROL, "Writing %s failed: %s",
+ options->ControlPortWriteToFile, strerror(errno));
+ }
+#ifndef MS_WINDOWS
+ if (options->ControlPortFileGroupReadable) {
+ if (chmod(options->ControlPortWriteToFile, 0640)) {
+ log_warn(LD_FS,"Unable to make %s group-readable.",
+ options->ControlPortWriteToFile);
+ }
+ }
+#endif
+ tor_free(joined);
+ SMARTLIST_FOREACH(lines, char *, cp, tor_free(cp));
+ smartlist_free(lines);
+}
+
/** Send a "DONE" message down the control connection <b>conn</b>. */
static void
send_control_done(control_connection_t *conn)
@@ -581,7 +628,7 @@ send_control_event_impl(uint16_t event, event_format_t which,
}
len = strlen(buf);
- if (memcmp("\r\n\0", buf+len-2, 3)) {
+ if (fast_memcmp("\r\n\0", buf+len-2, 3)) {
/* if it is not properly terminated, do it now */
buf[SEND_CONTROL1_EVENT_BUFFERSIZE-1] = '\0';
buf[SEND_CONTROL1_EVENT_BUFFERSIZE-2] = '\n';
@@ -1069,7 +1116,7 @@ handle_control_authenticate(control_connection_t *conn, uint32_t len,
goto err;
}
bad_cookie = 1;
- } else if (memcmp(authentication_cookie, password, password_len)) {
+ } else if (tor_memneq(authentication_cookie, password, password_len)) {
if (!also_password) {
log_warn(LD_CONTROL, "Got mismatched authentication cookie");
errstr = "Authentication cookie did not match expected value.";
@@ -1119,7 +1166,7 @@ handle_control_authenticate(control_connection_t *conn, uint32_t len,
SMARTLIST_FOREACH(sl, char *, expected,
{
secret_to_key(received,DIGEST_LEN,password,password_len,expected);
- if (!memcmp(expected+S2K_SPECIFIER_LEN, received, DIGEST_LEN))
+ if (tor_memeq(expected+S2K_SPECIFIER_LEN, received, DIGEST_LEN))
goto ok;
});
SMARTLIST_FOREACH(sl, char *, cp, tor_free(cp));
@@ -1407,6 +1454,63 @@ munge_extrainfo_into_routerinfo(const char *ri_body, signed_descriptor_t *ri,
return tor_strndup(ri_body, ri->signed_descriptor_len);
}
+/** Implementation helper for GETINFO: answers requests for information about
+ * which ports are bound. */
+static int
+getinfo_helper_listeners(control_connection_t *control_conn,
+ const char *question,
+ char **answer, const char **errmsg)
+{
+ int type;
+ smartlist_t *res;
+
+ (void)control_conn;
+ (void)errmsg;
+
+ if (!strcmp(question, "net/listeners/or"))
+ type = CONN_TYPE_OR_LISTENER;
+ else if (!strcmp(question, "net/listeners/dir"))
+ type = CONN_TYPE_DIR_LISTENER;
+ else if (!strcmp(question, "net/listeners/socks"))
+ type = CONN_TYPE_AP_LISTENER;
+ else if (!strcmp(question, "net/listeners/trans"))
+ type = CONN_TYPE_AP_TRANS_LISTENER;
+ else if (!strcmp(question, "net/listeners/natd"))
+ type = CONN_TYPE_AP_NATD_LISTENER;
+ else if (!strcmp(question, "net/listeners/dns"))
+ type = CONN_TYPE_AP_DNS_LISTENER;
+ else if (!strcmp(question, "net/listeners/control"))
+ type = CONN_TYPE_CONTROL_LISTENER;
+ else
+ return 0; /* unknown key */
+
+ res = smartlist_create();
+ SMARTLIST_FOREACH_BEGIN(get_connection_array(), connection_t *, conn) {
+ char *addr;
+ struct sockaddr_storage ss;
+ socklen_t ss_len = sizeof(ss);
+
+ if (conn->type != type || conn->marked_for_close || conn->s < 0)
+ continue;
+
+ if (getsockname(conn->s, (struct sockaddr *)&ss, &ss_len) < 0) {
+ tor_asprintf(&addr, "%s:%d", conn->address, (int)conn->port);
+ } else {
+ char *tmp = tor_sockaddr_to_str((struct sockaddr *)&ss);
+ addr = esc_for_log(tmp);
+ tor_free(tmp);
+ }
+ if (addr)
+ smartlist_add(res, addr);
+ } SMARTLIST_FOREACH_END(conn);
+
+ *answer = smartlist_join_strings(res, " ", 0, NULL);
+
+ SMARTLIST_FOREACH(res, char *, cp, tor_free(cp));
+ smartlist_free(res);
+ return 0;
+}
+
/** Implementation helper for GETINFO: knows the answers for questions about
* directory information. */
static int
@@ -1861,6 +1965,7 @@ static const getinfo_item_t getinfo_items[] = {
"All non-expired, non-superseded router descriptors."),
ITEM("desc/all-recent-extrainfo-hack", dir, NULL), /* Hack. */
PREFIX("extra-info/digest/", dir, "Extra-info documents by digest."),
+ PREFIX("net/listeners/", listeners, "Bound addresses by type"),
ITEM("ns/all", networkstatus,
"Brief summary of router status (v2 directory format)"),
PREFIX("ns/id/", networkstatus,
@@ -2834,13 +2939,13 @@ connection_control_process_inbuf(control_connection_t *conn)
break;
/* XXXX this code duplication is kind of dumb. */
if (last_idx+3 == conn->incoming_cmd_cur_len &&
- !memcmp(conn->incoming_cmd + last_idx, ".\r\n", 3)) {
+ tor_memeq(conn->incoming_cmd + last_idx, ".\r\n", 3)) {
/* Just appended ".\r\n"; we're done. Remove it. */
conn->incoming_cmd[last_idx] = '\0';
conn->incoming_cmd_cur_len -= 3;
break;
} else if (last_idx+2 == conn->incoming_cmd_cur_len &&
- !memcmp(conn->incoming_cmd + last_idx, ".\n", 2)) {
+ tor_memeq(conn->incoming_cmd + last_idx, ".\n", 2)) {
/* Just appended ".\n"; we're done. Remove it. */
conn->incoming_cmd[last_idx] = '\0';
conn->incoming_cmd_cur_len -= 2;
@@ -3875,7 +3980,7 @@ static int bootstrap_problems = 0;
* information and initial circuits.
*
* <b>status</b> is the new status, that is, what task we will be doing
- * next. <b>percent</b> is zero if we just started this task, else it
+ * next. <b>progress</b> is zero if we just started this task, else it
* represents progress on the task. */
void
control_event_bootstrap(bootstrap_status_t status, int progress)
@@ -3931,6 +4036,9 @@ control_event_bootstrap_problem(const char *warn, int reason)
char buf[BOOTSTRAP_MSG_LEN];
const char *recommendation = "ignore";
+ /* bootstrap_percent must not be in "undefined" state here. */
+ tor_assert(status >= 0);
+
if (bootstrap_percent == 100)
return; /* already bootstrapped; nothing to be done here. */
diff --git a/src/or/control.h b/src/or/control.h
index 2ae96b4b8a..a73ed5d3c1 100644
--- a/src/or/control.h
+++ b/src/or/control.h
@@ -15,6 +15,8 @@
void control_update_global_event_mask(void);
void control_adjust_event_log_severity(void);
+void control_ports_write_to_file(void);
+
/** Log information about the connection <b>conn</b>, protecting it as with
* CONN_LOG_PROTECT. Example:
*
diff --git a/src/or/directory.c b/src/or/directory.c
index 0c095fe871..347ed42cb8 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -64,7 +64,7 @@ static int purpose_needs_anonymity(uint8_t dir_purpose,
uint8_t router_purpose);
static char *http_get_header(const char *headers, const char *which);
static void http_set_address_origin(const char *headers, connection_t *conn);
-static void connection_dir_download_networkstatus_failed(
+static void connection_dir_download_v2_networkstatus_failed(
dir_connection_t *conn, int status_code);
static void connection_dir_download_routerdesc_failed(dir_connection_t *conn);
static void connection_dir_bridge_routerdesc_failed(dir_connection_t *conn);
@@ -279,6 +279,8 @@ directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose,
int post_via_tor;
smartlist_t *dirservers = router_get_trusted_dir_servers();
int found = 0;
+ const int exclude_self = (dir_purpose == DIR_PURPOSE_UPLOAD_VOTE ||
+ dir_purpose == DIR_PURPOSE_UPLOAD_SIGNATURES);
tor_assert(dirservers);
/* This tries dirservers which we believe to be down, but ultimately, that's
* harmless, and we may as well err on the side of getting things uploaded.
@@ -291,6 +293,9 @@ directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose,
if ((type & ds->type) == 0)
continue;
+ if (exclude_self && router_digest_is_me(ds->digest))
+ continue;
+
if (options->ExcludeNodes && options->StrictNodes &&
routerset_contains_routerstatus(options->ExcludeNodes, rs)) {
log_warn(LD_DIR, "Wanted to contact authority '%s' for %s, but "
@@ -353,6 +358,7 @@ directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose,
break;
case DIR_PURPOSE_FETCH_V2_NETWORKSTATUS:
type = V2_AUTHORITY;
+ prefer_authority = 1; /* Only v2 authorities have these anyway. */
break;
case DIR_PURPOSE_FETCH_SERVERDESC:
type = (router_purpose == ROUTER_PURPOSE_BRIDGE ? BRIDGE_AUTHORITY :
@@ -616,7 +622,7 @@ connection_dir_request_failed(dir_connection_t *conn)
if (conn->_base.purpose == DIR_PURPOSE_FETCH_V2_NETWORKSTATUS) {
log_info(LD_DIR, "Giving up on directory server at '%s'; retrying",
conn->_base.address);
- connection_dir_download_networkstatus_failed(conn, -1);
+ connection_dir_download_v2_networkstatus_failed(conn, -1);
} else if (conn->_base.purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
conn->_base.purpose == DIR_PURPOSE_FETCH_EXTRAINFO) {
log_info(LD_DIR, "Giving up on directory server at '%s'; retrying",
@@ -644,7 +650,7 @@ connection_dir_request_failed(dir_connection_t *conn)
* retry the fetch now, later, or never.
*/
static void
-connection_dir_download_networkstatus_failed(dir_connection_t *conn,
+connection_dir_download_v2_networkstatus_failed(dir_connection_t *conn,
int status_code)
{
if (!conn->requested_resource) {
@@ -1647,13 +1653,19 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
log_info(LD_DIR,"Received networkstatus objects (size %d) from server "
"'%s:%d'", (int)body_len, conn->_base.address, conn->_base.port);
if (status_code != 200) {
- log_warn(LD_DIR,
- "Received http status code %d (%s) from server "
- "'%s:%d' while fetching \"/tor/status/%s\". I'll try again soon.",
- status_code, escaped(reason), conn->_base.address,
- conn->_base.port, conn->requested_resource);
+ static ratelim_t warning_limit = RATELIM_INIT(3600);
+ char *m;
+ if ((m = rate_limit_log(&warning_limit, now))) {
+ log_warn(LD_DIR,
+ "Received http status code %d (%s) from server "
+ "'%s:%d' while fetching \"/tor/status/%s\". "
+ "I'll try again soon.%s",
+ status_code, escaped(reason), conn->_base.address,
+ conn->_base.port, conn->requested_resource, m);
+ tor_free(m);
+ }
tor_free(body); tor_free(headers); tor_free(reason);
- connection_dir_download_networkstatus_failed(conn, status_code);
+ connection_dir_download_v2_networkstatus_failed(conn, status_code);
return -1;
}
if (conn->requested_resource &&
@@ -2435,7 +2447,7 @@ client_likes_consensus(networkstatus_t *v, const char *want_url)
SMARTLIST_FOREACH_BEGIN(v->voters, networkstatus_voter_info_t *, vi) {
if (smartlist_len(vi->sigs) &&
- !memcmp(vi->identity_digest, want_digest, want_len)) {
+ tor_memeq(vi->identity_digest, want_digest, want_len)) {
have++;
break;
};
@@ -3608,17 +3620,17 @@ dir_routerdesc_download_failed(smartlist_t *failed, int status_code,
* every 10 or 60 seconds (FOO_DESCRIPTOR_RETRY_INTERVAL) in main.c. */
}
-/** Helper. Compare two fp_pair_t objects, and return -1, 0, or 1 as
- * appropriate. */
+/** Helper. Compare two fp_pair_t objects, and return negative, 0, or
+ * positive as appropriate. */
static int
_compare_pairs(const void **a, const void **b)
{
const fp_pair_t *fp1 = *a, *fp2 = *b;
int r;
- if ((r = memcmp(fp1->first, fp2->first, DIGEST_LEN)))
+ if ((r = fast_memcmp(fp1->first, fp2->first, DIGEST_LEN)))
return r;
else
- return memcmp(fp1->second, fp2->second, DIGEST_LEN);
+ return fast_memcmp(fp1->second, fp2->second, DIGEST_LEN);
}
/** Divide a string <b>res</b> of the form FP1-FP2+FP3-FP4...[.z], where each
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index c8dda665e4..79b68cdac8 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -2087,7 +2087,7 @@ routerstatus_format_entry(char *buf, size_t buf_len,
/* This assert can fire for the control port, because
* it can request NS documents before all descriptors
* have been fetched. */
- if (memcmp(desc->cache_info.signed_descriptor_digest,
+ if (tor_memneq(desc->cache_info.signed_descriptor_digest,
rs->descriptor_digest,
DIGEST_LEN)) {
char rl_d[HEX_DIGEST_LEN+1];
@@ -2103,7 +2103,7 @@ routerstatus_format_entry(char *buf, size_t buf_len,
"(router %s)\n",
rl_d, rs_d, id);
- tor_assert(!memcmp(desc->cache_info.signed_descriptor_digest,
+ tor_assert(tor_memeq(desc->cache_info.signed_descriptor_digest,
rs->descriptor_digest,
DIGEST_LEN));
};
@@ -2198,9 +2198,9 @@ _compare_routerinfo_by_ip_and_bw(const void **a, const void **b)
/* They're equal! Compare by identity digest, so there's a
* deterministic order and we avoid flapping. */
- return memcmp(first->cache_info.identity_digest,
- second->cache_info.identity_digest,
- DIGEST_LEN);
+ return fast_memcmp(first->cache_info.identity_digest,
+ second->cache_info.identity_digest,
+ DIGEST_LEN);
}
/** Given a list of routerinfo_t in <b>routers</b>, return a new digestmap_t
@@ -2699,13 +2699,16 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_env_t *private_key,
voter->sigs = smartlist_create();
voter->address = hostname;
voter->addr = addr;
- voter->dir_port = options->DirPort;
- voter->or_port = options->ORPort;
+ voter->dir_port = router_get_advertised_dir_port(options);
+ voter->or_port = router_get_advertised_or_port(options);
voter->contact = tor_strdup(contact);
if (options->V3AuthUseLegacyKey) {
authority_cert_t *c = get_my_v3_legacy_cert();
if (c) {
- crypto_pk_get_digest(c->identity_key, voter->legacy_id_digest);
+ if (crypto_pk_get_digest(c->identity_key, voter->legacy_id_digest)) {
+ log_warn(LD_BUG, "Unable to compute digest of legacy v3 identity key");
+ memset(voter->legacy_id_digest, 0, DIGEST_LEN);
+ }
}
}
@@ -2803,7 +2806,7 @@ generate_v2_networkstatus_opinion(void)
"dir-options%s%s%s%s\n"
"%s" /* client version line, server version line. */
"dir-signing-key\n%s",
- hostname, ipaddr, (int)options->DirPort,
+ hostname, ipaddr, (int)router_get_advertised_dir_port(options),
fingerprint,
contact,
published,
@@ -3155,7 +3158,7 @@ dirserv_orconn_tls_done(const char *address,
SMARTLIST_FOREACH_BEGIN(rl->routers, routerinfo_t *, ri) {
if (!strcasecmp(address, ri->address) && or_port == ri->or_port &&
as_advertised &&
- !memcmp(ri->cache_info.identity_digest, digest_rcvd, DIGEST_LEN)) {
+ fast_memeq(ri->cache_info.identity_digest, digest_rcvd, DIGEST_LEN)) {
/* correct digest. mark this router reachable! */
if (!bridge_auth || ri->purpose == ROUTER_PURPOSE_BRIDGE) {
tor_addr_t addr, *addrp=NULL;
diff --git a/src/or/dirvote.c b/src/or/dirvote.c
index 9273dbc90d..96e3df5cec 100644
--- a/src/or/dirvote.c
+++ b/src/or/dirvote.c
@@ -340,7 +340,7 @@ static int
_compare_votes_by_authority_id(const void **_a, const void **_b)
{
const networkstatus_t *a = *_a, *b = *_b;
- return memcmp(get_voter(a)->identity_digest,
+ return fast_memcmp(get_voter(a)->identity_digest,
get_voter(b)->identity_digest, DIGEST_LEN);
}
@@ -357,7 +357,7 @@ _compare_dir_src_ents_by_authority_id(const void **_a, const void **_b)
a_id = a->is_legacy ? a_v->legacy_id_digest : a_v->identity_digest;
b_id = b->is_legacy ? b_v->legacy_id_digest : b_v->identity_digest;
- return memcmp(a_id, b_id, DIGEST_LEN);
+ return fast_memcmp(a_id, b_id, DIGEST_LEN);
}
/** Given a sorted list of strings <b>in</b>, add every member to <b>out</b>
@@ -394,11 +394,12 @@ static int
compare_vote_rs(const vote_routerstatus_t *a, const vote_routerstatus_t *b)
{
int r;
- if ((r = memcmp(a->status.identity_digest, b->status.identity_digest,
+ if ((r = fast_memcmp(a->status.identity_digest, b->status.identity_digest,
DIGEST_LEN)))
return r;
- if ((r = memcmp(a->status.descriptor_digest, b->status.descriptor_digest,
- DIGEST_LEN)))
+ if ((r = fast_memcmp(a->status.descriptor_digest,
+ b->status.descriptor_digest,
+ DIGEST_LEN)))
return r;
if ((r = (int)(b->status.published_on - a->status.published_on)))
return r;
@@ -444,9 +445,9 @@ compute_routerstatus_consensus(smartlist_t *votes, int consensus_method,
if (cur && !compare_vote_rs(cur, rs)) {
++cur_n;
} else {
- if (cur_n > most_n ||
- (cur && cur_n == most_n &&
- cur->status.published_on > most_published)) {
+ if (cur && (cur_n > most_n ||
+ (cur_n == most_n &&
+ cur->status.published_on > most_published))) {
most = cur;
most_n = cur_n;
most_published = cur->status.published_on;
@@ -1648,7 +1649,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
strmap_set_lc(name_to_id_map, rs->status.nickname,
rs->status.identity_digest);
} else if (d != conflict &&
- memcmp(d, rs->status.identity_digest, DIGEST_LEN)) {
+ fast_memcmp(d, rs->status.identity_digest, DIGEST_LEN)) {
/* Authorities disagree about this nickname. */
strmap_set_lc(name_to_id_map, rs->status.nickname, conflict);
} else {
@@ -1672,7 +1673,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
} else if (!d) {
/* We have no name officially mapped to this digest. */
strmap_set_lc(name_to_id_map, rs->status.nickname, unknown);
- } else if (!memcmp(d, rs->status.identity_digest, DIGEST_LEN)) {
+ } else if (fast_memeq(d, rs->status.identity_digest, DIGEST_LEN)) {
/* Authorities disagree about this nickname. */
strmap_set_lc(name_to_id_map, rs->status.nickname, conflict);
} else {
@@ -1705,7 +1706,8 @@ networkstatus_compute_consensus(smartlist_t *votes,
if (index[v_sl_idx] < size[v_sl_idx]) {
rs = smartlist_get(v->routerstatus_list, index[v_sl_idx]);
if (!lowest_id ||
- memcmp(rs->status.identity_digest, lowest_id, DIGEST_LEN) < 0)
+ fast_memcmp(rs->status.identity_digest,
+ lowest_id, DIGEST_LEN) < 0)
lowest_id = rs->status.identity_digest;
}
});
@@ -1724,7 +1726,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
if (index[v_sl_idx] >= size[v_sl_idx])
continue; /* out of entries. */
rs = smartlist_get(v->routerstatus_list, index[v_sl_idx]);
- if (memcmp(rs->status.identity_digest, lowest_id, DIGEST_LEN))
+ if (fast_memcmp(rs->status.identity_digest, lowest_id, DIGEST_LEN))
continue; /* doesn't include this router. */
/* At this point, we know that we're looking at a routerstatus with
* identity "lowest".
@@ -1769,7 +1771,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
rs = compute_routerstatus_consensus(matching_descs, consensus_method,
microdesc_digest);
/* Copy bits of that into rs_out. */
- tor_assert(!memcmp(lowest_id, rs->status.identity_digest, DIGEST_LEN));
+ tor_assert(fast_memeq(lowest_id, rs->status.identity_digest,DIGEST_LEN));
memcpy(rs_out.identity_digest, lowest_id, DIGEST_LEN);
memcpy(rs_out.descriptor_digest, rs->status.descriptor_digest,
DIGEST_LEN);
@@ -1793,7 +1795,7 @@ networkstatus_compute_consensus(smartlist_t *votes,
const char *d = strmap_get_lc(name_to_id_map, rs_out.nickname);
if (!d) {
is_named = is_unnamed = 0;
- } else if (!memcmp(d, lowest_id, DIGEST_LEN)) {
+ } else if (fast_memeq(d, lowest_id, DIGEST_LEN)) {
is_named = 1; is_unnamed = 0;
} else {
is_named = 0; is_unnamed = 1;
@@ -1891,11 +1893,11 @@ networkstatus_compute_consensus(smartlist_t *votes,
SMARTLIST_FOREACH(matching_descs, vote_routerstatus_t *, vsr, {
/* Check if the vote where this status comes from had the
* proper descriptor */
- tor_assert(!memcmp(rs_out.identity_digest,
+ tor_assert(fast_memeq(rs_out.identity_digest,
vsr->status.identity_digest,
DIGEST_LEN));
if (vsr->status.has_exitsummary &&
- !memcmp(rs_out.descriptor_digest,
+ fast_memeq(rs_out.descriptor_digest,
vsr->status.descriptor_digest,
DIGEST_LEN)) {
tor_assert(vsr->status.exitsummary);
@@ -2211,7 +2213,8 @@ networkstatus_add_detached_signatures(networkstatus_t *target,
}
for (alg = DIGEST_SHA1; alg < N_DIGEST_ALGORITHMS; ++alg) {
if (!tor_mem_is_zero(digests->d[alg], DIGEST256_LEN)) {
- if (!memcmp(target->digests.d[alg], digests->d[alg], DIGEST256_LEN)) {
+ if (fast_memeq(target->digests.d[alg], digests->d[alg],
+ DIGEST256_LEN)) {
++n_matches;
} else {
*msg_out = "Mismatched digest.";
@@ -2975,11 +2978,11 @@ dirvote_add_vote(const char *vote_body, const char **msg_out, int *status_out)
/* Now see whether we already have a vote from this authority. */
SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, v, {
- if (! memcmp(v->vote->cert->cache_info.identity_digest,
+ if (fast_memeq(v->vote->cert->cache_info.identity_digest,
vote->cert->cache_info.identity_digest,
DIGEST_LEN)) {
networkstatus_voter_info_t *vi_old = get_voter(v->vote);
- if (!memcmp(vi_old->vote_digest, vi->vote_digest, DIGEST_LEN)) {
+ if (fast_memeq(vi_old->vote_digest, vi->vote_digest, DIGEST_LEN)) {
/* Ah, it's the same vote. Not a problem. */
log_info(LD_DIR, "Discarding a vote we already have (from %s).",
vi->address);
@@ -3129,8 +3132,12 @@ dirvote_compute_consensuses(void)
authority_cert_t *cert = get_my_v3_legacy_cert();
legacy_sign = get_my_v3_legacy_signing_key();
if (cert) {
- crypto_pk_get_digest(cert->identity_key, legacy_dbuf);
- legacy_id_digest = legacy_dbuf;
+ if (crypto_pk_get_digest(cert->identity_key, legacy_dbuf)) {
+ log_warn(LD_BUG,
+ "Unable to compute digest of legacy v3 identity key");
+ } else {
+ legacy_id_digest = legacy_dbuf;
+ }
}
}
@@ -3476,23 +3483,23 @@ dirvote_get_vote(const char *fp, int flags)
if (by_id) {
if (pending_vote_list && include_pending) {
SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, pv,
- if (!memcmp(get_voter(pv->vote)->identity_digest, fp, DIGEST_LEN))
+ if (fast_memeq(get_voter(pv->vote)->identity_digest, fp, DIGEST_LEN))
return pv->vote_body);
}
if (previous_vote_list && include_previous) {
SMARTLIST_FOREACH(previous_vote_list, pending_vote_t *, pv,
- if (!memcmp(get_voter(pv->vote)->identity_digest, fp, DIGEST_LEN))
+ if (fast_memeq(get_voter(pv->vote)->identity_digest, fp, DIGEST_LEN))
return pv->vote_body);
}
} else {
if (pending_vote_list && include_pending) {
SMARTLIST_FOREACH(pending_vote_list, pending_vote_t *, pv,
- if (!memcmp(pv->vote->digests.d[DIGEST_SHA1], fp, DIGEST_LEN))
+ if (fast_memeq(pv->vote->digests.d[DIGEST_SHA1], fp, DIGEST_LEN))
return pv->vote_body);
}
if (previous_vote_list && include_previous) {
SMARTLIST_FOREACH(previous_vote_list, pending_vote_t *, pv,
- if (!memcmp(pv->vote->digests.d[DIGEST_SHA1], fp, DIGEST_LEN))
+ if (fast_memeq(pv->vote->digests.d[DIGEST_SHA1], fp, DIGEST_LEN))
return pv->vote_body);
}
}
@@ -3611,7 +3618,7 @@ vote_routerstatus_find_microdesc_hash(char *digest256_out,
* the first part. */
while (1) {
num_len = strspn(cp, "1234567890");
- if (num_len == mlen && !memcmp(mstr, cp, mlen)) {
+ if (num_len == mlen && fast_memeq(mstr, cp, mlen)) {
/* This is the line. */
char buf[BASE64_DIGEST256_LEN+1];
/* XXXX ignores extraneous stuff if the digest is too long. This
diff --git a/src/or/eventdns.c b/src/or/eventdns.c
index cf583d0682..fc005df2d7 100644
--- a/src/or/eventdns.c
+++ b/src/or/eventdns.c
@@ -461,7 +461,7 @@ sockaddr_eq(const struct sockaddr *sa1, const struct sockaddr *sa2,
const struct sockaddr_in6 *sin1, *sin2;
sin1 = (const struct sockaddr_in6 *)sa1;
sin2 = (const struct sockaddr_in6 *)sa2;
- if (memcmp(sin1->sin6_addr.s6_addr, sin2->sin6_addr.s6_addr, 16))
+ if (tor_memneq(sin1->sin6_addr.s6_addr, sin2->sin6_addr.s6_addr, 16))
return 0;
else if (include_port && sin1->sin6_port != sin2->sin6_port)
return 0;
@@ -2253,7 +2253,7 @@ sockaddr_is_loopback(const struct sockaddr *addr)
return (ntohl(sin->sin_addr.s_addr) & 0xff000000) == 0x7f000000;
} else if (addr->sa_family == AF_INET6) {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
- return !memcmp(sin6->sin6_addr.s6_addr, LOOPBACK_S6, 16);
+ return fast_memeq(sin6->sin6_addr.s6_addr, LOOPBACK_S6, 16);
}
return 0;
}
diff --git a/src/or/main.c b/src/or/main.c
index 462b51e783..d700f0e7a8 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -1417,7 +1417,6 @@ do_hup(void)
router_reset_warnings();
routerlist_reset_warnings();
- addressmap_clear_transient();
/* first, reload config variables, in case they've changed */
if (options->ReloadTorrcOnSIGHUP) {
/* no need to provide argc/v, they've been cached in init_from_config */
@@ -1587,6 +1586,7 @@ do_main_loop(void)
}
}
+#ifndef MS_WINDOWS /* Only called when we're willing to use signals */
/** Libevent callback: invoked when we get a signal.
*/
static void
@@ -1598,6 +1598,7 @@ signal_callback(int fd, short events, void *arg)
process_signal(sig);
}
+#endif
/** Do the work of acting on a signal received in <b>sig</b> */
void
@@ -2044,12 +2045,14 @@ void
tor_cleanup(void)
{
or_options_t *options = get_options();
- /* Remove our pid file. We don't care if there was an error when we
- * unlink, nothing we could do about it anyways. */
if (options->command == CMD_RUN_TOR) {
time_t now = time(NULL);
+ /* Remove our pid file. We don't care if there was an error when we
+ * unlink, nothing we could do about it anyways. */
if (options->PidFile)
unlink(options->PidFile);
+ if (options->ControlPortWriteToFile)
+ unlink(options->ControlPortWriteToFile);
if (accounting_is_enabled(options))
accounting_record_bandwidth_usage(now, get_or_state());
or_state_mark_dirty(get_or_state(), 0); /* force an immediate save. */
diff --git a/src/or/microdesc.c b/src/or/microdesc.c
index 73d2285009..7c67d51448 100644
--- a/src/or/microdesc.c
+++ b/src/or/microdesc.c
@@ -48,7 +48,7 @@ _microdesc_hash(microdesc_t *md)
static INLINE int
_microdesc_eq(microdesc_t *a, microdesc_t *b)
{
- return !memcmp(a->digest, b->digest, DIGEST256_LEN);
+ return tor_memeq(a->digest, b->digest, DIGEST256_LEN);
}
HT_PROTOTYPE(microdesc_map, microdesc_t, node,
@@ -399,10 +399,11 @@ microdesc_cache_rebuild(microdesc_cache_t *cache, int force)
smartlist_add(wrote, md);
}
- finish_writing_to_file(open_file); /*XXX Check me.*/
-
if (cache->cache_content)
tor_munmap_file(cache->cache_content);
+
+ finish_writing_to_file(open_file); /*XXX Check me.*/
+
cache->cache_content = tor_mmap_file(cache->cache_fname);
if (!cache->cache_content && smartlist_len(wrote)) {
@@ -414,7 +415,7 @@ microdesc_cache_rebuild(microdesc_cache_t *cache, int force)
SMARTLIST_FOREACH_BEGIN(wrote, microdesc_t *, md) {
tor_assert(md->saved_location == SAVED_IN_CACHE);
md->body = (char*)cache->cache_content->data + md->off;
- tor_assert(!memcmp(md->body, "onion-key", 9));
+ tor_assert(fast_memeq(md->body, "onion-key", 9));
} SMARTLIST_FOREACH_END(md);
smartlist_free(wrote);
@@ -423,7 +424,7 @@ microdesc_cache_rebuild(microdesc_cache_t *cache, int force)
cache->journal_len = 0;
cache->bytes_dropped = 0;
- new_size = (int)cache->cache_content->size;
+ new_size = cache->cache_content ? (int)cache->cache_content->size : 0;
log_info(LD_DIR, "Done rebuilding microdesc cache. "
"Saved %d bytes; %d still used.",
orig_size-new_size, new_size);
diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c
index 4f6fe15409..1aa4e4a239 100644
--- a/src/or/networkstatus.c
+++ b/src/or/networkstatus.c
@@ -409,7 +409,7 @@ networkstatus_get_voter_by_id(networkstatus_t *vote,
if (!vote || !vote->voters)
return NULL;
SMARTLIST_FOREACH(vote->voters, networkstatus_voter_info_t *, voter,
- if (!memcmp(voter->identity_digest, identity, DIGEST_LEN))
+ if (fast_memeq(voter->identity_digest, identity, DIGEST_LEN))
return voter);
return NULL;
}
@@ -430,9 +430,9 @@ networkstatus_check_document_signature(const networkstatus_t *consensus,
if (crypto_pk_get_digest(cert->signing_key, key_digest)<0)
return -1;
- if (memcmp(sig->signing_key_digest, key_digest, DIGEST_LEN) ||
- memcmp(sig->identity_digest, cert->cache_info.identity_digest,
- DIGEST_LEN))
+ if (tor_memneq(sig->signing_key_digest, key_digest, DIGEST_LEN) ||
+ tor_memneq(sig->identity_digest, cert->cache_info.identity_digest,
+ DIGEST_LEN))
return -1;
signed_digest_len = crypto_pk_keysize(cert->signing_key);
@@ -442,7 +442,7 @@ networkstatus_check_document_signature(const networkstatus_t *consensus,
signed_digest_len,
sig->signature,
sig->signature_len) < dlen ||
- memcmp(signed_digest, consensus->digests.d[sig->alg], dlen)) {
+ tor_memneq(signed_digest, consensus->digests.d[sig->alg], dlen)) {
log_warn(LD_DIR, "Got a bad signature on a networkstatus vote");
sig->bad_signature = 1;
} else {
@@ -494,7 +494,7 @@ networkstatus_check_consensus_signature(networkstatus_t *consensus,
authority_cert_t *cert =
authority_cert_get_by_digests(sig->identity_digest,
sig->signing_key_digest);
- tor_assert(!memcmp(sig->identity_digest, voter->identity_digest,
+ tor_assert(tor_memeq(sig->identity_digest, voter->identity_digest,
DIGEST_LEN));
if (!is_v3_auth) {
@@ -797,8 +797,8 @@ router_set_networkstatus_v2(const char *s, time_t arrived_at,
for (i=0; i < smartlist_len(networkstatus_v2_list); ++i) {
networkstatus_v2_t *old_ns = smartlist_get(networkstatus_v2_list, i);
- if (!memcmp(old_ns->identity_digest, ns->identity_digest, DIGEST_LEN)) {
- if (!memcmp(old_ns->networkstatus_digest,
+ if (tor_memeq(old_ns->identity_digest, ns->identity_digest, DIGEST_LEN)) {
+ if (tor_memeq(old_ns->networkstatus_digest,
ns->networkstatus_digest, DIGEST_LEN)) {
/* Same one we had before. */
networkstatus_v2_free(ns);
@@ -924,7 +924,7 @@ compare_digest_to_routerstatus_entry(const void *_key, const void **_member)
{
const char *key = _key;
const routerstatus_t *rs = *_member;
- return memcmp(key, rs->identity_digest, DIGEST_LEN);
+ return tor_memcmp(key, rs->identity_digest, DIGEST_LEN);
}
/** Return the entry in <b>ns</b> for the identity digest <b>digest</b>, or
@@ -1356,7 +1356,7 @@ update_networkstatus_downloads(time_t now)
or_options_t *options = get_options();
if (should_delay_dir_fetches(options))
return;
- if (directory_fetches_dir_info_early(options))
+ if (authdir_mode_any_main(options) || options->FetchV2Networkstatus)
update_v2_networkstatus_cache_downloads(now);
update_consensus_networkstatus_downloads(now);
update_certificate_downloads(now);
@@ -1392,7 +1392,7 @@ networkstatus_v2_get_by_digest(const char *digest)
{
SMARTLIST_FOREACH(networkstatus_v2_list, networkstatus_v2_t *, ns,
{
- if (!memcmp(ns->identity_digest, digest, DIGEST_LEN))
+ if (tor_memeq(ns->identity_digest, digest, DIGEST_LEN))
return ns;
});
return NULL;
@@ -1441,10 +1441,10 @@ networkstatus_get_reasonably_live_consensus(time_t now)
static int
routerstatus_has_changed(const routerstatus_t *a, const routerstatus_t *b)
{
- tor_assert(!memcmp(a->identity_digest, b->identity_digest, DIGEST_LEN));
+ tor_assert(tor_memeq(a->identity_digest, b->identity_digest, DIGEST_LEN));
return strcmp(a->nickname, b->nickname) ||
- memcmp(a->descriptor_digest, b->descriptor_digest, DIGEST_LEN) ||
+ fast_memneq(a->descriptor_digest, b->descriptor_digest, DIGEST_LEN) ||
a->addr != b->addr ||
a->or_port != b->or_port ||
a->dir_port != b->dir_port ||
@@ -1495,7 +1495,7 @@ notify_control_networkstatus_changed(const networkstatus_t *old_c,
SMARTLIST_FOREACH_JOIN(old_c->routerstatus_list, routerstatus_t *, rs_old,
new_c->routerstatus_list, routerstatus_t *, rs_new,
- memcmp(rs_old->identity_digest,
+ tor_memcmp(rs_old->identity_digest,
rs_new->identity_digest, DIGEST_LEN),
smartlist_add(changed, rs_new)) {
if (routerstatus_has_changed(rs_old, rs_new))
@@ -1519,14 +1519,14 @@ networkstatus_copy_old_consensus_info(networkstatus_t *new_c,
SMARTLIST_FOREACH_JOIN(old_c->routerstatus_list, routerstatus_t *, rs_old,
new_c->routerstatus_list, routerstatus_t *, rs_new,
- memcmp(rs_old->identity_digest,
+ tor_memcmp(rs_old->identity_digest,
rs_new->identity_digest, DIGEST_LEN),
STMT_NIL) {
/* Okay, so we're looking at the same identity. */
rs_new->name_lookup_warned = rs_old->name_lookup_warned;
rs_new->last_dir_503_at = rs_old->last_dir_503_at;
- if (!memcmp(rs_old->descriptor_digest, rs_new->descriptor_digest,
+ if (tor_memeq(rs_old->descriptor_digest, rs_new->descriptor_digest,
DIGEST_LEN)) {
/* And the same descriptor too! */
memcpy(&rs_new->dl_status, &rs_old->dl_status,sizeof(download_status_t));
@@ -1635,7 +1635,7 @@ networkstatus_set_current_consensus(const char *consensus,
}
if (current_digests &&
- !memcmp(&c->digests, current_digests, sizeof(c->digests))) {
+ tor_memeq(&c->digests, current_digests, sizeof(c->digests))) {
/* We already have this one. That's a failure. */
log_info(LD_DIR, "Got a %s consensus we already have", flavor);
goto done;
@@ -1957,7 +1957,7 @@ routers_update_status_from_consensus_networkstatus(smartlist_t *routers,
SMARTLIST_FOREACH_JOIN(ns->routerstatus_list, routerstatus_t *, rs,
routers, routerinfo_t *, router,
- memcmp(rs->identity_digest,
+ tor_memcmp(rs->identity_digest,
router->cache_info.identity_digest, DIGEST_LEN),
{
/* We have no routerstatus for this router. Clear flags and skip it. */
@@ -1980,7 +1980,7 @@ routers_update_status_from_consensus_networkstatus(smartlist_t *routers,
router->is_named = 0;
}
/* Is it the same descriptor, or only the same identity? */
- if (!memcmp(router->cache_info.signed_descriptor_digest,
+ if (tor_memeq(router->cache_info.signed_descriptor_digest,
rs->descriptor_digest, DIGEST_LEN)) {
if (ns->valid_until > router->cache_info.last_listed_as_valid_until)
router->cache_info.last_listed_as_valid_until = ns->valid_until;
@@ -2021,10 +2021,10 @@ routers_update_status_from_consensus_networkstatus(smartlist_t *routers,
time_t live_until = ns->published_on + V2_NETWORKSTATUS_ROUTER_LIFETIME;
SMARTLIST_FOREACH_JOIN(ns->entries, routerstatus_t *, rs,
routers, routerinfo_t *, ri,
- memcmp(rs->identity_digest,
+ tor_memcmp(rs->identity_digest,
ri->cache_info.identity_digest, DIGEST_LEN),
STMT_NIL) {
- if (!memcmp(ri->cache_info.signed_descriptor_digest,
+ if (tor_memeq(ri->cache_info.signed_descriptor_digest,
rs->descriptor_digest, DIGEST_LEN)) {
if (live_until > ri->cache_info.last_listed_as_valid_until)
ri->cache_info.last_listed_as_valid_until = live_until;
diff --git a/src/or/onion.c b/src/or/onion.c
index e1d10a60bb..211d14c1e1 100644
--- a/src/or/onion.c
+++ b/src/or/onion.c
@@ -328,7 +328,7 @@ onion_skin_client_handshake(crypto_dh_env_t *handshake_state,
if (len < 0)
goto err;
- if (memcmp(key_material, handshake_reply+DH_KEY_LEN, DIGEST_LEN)) {
+ if (tor_memneq(key_material, handshake_reply+DH_KEY_LEN, DIGEST_LEN)) {
/* H(K) does *not* match. Something fishy. */
log_warn(LD_PROTOCOL,"Digest DOES NOT MATCH on onion handshake. "
"Bug or attack.");
@@ -415,7 +415,7 @@ fast_client_handshake(const uint8_t *handshake_state,/*DIGEST_LEN bytes*/
if (crypto_expand_key_material(tmp, sizeof(tmp), out, out_len)) {
goto done;
}
- if (memcmp(out, handshake_reply_out+DIGEST_LEN, DIGEST_LEN)) {
+ if (tor_memneq(out, handshake_reply_out+DIGEST_LEN, DIGEST_LEN)) {
/* H(K) does *not* match. Something fishy. */
log_warn(LD_PROTOCOL,"Digest DOES NOT MATCH on fast handshake. "
"Bug or attack.");
diff --git a/src/or/or.h b/src/or/or.h
index 7d354c8fe1..b9d8319ba5 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -2353,6 +2353,10 @@ typedef struct config_line_t {
typedef struct routerset_t routerset_t;
+/** A magic value for the (Socks|OR|...)Port options below, telling Tor
+ * to pick its own port. */
+#define CFG_AUTO_PORT 0xc4005e
+
/** Configuration options for a Tor process. */
typedef struct {
uint32_t _magic;
@@ -2441,6 +2445,7 @@ typedef struct {
int ControlPort; /**< Port to listen on for control connections. */
config_line_t *ControlSocket; /**< List of Unix Domain Sockets to listen on
* for control connections. */
+ int ControlSocketsGroupWritable; /**< Boolean: Are control sockets g+rw? */
int DirPort; /**< Port to listen on for directory connections. */
int DNSPort; /**< Port to listen on for DNS requests. */
int AssumeReachable; /**< Whether to publish our descriptor regardless. */
@@ -2489,7 +2494,9 @@ typedef struct {
/** Boolean: do we publish hidden service descriptors to the HS auths? */
int PublishHidServDescriptors;
int FetchServerDescriptors; /**< Do we fetch server descriptors as normal? */
- int FetchHidServDescriptors; /** and hidden service descriptors? */
+ int FetchHidServDescriptors; /**< and hidden service descriptors? */
+ int FetchV2Networkstatus; /**< Do we fetch v2 networkstatus documents when
+ * we don't need to? */
int HidServDirectoryV2; /**< Do we participate in the HS DHT? */
int MinUptimeHidServDirectoryV2; /**< As directory authority, accept hidden
@@ -2868,6 +2875,11 @@ typedef struct {
* the defaults have changed. */
int _UsingTestNetworkDefaults;
+ /** File where we should write the ControlPort. */
+ char *ControlPortWriteToFile;
+ /** Should that file be group-readable? */
+ int ControlPortFileGroupReadable;
+
} or_options_t;
/** Persistent state for an onion router, as saved to disk. */
@@ -3139,6 +3151,9 @@ typedef enum setopt_err_t {
typedef enum {
/** We're remapping this address because the controller told us to. */
ADDRMAPSRC_CONTROLLER,
+ /** We're remapping this address because of an AutomapHostsOnResolve
+ * configuration. */
+ ADDRMAPSRC_AUTOMAP,
/** We're remapping this address because our configuration (via torrc, the
* command line, or a SETCONF command) told us to. */
ADDRMAPSRC_TORRC,
@@ -3203,7 +3218,9 @@ typedef enum buildtimeout_set_event_t {
*/
#define CONN_LOG_PROTECT(conn, stmt) \
STMT_BEGIN \
- int _log_conn_is_control = (conn && conn->type == CONN_TYPE_CONTROL); \
+ int _log_conn_is_control; \
+ tor_assert(conn); \
+ _log_conn_is_control = (conn->type == CONN_TYPE_CONTROL); \
if (_log_conn_is_control) \
disable_control_logging(); \
STMT_BEGIN stmt; STMT_END; \
diff --git a/src/or/relay.c b/src/or/relay.c
index 807cb3d435..9effae3036 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -133,7 +133,7 @@ relay_digest_matches(crypto_digest_env_t *digest, cell_t *cell)
crypto_digest_add_bytes(digest, (char*) cell->payload, CELL_PAYLOAD_SIZE);
crypto_digest_get_digest(digest, calculated_integrity, 4);
- if (memcmp(received_integrity, calculated_integrity, 4)) {
+ if (tor_memneq(received_integrity, calculated_integrity, 4)) {
// log_fn(LOG_INFO,"Recognized=0 but bad digest. Not recognizing.");
// (%d vs %d).", received_integrity, calculated_integrity);
/* restore digest to its old form */
diff --git a/src/or/rendclient.c b/src/or/rendclient.c
index 8d024d8ebb..77e11c2a07 100644
--- a/src/or/rendclient.c
+++ b/src/or/rendclient.c
@@ -157,7 +157,7 @@ rend_client_send_introduction(origin_circuit_t *introcirc,
intro_key = NULL;
SMARTLIST_FOREACH(entry->parsed->intro_nodes, rend_intro_point_t *,
intro, {
- if (!memcmp(introcirc->build_state->chosen_exit->identity_digest,
+ if (tor_memeq(introcirc->build_state->chosen_exit->identity_digest,
intro->extend_info->identity_digest, DIGEST_LEN)) {
intro_key = intro->intro_key;
break;
@@ -277,7 +277,7 @@ rend_client_send_introduction(origin_circuit_t *introcirc,
introcirc->_base.purpose = CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT;
return 0;
-perm_err:
+ perm_err:
if (!introcirc->_base.marked_for_close)
circuit_mark_for_close(TO_CIRCUIT(introcirc), END_CIRC_REASON_INTERNAL);
circuit_mark_for_close(TO_CIRCUIT(rendcirc), END_CIRC_REASON_INTERNAL);
@@ -626,7 +626,7 @@ rend_client_remove_intro_point(extend_info_t *failed_intro,
for (i = 0; i < smartlist_len(ent->parsed->intro_nodes); i++) {
rend_intro_point_t *intro = smartlist_get(ent->parsed->intro_nodes, i);
- if (!memcmp(failed_intro->identity_digest,
+ if (tor_memeq(failed_intro->identity_digest,
intro->extend_info->identity_digest, DIGEST_LEN)) {
rend_intro_point_free(intro);
smartlist_del(ent->parsed->intro_nodes, i);
@@ -725,7 +725,7 @@ rend_client_receive_rendezvous(origin_circuit_t *circ, const uint8_t *request,
goto err;
/* Check whether the digest is right... */
- if (memcmp(keys, request+DH_KEY_LEN, DIGEST_LEN)) {
+ if (tor_memneq(keys, request+DH_KEY_LEN, DIGEST_LEN)) {
log_warn(LD_PROTOCOL, "Incorrect digest of key material.");
goto err;
}
diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c
index f8e7f9bbb0..da33feccbc 100644
--- a/src/or/rendcommon.c
+++ b/src/or/rendcommon.c
@@ -885,15 +885,15 @@ rend_id_is_in_interval(const char *a, const char *b, const char *c)
tor_assert(c);
/* There are five cases in which a is outside the interval ]b,c]: */
- a_b = memcmp(a,b,DIGEST_LEN);
+ a_b = tor_memcmp(a,b,DIGEST_LEN);
if (a_b == 0)
return 0; /* 1. a == b (b is excluded) */
- b_c = memcmp(b,c,DIGEST_LEN);
+ b_c = tor_memcmp(b,c,DIGEST_LEN);
if (b_c == 0)
return 0; /* 2. b == c (interval is empty) */
else if (a_b <= 0 && b_c < 0)
return 0; /* 3. a b c */
- c_a = memcmp(c,a,DIGEST_LEN);
+ c_a = tor_memcmp(c,a,DIGEST_LEN);
if (c_a < 0 && a_b <= 0)
return 0; /* 4. c a b */
else if (b_c < 0 && c_a < 0)
@@ -1067,7 +1067,7 @@ rend_cache_store(const char *desc, size_t desc_len, int published)
rend_service_descriptor_free(parsed);
return 0;
}
- if (e && e->len == desc_len && !memcmp(desc,e->desc,desc_len)) {
+ if (e && e->len == desc_len && tor_memeq(desc,e->desc,desc_len)) {
log_info(LD_REND,"We already have this service descriptor %s.",
safe_str_client(query));
e->received = time(NULL);
diff --git a/src/or/rendmid.c b/src/or/rendmid.c
index 5e2dd986ba..04edd8e3e2 100644
--- a/src/or/rendmid.c
+++ b/src/or/rendmid.c
@@ -62,7 +62,7 @@ rend_mid_establish_intro(or_circuit_t *circ, const uint8_t *request,
log_warn(LD_BUG, "Internal error computing digest.");
goto err;
}
- if (memcmp(expected_digest, request+2+asn1len, DIGEST_LEN)) {
+ if (tor_memneq(expected_digest, request+2+asn1len, DIGEST_LEN)) {
log_warn(LD_PROTOCOL, "Hash of session info was not as expected.");
reason = END_CIRC_REASON_TORPROTOCOL;
goto err;
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index cd8f9eabeb..35e8b9057a 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -465,7 +465,7 @@ rend_config_services(or_options_t *options, int validate_only)
int keep_it = 0;
tor_assert(oc->rend_data);
SMARTLIST_FOREACH(surviving_services, rend_service_t *, ptr, {
- if (!memcmp(ptr->pk_digest, oc->rend_data->rend_pk_digest,
+ if (tor_memeq(ptr->pk_digest, oc->rend_data->rend_pk_digest,
DIGEST_LEN)) {
keep_it = 1;
break;
@@ -760,7 +760,7 @@ static rend_service_t *
rend_service_get_by_pk_digest(const char* digest)
{
SMARTLIST_FOREACH(rend_service_list, rend_service_t*, s,
- if (!memcmp(s->pk_digest,digest,DIGEST_LEN))
+ if (tor_memeq(s->pk_digest,digest,DIGEST_LEN))
return s);
return NULL;
}
@@ -800,7 +800,7 @@ rend_check_authorization(rend_service_t *service,
/* Look up client authorization by descriptor cookie. */
SMARTLIST_FOREACH(service->clients, rend_authorized_client_t *, client, {
- if (!memcmp(client->descriptor_cookie, descriptor_cookie,
+ if (tor_memeq(client->descriptor_cookie, descriptor_cookie,
REND_DESC_COOKIE_LEN)) {
auth_client = client;
break;
@@ -914,7 +914,7 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request,
/* first DIGEST_LEN bytes of request is intro or service pk digest */
crypto_pk_get_digest(intro_key, intro_key_digest);
- if (memcmp(intro_key_digest, request, DIGEST_LEN)) {
+ if (tor_memneq(intro_key_digest, request, DIGEST_LEN)) {
base32_encode(serviceid, REND_SERVICE_ID_LEN_BASE32+1,
(char*)request, REND_SERVICE_ID_LEN);
log_warn(LD_REND, "Got an INTRODUCE2 cell for the wrong service (%s).",
@@ -1269,7 +1269,7 @@ rend_service_launch_establish_intro(rend_service_t *service,
return -1;
}
- if (memcmp(intro->extend_info->identity_digest,
+ if (tor_memneq(intro->extend_info->identity_digest,
launched->build_state->chosen_exit->identity_digest, DIGEST_LEN)) {
char cann[HEX_DIGEST_LEN+1], orig[HEX_DIGEST_LEN+1];
base16_encode(cann, sizeof(cann),
@@ -1555,7 +1555,7 @@ find_intro_circuit(rend_intro_point_t *intro, const char *pk_digest)
tor_assert(intro);
while ((circ = circuit_get_next_by_pk_and_purpose(circ,pk_digest,
CIRCUIT_PURPOSE_S_INTRO))) {
- if (!memcmp(circ->build_state->chosen_exit->identity_digest,
+ if (tor_memeq(circ->build_state->chosen_exit->identity_digest,
intro->extend_info->identity_digest, DIGEST_LEN) &&
circ->rend_data) {
return circ;
@@ -1565,7 +1565,7 @@ find_intro_circuit(rend_intro_point_t *intro, const char *pk_digest)
circ = NULL;
while ((circ = circuit_get_next_by_pk_and_purpose(circ,pk_digest,
CIRCUIT_PURPOSE_S_ESTABLISH_INTRO))) {
- if (!memcmp(circ->build_state->chosen_exit->identity_digest,
+ if (tor_memeq(circ->build_state->chosen_exit->identity_digest,
intro->extend_info->identity_digest, DIGEST_LEN) &&
circ->rend_data) {
return circ;
@@ -1822,7 +1822,7 @@ rend_services_introduce(void)
if (service->desc) {
SMARTLIST_FOREACH(service->desc->intro_nodes, rend_intro_point_t *,
dintro, {
- if (!memcmp(dintro->extend_info->identity_digest,
+ if (tor_memeq(dintro->extend_info->identity_digest,
intro->extend_info->identity_digest, DIGEST_LEN)) {
log_info(LD_REND, "The intro point we are giving up on was "
"included in the last published descriptor. "
diff --git a/src/or/rephist.c b/src/or/rephist.c
index 02db247389..8cddd2b5eb 100644
--- a/src/or/rephist.c
+++ b/src/or/rephist.c
@@ -117,7 +117,7 @@ get_or_history(const char* id)
{
or_history_t *hist;
- if (tor_mem_is_zero(id, DIGEST_LEN))
+ if (tor_digest_is_zero(id))
return NULL;
hist = digestmap_get(history_map, id);
@@ -145,7 +145,7 @@ get_link_history(const char *from_id, const char *to_id)
orhist = get_or_history(from_id);
if (!orhist)
return NULL;
- if (tor_mem_is_zero(to_id, DIGEST_LEN))
+ if (tor_digest_is_zero(to_id))
return NULL;
lhist = (link_history_t*) digestmap_get(orhist->link_history_map, to_id);
if (!lhist) {
diff --git a/src/or/router.c b/src/or/router.c
index 65afd49f7f..616a290d8a 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -704,8 +704,8 @@ init_keys(void)
ds = router_get_trusteddirserver_by_digest(digest);
if (!ds) {
ds = add_trusted_dir_server(options->Nickname, NULL,
- (uint16_t)options->DirPort,
- (uint16_t)options->ORPort,
+ router_get_advertised_dir_port(options),
+ router_get_advertised_or_port(options),
digest,
v3_digest,
type);
@@ -722,7 +722,7 @@ init_keys(void)
ds->type = type;
}
if (v3_digest_set && (ds->type & V3_AUTHORITY) &&
- memcmp(v3_digest, ds->v3_identity_digest, DIGEST_LEN)) {
+ tor_memneq(v3_digest, ds->v3_identity_digest, DIGEST_LEN)) {
log_warn(LD_DIR, "V3 identity key does not match identity declared in "
"DirServer line. Adjusting.");
memcpy(ds->v3_identity_digest, v3_digest, DIGEST_LEN);
@@ -1165,6 +1165,36 @@ consider_publishable_server(int force)
}
}
+/** Return the port that we should advertise as our ORPort; this is either
+ * the one configured in the ORPort option, or the one we actually bound to
+ * if ORPort is "auto". */
+uint16_t
+router_get_advertised_or_port(or_options_t *options)
+{
+ if (options->ORPort == CFG_AUTO_PORT) {
+ connection_t *c = connection_get_by_type(CONN_TYPE_OR_LISTENER);
+ if (c)
+ return c->port;
+ return 0;
+ }
+ return options->ORPort;
+}
+
+/** Return the port that we should advertise as our DirPort; this is either
+ * the one configured in the DirPort option, or the one we actually bound to
+ * if DirPort is "auto". */
+uint16_t
+router_get_advertised_dir_port(or_options_t *options)
+{
+ if (options->DirPort == CFG_AUTO_PORT) {
+ connection_t *c = connection_get_by_type(CONN_TYPE_DIR_LISTENER);
+ if (c)
+ return c->port;
+ return 0;
+ }
+ return options->DirPort;
+}
+
/*
* OR descriptor generation.
*/
@@ -1261,7 +1291,7 @@ int
router_digest_is_me(const char *digest)
{
return (server_identitykey &&
- !memcmp(server_identitykey_digest, digest, DIGEST_LEN));
+ tor_memeq(server_identitykey_digest, digest, DIGEST_LEN));
}
/** Return true iff I'm a server and <b>digest</b> is equal to
@@ -1273,7 +1303,7 @@ router_extrainfo_digest_is_me(const char *digest)
if (!ei)
return 0;
- return !memcmp(digest,
+ return tor_memeq(digest,
ei->cache_info.signed_descriptor_digest,
DIGEST_LEN);
}
@@ -1398,8 +1428,8 @@ router_rebuild_descriptor(int force)
ri->address = tor_dup_ip(addr);
ri->nickname = tor_strdup(options->Nickname);
ri->addr = addr;
- ri->or_port = options->ORPort;
- ri->dir_port = options->DirPort;
+ ri->or_port = router_get_advertised_or_port(options);
+ ri->dir_port = router_get_advertised_dir_port(options);
ri->cache_info.published_on = time(NULL);
ri->onion_pkey = crypto_pk_dup_key(get_onion_key()); /* must invoke from
* main thread */
diff --git a/src/or/router.h b/src/or/router.h
index 5e021f6fed..1bf1a51ae1 100644
--- a/src/or/router.h
+++ b/src/or/router.h
@@ -50,6 +50,9 @@ int authdir_mode_publishes_statuses(or_options_t *options);
int authdir_mode_tests_reachability(or_options_t *options);
int authdir_mode_bridge(or_options_t *options);
+uint16_t router_get_advertised_or_port(or_options_t *options);
+uint16_t router_get_advertised_dir_port(or_options_t *options);
+
int server_mode(or_options_t *options);
int public_server_mode(or_options_t *options);
int advertised_server_mode(void);
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index f567ccdf3c..a3d9b78ee7 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -165,7 +165,7 @@ already_have_cert(authority_cert_t *cert)
SMARTLIST_FOREACH(cl->certs, authority_cert_t *, c,
{
- if (!memcmp(c->cache_info.signed_descriptor_digest,
+ if (tor_memeq(c->cache_info.signed_descriptor_digest,
cert->cache_info.signed_descriptor_digest,
DIGEST_LEN))
return 1;
@@ -378,16 +378,16 @@ authority_cert_get_by_sk_digest(const char *sk_digest)
return NULL;
if ((c = get_my_v3_authority_cert()) &&
- !memcmp(c->signing_key_digest, sk_digest, DIGEST_LEN))
+ tor_memeq(c->signing_key_digest, sk_digest, DIGEST_LEN))
return c;
if ((c = get_my_v3_legacy_cert()) &&
- !memcmp(c->signing_key_digest, sk_digest, DIGEST_LEN))
+ tor_memeq(c->signing_key_digest, sk_digest, DIGEST_LEN))
return c;
DIGESTMAP_FOREACH(trusted_dir_certs, key, cert_list_t *, cl) {
SMARTLIST_FOREACH(cl->certs, authority_cert_t *, cert,
{
- if (!memcmp(cert->signing_key_digest, sk_digest, DIGEST_LEN))
+ if (tor_memeq(cert->signing_key_digest, sk_digest, DIGEST_LEN))
return cert;
});
} DIGESTMAP_FOREACH_END;
@@ -406,7 +406,7 @@ authority_cert_get_by_digests(const char *id_digest,
!(cl = digestmap_get(trusted_dir_certs, id_digest)))
return NULL;
SMARTLIST_FOREACH(cl->certs, authority_cert_t *, cert,
- if (!memcmp(cert->signing_key_digest, sk_digest, DIGEST_LEN))
+ if (tor_memeq(cert->signing_key_digest, sk_digest, DIGEST_LEN))
return cert; );
return NULL;
@@ -1002,7 +1002,7 @@ router_get_trusteddirserver_by_digest(const char *digest)
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
{
- if (!memcmp(ds->digest, digest, DIGEST_LEN))
+ if (tor_memeq(ds->digest, digest, DIGEST_LEN))
return ds;
});
@@ -1021,7 +1021,7 @@ trusteddirserver_get_by_v3_auth_digest(const char *digest)
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ds,
{
- if (!memcmp(ds->v3_identity_digest, digest, DIGEST_LEN) &&
+ if (tor_memeq(ds->v3_identity_digest, digest, DIGEST_LEN) &&
(ds->type & V3_AUTHORITY))
return ds;
});
@@ -2267,7 +2267,7 @@ hex_digest_matches(const char *hexdigest, const char *identity_digest,
if (base16_decode(digest, DIGEST_LEN, hexdigest, HEX_DIGEST_LEN)<0)
return 0;
- return (!memcmp(digest, identity_digest, DIGEST_LEN));
+ return (tor_memeq(digest, identity_digest, DIGEST_LEN));
}
/** Return true iff the digest of <b>router</b>'s identity key,
@@ -2332,8 +2332,8 @@ router_get_by_nickname(const char *nickname, int warn_if_unnamed)
if (n_matches <= 1 || router->is_running)
best_match = router;
} else if (maybedigest &&
- !memcmp(digest, router->cache_info.identity_digest, DIGEST_LEN)
- ) {
+ tor_memeq(digest, router->cache_info.identity_digest,
+ DIGEST_LEN)) {
if (router_hex_digest_matches(router, nickname))
return router;
/* If we reach this point, we have a ID=name syntax that matches the
@@ -2422,7 +2422,7 @@ router_digest_is_trusted_dir_type(const char *digest, authority_type_t type)
if (authdir_mode(get_options()) && router_digest_is_me(digest))
return 1;
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, ent,
- if (!memcmp(digest, ent->digest, DIGEST_LEN)) {
+ if (tor_memeq(digest, ent->digest, DIGEST_LEN)) {
return (!type) || ((type & ent->type) != 0);
});
return 0;
@@ -2587,7 +2587,7 @@ signed_descriptor_get_body_impl(signed_descriptor_t *desc,
tor_assert(r);
if (!with_annotations) {
- if (memcmp("router ", r, 7) && memcmp("extra-info ", r, 11)) {
+ if (fast_memcmp("router ", r, 7) && fast_memcmp("extra-info ", r, 11)) {
char *cp = tor_strndup(r, 64);
log_err(LD_DIR, "descriptor at %p begins with unexpected string %s. "
"Is another process running in our data directory? Exiting.",
@@ -3066,7 +3066,7 @@ routerlist_replace(routerlist_t *rl, routerinfo_t *ri_old,
routerlist_insert(rl, ri_new);
return;
}
- if (memcmp(ri_old->cache_info.identity_digest,
+ if (tor_memneq(ri_old->cache_info.identity_digest,
ri_new->cache_info.identity_digest, DIGEST_LEN)) {
/* digests don't match; digestmap_set won't replace */
rimap_remove(rl->identity_map, ri_old->cache_info.identity_digest);
@@ -3083,7 +3083,7 @@ routerlist_replace(routerlist_t *rl, routerinfo_t *ri_old,
&ri_new->cache_info);
}
- same_descriptors = ! memcmp(ri_old->cache_info.signed_descriptor_digest,
+ same_descriptors = tor_memeq(ri_old->cache_info.signed_descriptor_digest,
ri_new->cache_info.signed_descriptor_digest,
DIGEST_LEN);
@@ -3105,7 +3105,7 @@ routerlist_replace(routerlist_t *rl, routerinfo_t *ri_old,
sdmap_remove(rl->desc_digest_map,
ri_old->cache_info.signed_descriptor_digest);
- if (memcmp(ri_old->cache_info.extra_info_digest,
+ if (tor_memneq(ri_old->cache_info.extra_info_digest,
ri_new->cache_info.extra_info_digest, DIGEST_LEN)) {
ei_tmp = eimap_remove(rl->extra_info_map,
ri_old->cache_info.extra_info_digest);
@@ -3205,7 +3205,7 @@ router_set_status(const char *digest, int up)
tor_assert(digest);
SMARTLIST_FOREACH(trusted_dir_servers, trusted_dir_server_t *, d,
- if (!memcmp(d->digest, digest, DIGEST_LEN))
+ if (tor_memeq(d->digest, digest, DIGEST_LEN))
d->is_running = up);
router = router_get_by_digest(digest);
@@ -3329,14 +3329,14 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
{
routerstatus_t *rs =
networkstatus_v2_find_entry(ns, id_digest);
- if (rs && !memcmp(rs->descriptor_digest,
+ if (rs && tor_memeq(rs->descriptor_digest,
router->cache_info.signed_descriptor_digest,
DIGEST_LEN))
rs->need_to_mirror = 0;
});
if (consensus) {
routerstatus_t *rs = networkstatus_vote_find_entry(consensus, id_digest);
- if (rs && !memcmp(rs->descriptor_digest,
+ if (rs && tor_memeq(rs->descriptor_digest,
router->cache_info.signed_descriptor_digest,
DIGEST_LEN)) {
in_consensus = 1;
@@ -3458,7 +3458,7 @@ _compare_old_routers_by_identity(const void **_a, const void **_b)
{
int i;
const signed_descriptor_t *r1 = *_a, *r2 = *_b;
- if ((i = memcmp(r1->identity_digest, r2->identity_digest, DIGEST_LEN)))
+ if ((i = fast_memcmp(r1->identity_digest, r2->identity_digest, DIGEST_LEN)))
return i;
return (int)(r1->published_on - r2->published_on);
}
@@ -3506,7 +3506,7 @@ routerlist_remove_old_cached_routers_with_id(time_t now,
ident = ((signed_descriptor_t*)smartlist_get(lst, lo))->identity_digest;
for (i = lo+1; i <= hi; ++i) {
signed_descriptor_t *r = smartlist_get(lst, i);
- tor_assert(!memcmp(ident, r->identity_digest, DIGEST_LEN));
+ tor_assert(tor_memeq(ident, r->identity_digest, DIGEST_LEN));
}
#endif
/* Check whether we need to do anything at all. */
@@ -3718,7 +3718,7 @@ routerlist_remove_old_routers(void)
cur_id = r->identity_digest;
hi = i;
}
- if (memcmp(cur_id, r->identity_digest, DIGEST_LEN)) {
+ if (tor_memneq(cur_id, r->identity_digest, DIGEST_LEN)) {
routerlist_remove_old_cached_routers_with_id(now,
cutoff, i+1, hi, retain);
cur_id = r->identity_digest;
@@ -3956,7 +3956,7 @@ signed_desc_digest_is_recognized(signed_descriptor_t *desc)
if (consensus) {
rs = networkstatus_vote_find_entry(consensus, desc->identity_digest);
- if (rs && !memcmp(rs->descriptor_digest,
+ if (rs && tor_memeq(rs->descriptor_digest,
desc->signed_descriptor_digest, DIGEST_LEN))
return 1;
}
@@ -3965,7 +3965,7 @@ signed_desc_digest_is_recognized(signed_descriptor_t *desc)
{
if (!(rs = networkstatus_v2_find_entry(ns, desc->identity_digest)))
continue;
- if (!memcmp(rs->descriptor_digest,
+ if (tor_memeq(rs->descriptor_digest,
desc->signed_descriptor_digest, DIGEST_LEN))
return 1;
});
@@ -4548,7 +4548,7 @@ update_consensus_router_descriptor_downloads(time_t now, int is_vote,
routerinfo_t *ri;
++n_have;
if (!(ri = router_get_by_digest(rs->identity_digest)) ||
- memcmp(ri->cache_info.signed_descriptor_digest,
+ tor_memneq(ri->cache_info.signed_descriptor_digest,
sd->signed_descriptor_digest, DIGEST_LEN)) {
/* We have a descriptor with this digest, but either there is no
* entry in routerlist with the same ID (!ri), or there is one,
@@ -5058,13 +5058,14 @@ routerinfo_incompatible_with_extrainfo(routerinfo_t *ri, extrainfo_t *ei,
return 1;
}
- digest_matches = !memcmp(ei->cache_info.signed_descriptor_digest,
+ digest_matches = tor_memeq(ei->cache_info.signed_descriptor_digest,
sd->extra_info_digest, DIGEST_LEN);
/* The identity must match exactly to have been generated at the same time
* by the same router. */
- if (memcmp(ri->cache_info.identity_digest, ei->cache_info.identity_digest,
- DIGEST_LEN)) {
+ if (tor_memneq(ri->cache_info.identity_digest,
+ ei->cache_info.identity_digest,
+ DIGEST_LEN)) {
if (msg) *msg = "Extrainfo nickname or identity did not match routerinfo";
goto err; /* different servers */
}
@@ -5074,7 +5075,7 @@ routerinfo_incompatible_with_extrainfo(routerinfo_t *ri, extrainfo_t *ei,
if (crypto_pk_public_checksig(ri->identity_pkey,
signed_digest, sizeof(signed_digest),
ei->pending_sig, ei->pending_sig_len) != DIGEST_LEN ||
- memcmp(signed_digest, ei->cache_info.signed_descriptor_digest,
+ tor_memneq(signed_digest, ei->cache_info.signed_descriptor_digest,
DIGEST_LEN)) {
ei->bad_sig = 1;
tor_free(ei->pending_sig);
@@ -5170,25 +5171,25 @@ routerlist_assert_ok(routerlist_t *rl)
});
RIMAP_FOREACH(rl->identity_map, d, r) {
- tor_assert(!memcmp(r->cache_info.identity_digest, d, DIGEST_LEN));
+ tor_assert(tor_memeq(r->cache_info.identity_digest, d, DIGEST_LEN));
} DIGESTMAP_FOREACH_END;
SDMAP_FOREACH(rl->desc_digest_map, d, sd) {
- tor_assert(!memcmp(sd->signed_descriptor_digest, d, DIGEST_LEN));
+ tor_assert(tor_memeq(sd->signed_descriptor_digest, d, DIGEST_LEN));
} DIGESTMAP_FOREACH_END;
SDMAP_FOREACH(rl->desc_by_eid_map, d, sd) {
tor_assert(!tor_digest_is_zero(d));
tor_assert(sd);
- tor_assert(!memcmp(sd->extra_info_digest, d, DIGEST_LEN));
+ tor_assert(tor_memeq(sd->extra_info_digest, d, DIGEST_LEN));
} DIGESTMAP_FOREACH_END;
EIMAP_FOREACH(rl->extra_info_map, d, ei) {
signed_descriptor_t *sd;
- tor_assert(!memcmp(ei->cache_info.signed_descriptor_digest,
+ tor_assert(tor_memeq(ei->cache_info.signed_descriptor_digest,
d, DIGEST_LEN));
sd = sdmap_get(rl->desc_by_eid_map,
ei->cache_info.signed_descriptor_digest);
// tor_assert(sd); // XXXX see above
if (sd) {
- tor_assert(!memcmp(ei->cache_info.signed_descriptor_digest,
+ tor_assert(tor_memeq(ei->cache_info.signed_descriptor_digest,
sd->extra_info_digest, DIGEST_LEN));
}
} DIGESTMAP_FOREACH_END;
@@ -5234,7 +5235,7 @@ static int
_compare_routerinfo_by_id_digest(const void **a, const void **b)
{
routerinfo_t *first = *(routerinfo_t **)a, *second = *(routerinfo_t **)b;
- return memcmp(first->cache_info.identity_digest,
+ return fast_memcmp(first->cache_info.identity_digest,
second->cache_info.identity_digest,
DIGEST_LEN);
}
@@ -5758,8 +5759,6 @@ int
hid_serv_acting_as_directory(void)
{
routerinfo_t *me = router_get_my_routerinfo();
- networkstatus_t *c;
- routerstatus_t *rs;
if (!me)
return 0;
if (!get_options()->HidServDirectoryV2) {
@@ -5767,22 +5766,6 @@ hid_serv_acting_as_directory(void)
"because we have not been configured as such.");
return 0;
}
- if (!(c = networkstatus_get_latest_consensus())) {
- log_info(LD_REND, "There's no consensus, so I can't tell if I'm a hidden "
- "service directory");
- return 0;
- }
- rs = networkstatus_vote_find_entry(c, me->cache_info.identity_digest);
- if (!rs) {
- log_info(LD_REND, "We're not listed in the consensus, so we're not "
- "being a hidden service directory.");
- return 0;
- }
- if (!rs->is_hs_dir) {
- log_info(LD_REND, "We're not listed as a hidden service directory in "
- "the consensus, so we won't be one.");
- return 0;
- }
return 1;
}
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index d0138e638b..389f22fd99 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -1095,7 +1095,7 @@ check_signature_token(const char *digest,
}
// log_debug(LD_DIR,"Signed %s hash starts %s", doctype,
// hex_str(signed_digest,4));
- if (memcmp(digest, signed_digest, digest_len)) {
+ if (tor_memneq(digest, signed_digest, digest_len)) {
log_warn(LD_DIR, "Error reading %s: signature does not match.", doctype);
tor_free(signed_digest);
return -1;
@@ -1483,7 +1483,7 @@ router_parse_entry_from_string(const char *s, const char *end,
escaped(tok->args[0]));
goto err;
}
- if (memcmp(d,router->cache_info.identity_digest, DIGEST_LEN)!=0) {
+ if (tor_memneq(d,router->cache_info.identity_digest, DIGEST_LEN)) {
log_warn(LD_DIR, "Fingerprint '%s' does not match identity digest.",
tok->args[0]);
goto err;
@@ -1807,7 +1807,7 @@ authority_cert_parse_from_string(const char *s, const char **end_of_string)
cert->cache_info.identity_digest))
goto err;
- if (memcmp(cert->cache_info.identity_digest, fp_declared, DIGEST_LEN)) {
+ if (tor_memneq(cert->cache_info.identity_digest, fp_declared, DIGEST_LEN)) {
log_warn(LD_DIR, "Digest of certificate key didn't match declared "
"fingerprint");
goto err;
@@ -1855,7 +1855,7 @@ authority_cert_parse_from_string(const char *s, const char **end_of_string)
* buy us much. */
if (old_cert->cache_info.signed_descriptor_len == len &&
old_cert->cache_info.signed_descriptor_body &&
- !memcmp(s, old_cert->cache_info.signed_descriptor_body, len)) {
+ tor_memeq(s, old_cert->cache_info.signed_descriptor_body, len)) {
log_debug(LD_DIR, "We already checked the signature on this "
"certificate; no need to do so again.");
found = 1;
@@ -2194,7 +2194,7 @@ int
compare_routerstatus_entries(const void **_a, const void **_b)
{
const routerstatus_t *a = *_a, *b = *_b;
- return memcmp(a->identity_digest, b->identity_digest, DIGEST_LEN);
+ return fast_memcmp(a->identity_digest, b->identity_digest, DIGEST_LEN);
}
/** Helper: used in call to _smartlist_uniq to clear out duplicate entries. */
@@ -2287,7 +2287,7 @@ networkstatus_v2_parse_from_string(const char *s)
log_warn(LD_DIR, "Couldn't compute signing key digest");
goto err;
}
- if (memcmp(tmp_digest, ns->identity_digest, DIGEST_LEN)) {
+ if (tor_memneq(tmp_digest, ns->identity_digest, DIGEST_LEN)) {
log_warn(LD_DIR,
"network-status fingerprint did not match dir-signing-key");
goto err;
@@ -2991,7 +2991,7 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
goto err;
}
if (ns->type != NS_TYPE_CONSENSUS &&
- memcmp(ns->cert->cache_info.identity_digest,
+ tor_memneq(ns->cert->cache_info.identity_digest,
voter->identity_digest, DIGEST_LEN)) {
log_warn(LD_DIR,"Mismatch between identities in certificate and vote");
goto err;
@@ -3097,7 +3097,8 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
rs1 = smartlist_get(ns->routerstatus_list, i-1);
rs2 = smartlist_get(ns->routerstatus_list, i);
}
- if (memcmp(rs1->identity_digest, rs2->identity_digest, DIGEST_LEN) >= 0) {
+ if (fast_memcmp(rs1->identity_digest, rs2->identity_digest, DIGEST_LEN)
+ >= 0) {
log_warn(LD_DIR, "Vote networkstatus entries not sorted by identity "
"digest");
goto err;
@@ -3216,7 +3217,7 @@ networkstatus_parse_vote_from_string(const char *s, const char **eos_out,
}
if (ns->type != NS_TYPE_CONSENSUS) {
- if (memcmp(declared_identity, ns->cert->cache_info.identity_digest,
+ if (tor_memneq(declared_identity, ns->cert->cache_info.identity_digest,
DIGEST_LEN)) {
log_warn(LD_DIR, "Digest mismatch between declared and actual on "
"network-status vote.");
@@ -3498,8 +3499,8 @@ networkstatus_parse_detached_signatures(const char *s, const char *eos)
is_duplicate = 0;
SMARTLIST_FOREACH(siglist, document_signature_t *, s, {
if (s->alg == alg &&
- !memcmp(id_digest, s->identity_digest, DIGEST_LEN) &&
- !memcmp(sk_digest, s->signing_key_digest, DIGEST_LEN)) {
+ tor_memeq(id_digest, s->identity_digest, DIGEST_LEN) &&
+ tor_memeq(sk_digest, s->signing_key_digest, DIGEST_LEN)) {
is_duplicate = 1;
}
});
@@ -4537,7 +4538,7 @@ tor_version_compare(tor_version_t *a, tor_version_t *b)
else if ((i = a->git_tag_len - b->git_tag_len))
return i;
else if (a->git_tag_len)
- return memcmp(a->git_tag, b->git_tag, a->git_tag_len);
+ return fast_memcmp(a->git_tag, b->git_tag, a->git_tag_len);
else
return 0;
}
@@ -4756,7 +4757,7 @@ rend_parse_v2_service_descriptor(rend_service_descriptor_t **parsed_out,
crypto_pk_get_digest(result->pk, public_key_hash);
rend_get_descriptor_id_bytes(test_desc_id, public_key_hash,
secret_id_part);
- if (memcmp(desc_id_out, test_desc_id, DIGEST_LEN)) {
+ if (tor_memneq(desc_id_out, test_desc_id, DIGEST_LEN)) {
log_warn(LD_REND, "Parsed descriptor ID does not match "
"computed descriptor ID.");
goto err;
@@ -4821,7 +4822,7 @@ rend_decrypt_introduction_points(char **ipos_decrypted,
crypto_free_digest_env(digest);
for (pos = 2; pos < 2 + client_entries_len;
pos += REND_BASIC_AUTH_CLIENT_ENTRY_LEN) {
- if (!memcmp(ipos_encrypted + pos, client_id,
+ if (tor_memeq(ipos_encrypted + pos, client_id,
REND_BASIC_AUTH_CLIENT_ID_LEN)) {
/* Attempt to decrypt introduction points. */
cipher = crypto_create_init_cipher(descriptor_cookie, 0);
@@ -4845,7 +4846,7 @@ rend_decrypt_introduction_points(char **ipos_decrypted,
tor_free(dec);
return -1;
}
- if (memcmpstart(dec, declen, "introduction-point ")) {
+ if (fast_memcmpstart(dec, declen, "introduction-point ")) {
log_warn(LD_REND, "Decrypted introduction points don't "
"look like we could parse them.");
tor_free(dec);
@@ -4914,7 +4915,7 @@ rend_parse_introduction_points(rend_service_descriptor_t *parsed,
parsed->intro_nodes = smartlist_create();
area = memarea_new();
- while (!memcmpstart(current_ipo, end_of_intro_points-current_ipo,
+ while (!fast_memcmpstart(current_ipo, end_of_intro_points-current_ipo,
"introduction-point ")) {
/* Determine end of string. */
const char *eos = tor_memstr(current_ipo, end_of_intro_points-current_ipo,