summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/app/config/config.c3
-rw-r--r--src/core/mainloop/mainloop.c8
-rw-r--r--src/core/or/circuituse.c3
-rw-r--r--src/core/or/connection_edge.c18
-rw-r--r--src/core/or/connection_edge.h3
-rw-r--r--src/ext/byteorder.h4
-rw-r--r--src/ext/ed25519/donna/ed25519-donna-portable-identify.h2
-rw-r--r--src/ext/trunnel/trunnel.c6
-rw-r--r--src/feature/client/circpathbias.c14
-rw-r--r--src/feature/control/control.c32
-rw-r--r--src/feature/dircache/dircache.c73
-rw-r--r--src/feature/dirparse/parsecommon.c21
-rw-r--r--src/feature/hs/hs_client.c56
-rw-r--r--src/feature/nodelist/microdesc.c10
-rw-r--r--src/feature/nodelist/networkstatus.c35
-rw-r--r--src/feature/nodelist/networkstatus.h2
-rw-r--r--src/feature/rend/rendclient.c6
-rw-r--r--src/lib/err/backtrace.c3
-rw-r--r--src/lib/net/inaddr_st.h5
-rw-r--r--src/lib/net/socketpair.c2
-rw-r--r--src/lib/process/process_unix.c8
-rw-r--r--src/lib/string/util_string.c15
-rw-r--r--src/lib/string/util_string.h1
-rw-r--r--src/lib/time/compat_time.h96
-rw-r--r--src/test/test-memwipe.c4
-rw-r--r--src/test/test_entrynodes.c32
-rw-r--r--src/test/test_hs_service.c34
-rw-r--r--src/test/test_options.c4
-rw-r--r--src/test/test_routerlist.c1
-rw-r--r--src/test/test_util.c9
30 files changed, 377 insertions, 133 deletions
diff --git a/src/app/config/config.c b/src/app/config/config.c
index 32b487dd24..22070c346b 100644
--- a/src/app/config/config.c
+++ b/src/app/config/config.c
@@ -132,6 +132,9 @@
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
diff --git a/src/core/mainloop/mainloop.c b/src/core/mainloop/mainloop.c
index a2e1080720..ca0fefca71 100644
--- a/src/core/mainloop/mainloop.c
+++ b/src/core/mainloop/mainloop.c
@@ -2166,11 +2166,9 @@ check_expired_networkstatus_callback(time_t now, const or_options_t *options)
(void)options;
/* Check whether our networkstatus has expired. */
networkstatus_t *ns = networkstatus_get_latest_consensus();
- /*XXXX RD: This value needs to be the same as REASONABLY_LIVE_TIME in
- * networkstatus_get_reasonably_live_consensus(), but that value is way
- * way too high. Arma: is the bridge issue there resolved yet? -NM */
-#define NS_EXPIRY_SLOP (24*60*60)
- if (ns && ns->valid_until < (now - NS_EXPIRY_SLOP) &&
+ /* Use reasonably live consensuses until they are no longer reasonably live.
+ */
+ if (ns && !networkstatus_consensus_reasonably_live(ns, now) &&
router_have_minimum_dir_info()) {
router_dir_info_changed();
}
diff --git a/src/core/or/circuituse.c b/src/core/or/circuituse.c
index e230ad1005..b7a4ab1b9e 100644
--- a/src/core/or/circuituse.c
+++ b/src/core/or/circuituse.c
@@ -2377,8 +2377,7 @@ circuit_get_open_circ_or_launch(entry_connection_t *conn,
} else {
hs_client_refetch_hsdesc(&edge_conn->hs_ident->identity_pk);
}
- connection_ap_mark_as_non_pending_circuit(conn);
- ENTRY_TO_CONN(conn)->state = AP_CONN_STATE_RENDDESC_WAIT;
+ connection_ap_mark_as_waiting_for_renddesc(conn);
return 0;
}
log_info(LD_REND,"Chose %s as intro point for '%s'.",
diff --git a/src/core/or/connection_edge.c b/src/core/or/connection_edge.c
index 9f76929e53..93383a4e01 100644
--- a/src/core/or/connection_edge.c
+++ b/src/core/or/connection_edge.c
@@ -140,6 +140,9 @@
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
#if defined(HAVE_NET_IF_H) && defined(HAVE_NET_PFVAR_H)
#include <net/if.h>
@@ -1365,6 +1368,21 @@ connection_ap_mark_as_non_pending_circuit(entry_connection_t *entry_conn)
smartlist_remove(pending_entry_connections, entry_conn);
}
+/** Mark <b>entry_conn</b> as waiting for a rendezvous descriptor. This
+ * function will remove the entry connection from the waiting for a circuit
+ * list (pending_entry_connections).
+ *
+ * This pattern is used across the code base because a connection in state
+ * AP_CONN_STATE_RENDDESC_WAIT must not be in the pending list. */
+void
+connection_ap_mark_as_waiting_for_renddesc(entry_connection_t *entry_conn)
+{
+ tor_assert(entry_conn);
+
+ connection_ap_mark_as_non_pending_circuit(entry_conn);
+ ENTRY_TO_CONN(entry_conn)->state = AP_CONN_STATE_RENDDESC_WAIT;
+}
+
/* DOCDOC */
void
connection_ap_warn_and_unmark_if_pending_circ(entry_connection_t *entry_conn,
diff --git a/src/core/or/connection_edge.h b/src/core/or/connection_edge.h
index 55b90d3eae..b8a7365a05 100644
--- a/src/core/or/connection_edge.h
+++ b/src/core/or/connection_edge.h
@@ -126,6 +126,9 @@ void connection_ap_mark_as_pending_circuit_(entry_connection_t *entry_conn,
#define connection_ap_mark_as_pending_circuit(c) \
connection_ap_mark_as_pending_circuit_((c), __FILE__, __LINE__)
void connection_ap_mark_as_non_pending_circuit(entry_connection_t *entry_conn);
+void connection_ap_mark_as_waiting_for_renddesc(
+ entry_connection_t *entry_conn);
+
#define CONNECTION_AP_EXPECT_NONPENDING(c) do { \
if (ENTRY_TO_CONN(c)->state == AP_CONN_STATE_CIRCUIT_WAIT) { \
log_warn(LD_BUG, "At %s:%d: %p was unexpectedly in circuit_wait.", \
diff --git a/src/ext/byteorder.h b/src/ext/byteorder.h
index c8ba52184b..95e080b14d 100644
--- a/src/ext/byteorder.h
+++ b/src/ext/byteorder.h
@@ -29,6 +29,10 @@
Jean-Philippe Aumasson (https://131002.net/siphash/siphash24.c)
*/
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
/* This code is extracted from csiphash.h */
#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
diff --git a/src/ext/ed25519/donna/ed25519-donna-portable-identify.h b/src/ext/ed25519/donna/ed25519-donna-portable-identify.h
index 26a264cf9e..3e0f9cfc50 100644
--- a/src/ext/ed25519/donna/ed25519-donna-portable-identify.h
+++ b/src/ext/ed25519/donna/ed25519-donna-portable-identify.h
@@ -14,7 +14,7 @@
#define OS_OSX
#elif defined(macintosh) || defined(Macintosh)
#define OS_MAC
- #elif defined(__OpenBSD__)
+ #elif defined(OpenBSD)
#define OS_OPENBSD
#endif
#endif
diff --git a/src/ext/trunnel/trunnel.c b/src/ext/trunnel/trunnel.c
index b749d8136f..2442bc3909 100644
--- a/src/ext/trunnel/trunnel.c
+++ b/src/ext/trunnel/trunnel.c
@@ -14,6 +14,10 @@
#include <stdlib.h>
#include <string.h>
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \
__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
# define IS_LITTLE_ENDIAN 1
@@ -31,7 +35,7 @@
# define IS_LITTLE_ENDIAN
# endif
#else
-# if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+# if defined(__FreeBSD__) || defined(__NetBSD__) || defined(OpenBSD)
# include <sys/endian.h>
# else
# include <endian.h>
diff --git a/src/feature/client/circpathbias.c b/src/feature/client/circpathbias.c
index 9f2ed9347c..eaeef5fe5d 100644
--- a/src/feature/client/circpathbias.c
+++ b/src/feature/client/circpathbias.c
@@ -1332,7 +1332,7 @@ pathbias_measure_use_rate(entry_guard_t *guard)
if (pathbias_get_dropguards(options)) {
if (!pb->path_bias_disabled) {
log_warn(LD_CIRC,
- "Your Guard %s is failing to carry an extremely large "
+ "Guard %s is failing to carry an extremely large "
"amount of stream on its circuits. "
"To avoid potential route manipulation attacks, Tor has "
"disabled use of this guard. "
@@ -1356,7 +1356,7 @@ pathbias_measure_use_rate(entry_guard_t *guard)
} else if (!pb->path_bias_use_extreme) {
pb->path_bias_use_extreme = 1;
log_warn(LD_CIRC,
- "Your Guard %s is failing to carry an extremely large "
+ "Guard %s is failing to carry an extremely large "
"amount of streams on its circuits. "
"This could indicate a route manipulation attack, network "
"overload, bad local network connectivity, or a bug. "
@@ -1380,7 +1380,7 @@ pathbias_measure_use_rate(entry_guard_t *guard)
if (!pb->path_bias_use_noticed) {
pb->path_bias_use_noticed = 1;
log_notice(LD_CIRC,
- "Your Guard %s is failing to carry more streams on its "
+ "Guard %s is failing to carry more streams on its "
"circuits than usual. "
"Most likely this means the Tor network is overloaded "
"or your network connection is poor. "
@@ -1437,7 +1437,7 @@ pathbias_measure_close_rate(entry_guard_t *guard)
if (pathbias_get_dropguards(options)) {
if (!pb->path_bias_disabled) {
log_warn(LD_CIRC,
- "Your Guard %s is failing an extremely large "
+ "Guard %s is failing an extremely large "
"amount of circuits. "
"To avoid potential route manipulation attacks, Tor has "
"disabled use of this guard. "
@@ -1461,7 +1461,7 @@ pathbias_measure_close_rate(entry_guard_t *guard)
} else if (!pb->path_bias_extreme) {
pb->path_bias_extreme = 1;
log_warn(LD_CIRC,
- "Your Guard %s is failing an extremely large "
+ "Guard %s is failing an extremely large "
"amount of circuits. "
"This could indicate a route manipulation attack, "
"extreme network overload, or a bug. "
@@ -1485,7 +1485,7 @@ pathbias_measure_close_rate(entry_guard_t *guard)
if (!pb->path_bias_warned) {
pb->path_bias_warned = 1;
log_warn(LD_CIRC,
- "Your Guard %s is failing a very large "
+ "Guard %s is failing a very large "
"amount of circuits. "
"Most likely this means the Tor network is "
"overloaded, but it could also mean an attack against "
@@ -1510,7 +1510,7 @@ pathbias_measure_close_rate(entry_guard_t *guard)
if (!pb->path_bias_noticed) {
pb->path_bias_noticed = 1;
log_notice(LD_CIRC,
- "Your Guard %s is failing more circuits than "
+ "Guard %s is failing more circuits than "
"usual. "
"Most likely this means the Tor network is overloaded. "
"Success counts are %ld/%ld. Use counts are %ld/%ld. "
diff --git a/src/feature/control/control.c b/src/feature/control/control.c
index da62c94981..170037e060 100644
--- a/src/feature/control/control.c
+++ b/src/feature/control/control.c
@@ -1743,6 +1743,26 @@ handle_control_takeownership(control_connection_t *conn, uint32_t len,
return 0;
}
+/** Called when we get a DROPOWNERSHIP command. Mark this connection
+ * as a non-owning connection, so that we will not exit if the connection
+ * closes. */
+static int
+handle_control_dropownership(control_connection_t *conn, uint32_t len,
+ const char *body)
+{
+ (void)len;
+ (void)body;
+
+ conn->is_owning_control_connection = 0;
+
+ log_info(LD_CONTROL, "Control connection %d has dropped ownership of this "
+ "Tor instance.",
+ (int)(conn->base_.s));
+
+ send_control_done(conn);
+ return 0;
+}
+
/** Return true iff <b>addr</b> is unusable as a mapaddress target because of
* containing funny characters. */
static int
@@ -3069,11 +3089,6 @@ getinfo_helper_events(control_connection_t *control_conn,
case VS_UNKNOWN: *answer = tor_strdup("unknown"); break;
default: tor_fragile_assert();
}
- } else if (!strcmp(question, "status/version/num-versioning") ||
- !strcmp(question, "status/version/num-concurring")) {
- tor_asprintf(answer, "%d", get_n_authorities(V3_DIRINFO));
- log_warn(LD_GENERAL, "%s is deprecated; it no longer gives useful "
- "information", question);
}
} else if (!strcmp(question, "status/clients-seen")) {
char *bridge_stats = geoip_get_bridge_stats_controller(time(NULL));
@@ -3366,10 +3381,6 @@ static const getinfo_item_t getinfo_items[] = {
"A fresh relay/ei descriptor pair for Tor's current state. Not stored."),
DOC("status/version/recommended", "List of currently recommended versions."),
DOC("status/version/current", "Status of the current version."),
- DOC("status/version/num-versioning", "Number of versioning authorities."),
- DOC("status/version/num-concurring",
- "Number of versioning authorities agreeing on the status of the "
- "current version"),
ITEM("address", misc, "IP address of this Tor host, if we can guess it."),
ITEM("traffic/read", misc,"Bytes read since the process was started."),
ITEM("traffic/written", misc,
@@ -5550,6 +5561,9 @@ connection_control_process_inbuf(control_connection_t *conn)
} else if (!strcasecmp(conn->incoming_cmd, "TAKEOWNERSHIP")) {
if (handle_control_takeownership(conn, cmd_data_len, args))
return -1;
+ } else if (!strcasecmp(conn->incoming_cmd, "DROPOWNERSHIP")) {
+ if (handle_control_dropownership(conn, cmd_data_len, args))
+ return -1;
} else if (!strcasecmp(conn->incoming_cmd, "MAPADDRESS")) {
if (handle_control_mapaddress(conn, cmd_data_len, args))
return -1;
diff --git a/src/feature/dircache/dircache.c b/src/feature/dircache/dircache.c
index 4032223db4..8b89d05e98 100644
--- a/src/feature/dircache/dircache.c
+++ b/src/feature/dircache/dircache.c
@@ -489,28 +489,47 @@ handle_get_frontpage(dir_connection_t *conn, const get_handler_args_t *args)
}
/** Warn that the cached consensus <b>consensus</b> of type
- * <b>flavor</b> is too old and will not be served to clients. Rate-limit the
- * warning to avoid logging an entry on every request.
+ * <b>flavor</b> too new or too old, based on <b>is_too_new</b>,
+ * and will not be served to clients. Rate-limit the warning to avoid logging
+ * an entry on every request.
*/
static void
-warn_consensus_is_too_old(const struct consensus_cache_entry_t *consensus,
- const char *flavor, time_t now)
+warn_consensus_is_not_reasonably_live(
+ const struct consensus_cache_entry_t *consensus,
+ const char *flavor, time_t now, bool is_too_new)
{
-#define TOO_OLD_WARNING_INTERVAL (60*60)
- static ratelim_t warned = RATELIM_INIT(TOO_OLD_WARNING_INTERVAL);
+#define NOT_REASONABLY_LIVE_WARNING_INTERVAL (60*60)
+ static ratelim_t warned[2] = { RATELIM_INIT(
+ NOT_REASONABLY_LIVE_WARNING_INTERVAL),
+ RATELIM_INIT(
+ NOT_REASONABLY_LIVE_WARNING_INTERVAL) };
char timestamp[ISO_TIME_LEN+1];
- time_t valid_until;
- char *dupes;
+ /* valid_after if is_too_new, valid_until if !is_too_new */
+ time_t valid_time = 0;
+ char *dupes = NULL;
- if (consensus_cache_entry_get_valid_until(consensus, &valid_until))
- return;
-
- if ((dupes = rate_limit_log(&warned, now))) {
- format_local_iso_time(timestamp, valid_until);
- log_warn(LD_DIRSERV, "Our %s%sconsensus is too old, so we will not "
- "serve it to clients. It was valid until %s local time and we "
- "continued to serve it for up to 24 hours after it expired.%s",
- flavor ? flavor : "", flavor ? " " : "", timestamp, dupes);
+ if (is_too_new) {
+ if (consensus_cache_entry_get_valid_after(consensus, &valid_time))
+ return;
+ dupes = rate_limit_log(&warned[1], now);
+ } else {
+ if (consensus_cache_entry_get_valid_until(consensus, &valid_time))
+ return;
+ dupes = rate_limit_log(&warned[0], now);
+ }
+
+ if (dupes) {
+ format_local_iso_time(timestamp, valid_time);
+ log_warn(LD_DIRSERV, "Our %s%sconsensus is too %s, so we will not "
+ "serve it to clients. It was valid %s %s local time and we "
+ "continued to serve it for up to 24 hours %s.%s",
+ flavor ? flavor : "",
+ flavor ? " " : "",
+ is_too_new ? "new" : "old",
+ is_too_new ? "after" : "until",
+ timestamp,
+ is_too_new ? "before it was valid" : "after it expired",
+ dupes);
tor_free(dupes);
}
}
@@ -853,7 +872,6 @@ handle_get_current_consensus(dir_connection_t *conn,
if (req.diff_only && !cached_consensus) {
write_short_http_response(conn, 404, "No such diff available");
- // XXXX warn_consensus_is_too_old(v, req.flavor, now);
geoip_note_ns_response(GEOIP_REJECT_NOT_FOUND);
goto done;
}
@@ -864,19 +882,30 @@ handle_get_current_consensus(dir_connection_t *conn,
&compression_used);
}
- time_t fresh_until, valid_until;
- int have_fresh_until = 0, have_valid_until = 0;
+ time_t valid_after, fresh_until, valid_until;
+ int have_valid_after = 0, have_fresh_until = 0, have_valid_until = 0;
if (cached_consensus) {
+ have_valid_after =
+ !consensus_cache_entry_get_valid_after(cached_consensus, &valid_after);
have_fresh_until =
!consensus_cache_entry_get_fresh_until(cached_consensus, &fresh_until);
have_valid_until =
!consensus_cache_entry_get_valid_until(cached_consensus, &valid_until);
}
- if (cached_consensus && have_valid_until &&
+ if (cached_consensus && have_valid_after &&
+ !networkstatus_valid_after_is_reasonably_live(valid_after, now)) {
+ write_short_http_response(conn, 404, "Consensus is too new");
+ warn_consensus_is_not_reasonably_live(cached_consensus, req.flavor, now,
+ 1);
+ geoip_note_ns_response(GEOIP_REJECT_NOT_FOUND);
+ goto done;
+ } else if (
+ cached_consensus && have_valid_until &&
!networkstatus_valid_until_is_reasonably_live(valid_until, now)) {
write_short_http_response(conn, 404, "Consensus is too old");
- warn_consensus_is_too_old(cached_consensus, req.flavor, now);
+ warn_consensus_is_not_reasonably_live(cached_consensus, req.flavor, now,
+ 0);
geoip_note_ns_response(GEOIP_REJECT_NOT_FOUND);
goto done;
}
diff --git a/src/feature/dirparse/parsecommon.c b/src/feature/dirparse/parsecommon.c
index b53b0fe193..88df5eec6f 100644
--- a/src/feature/dirparse/parsecommon.c
+++ b/src/feature/dirparse/parsecommon.c
@@ -15,6 +15,7 @@
#include "lib/string/printf.h"
#include "lib/memarea/memarea.h"
#include "lib/crypt_ops/crypto_rsa.h"
+#include "lib/ctime/di_ops.h"
#include <string.h>
@@ -250,6 +251,16 @@ token_check_object(memarea_t *area, const char *kwd,
return tok;
}
+/** Return true iff the <b>memlen</b>-byte chunk of memory at
+ * <b>memlen</b> is the same length as <b>token</b>, and their
+ * contents are equal. */
+static bool
+mem_eq_token(const void *mem, size_t memlen, const char *token)
+{
+ size_t len = strlen(token);
+ return memlen == len && fast_memeq(mem, token, len);
+}
+
/** Helper function: read the next token from *s, advance *s to the end of the
* token, and return the parsed token. Parse *<b>s</b> according to the list
* of tokens in <b>table</b>.
@@ -289,7 +300,7 @@ get_next_token(memarea_t *area,
next = find_whitespace_eos(*s, eol);
- if (!strcmp_len(*s, "opt", next-*s)) {
+ if (mem_eq_token(*s, next-*s, "opt")) {
/* Skip past an "opt" at the start of the line. */
*s = eat_whitespace_eos_no_nl(next, eol);
next = find_whitespace_eos(*s, eol);
@@ -300,7 +311,7 @@ get_next_token(memarea_t *area,
/* Search the table for the appropriate entry. (I tried a binary search
* instead, but it wasn't any faster.) */
for (i = 0; table[i].t ; ++i) {
- if (!strcmp_len(*s, table[i].t, next-*s)) {
+ if (mem_eq_token(*s, next-*s, table[i].t)) {
/* We've found the keyword. */
kwd = table[i].t;
tok->tp = table[i].v;
@@ -352,7 +363,7 @@ get_next_token(memarea_t *area,
goto check_object;
if (eol - *s <= 16 || memchr(*s+11,'\0',eol-*s-16) || /* no short lines, */
- strcmp_len(eol-5, "-----", 5) || /* nuls or invalid endings */
+ !mem_eq_token(eol-5, 5, "-----") || /* nuls or invalid endings */
(eol-*s) > MAX_UNPARSED_OBJECT_SIZE) { /* name too long */
RET_ERR("Malformed object: bad begin line");
}
@@ -371,8 +382,8 @@ get_next_token(memarea_t *area,
eol = eos;
/* Validate the ending tag, which should be 9 + NAME + 5 + eol */
if ((size_t)(eol-next) != 9+obname_len+5 ||
- strcmp_len(next+9, tok->object_type, obname_len) ||
- strcmp_len(eol-5, "-----", 5)) {
+ !mem_eq_token(next+9, obname_len, tok->object_type) ||
+ !mem_eq_token(eol-5, 5, "-----")) {
tor_snprintf(ebuf, sizeof(ebuf), "Malformed object: mismatched end tag %s",
tok->object_type);
ebuf[sizeof(ebuf)-1] = '\0';
diff --git a/src/feature/hs/hs_client.c b/src/feature/hs/hs_client.c
index dfad216abb..5fded92fe3 100644
--- a/src/feature/hs/hs_client.c
+++ b/src/feature/hs/hs_client.c
@@ -142,8 +142,7 @@ flag_all_conn_wait_desc(const ed25519_public_key_t *service_identity_pk)
if (edge_conn->hs_ident &&
ed25519_pubkey_eq(&edge_conn->hs_ident->identity_pk,
service_identity_pk)) {
- connection_ap_mark_as_non_pending_circuit(TO_ENTRY_CONN(conn));
- conn->state = AP_CONN_STATE_RENDDESC_WAIT;
+ connection_ap_mark_as_waiting_for_renddesc(TO_ENTRY_CONN(conn));
}
} SMARTLIST_FOREACH_END(conn);
@@ -201,6 +200,26 @@ directory_request_is_pending(const ed25519_public_key_t *identity_pk)
return ret;
}
+/* Helper function that changes the state of an entry connection to waiting
+ * for a circuit. For this to work properly, the connection timestamps are set
+ * to now and the connection is then marked as pending for a circuit. */
+static void
+mark_conn_as_waiting_for_circuit(connection_t *conn, time_t now)
+{
+ tor_assert(conn);
+
+ /* Because the connection can now proceed to opening circuit and ultimately
+ * connect to the service, reset those timestamp so the connection is
+ * considered "fresh" and can continue without being closed too early. */
+ conn->timestamp_created = now;
+ conn->timestamp_last_read_allowed = now;
+ conn->timestamp_last_write_allowed = now;
+ /* Change connection's state into waiting for a circuit. */
+ conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
+
+ connection_ap_mark_as_pending_circuit(TO_ENTRY_CONN(conn));
+}
+
/* We failed to fetch a descriptor for the service with <b>identity_pk</b>
* because of <b>status</b>. Find all pending SOCKS connections for this
* service that are waiting on the descriptor and close them with
@@ -277,12 +296,19 @@ retry_all_socks_conn_waiting_for_desc(void)
/* Order a refetch in case it works this time. */
status = hs_client_refetch_hsdesc(&edge_conn->hs_ident->identity_pk);
- if (BUG(status == HS_CLIENT_FETCH_HAVE_DESC)) {
- /* This case is unique because it can NOT happen in theory. Once we get
- * a new descriptor, the HS client subsystem is notified immediately and
- * the connections waiting for it are handled which means the state will
- * change from renddesc wait state. Log this and continue to next
- * connection. */
+ if (status == HS_CLIENT_FETCH_HAVE_DESC) {
+ /* This is a rare case where a SOCKS connection is in state waiting for
+ * a descriptor but we do have it in the cache.
+ *
+ * This can happen is tor comes back from suspend where it previously
+ * had the descriptor but the intro points were not usuable. Once it
+ * came back to life, the intro point failure cache was cleaned up and
+ * thus the descriptor became usable again leaving us in this code path.
+ *
+ * We'll mark the connection as waiting for a circuit so the descriptor
+ * can be retried. This is safe because a connection in state waiting
+ * for a descriptor can not be in the entry connection pending list. */
+ mark_conn_as_waiting_for_circuit(base_conn, approx_time());
continue;
}
/* In the case of an error, either all SOCKS connections have been
@@ -1701,17 +1727,9 @@ hs_client_desc_has_arrived(const hs_ident_dir_conn_t *ident)
log_info(LD_REND, "Descriptor has arrived. Launching circuits.");
- /* Because the connection can now proceed to opening circuit and
- * ultimately connect to the service, reset those timestamp so the
- * connection is considered "fresh" and can continue without being closed
- * too early. */
- base_conn->timestamp_created = now;
- base_conn->timestamp_last_read_allowed = now;
- base_conn->timestamp_last_write_allowed = now;
- /* Change connection's state into waiting for a circuit. */
- base_conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
-
- connection_ap_mark_as_pending_circuit(entry_conn);
+ /* Mark connection as waiting for a circuit since we do have a usable
+ * descriptor now. */
+ mark_conn_as_waiting_for_circuit(base_conn, now);
} SMARTLIST_FOREACH_END(base_conn);
end:
diff --git a/src/feature/nodelist/microdesc.c b/src/feature/nodelist/microdesc.c
index eadca69548..82070afb98 100644
--- a/src/feature/nodelist/microdesc.c
+++ b/src/feature/nodelist/microdesc.c
@@ -111,8 +111,9 @@ microdesc_note_outdated_dirserver(const char *relay_digest)
/* If we have a reasonably live consensus, then most of our dirservers should
* still be caching all the microdescriptors in it. Reasonably live
- * consensuses are up to a day old. But microdescriptors expire 7 days after
- * the last consensus that referenced them. */
+ * consensuses are up to a day old (or a day in the future). But
+ * microdescriptors expire 7 days after the last consensus that referenced
+ * them. */
if (!networkstatus_get_reasonably_live_consensus(approx_time(),
FLAV_MICRODESC)) {
return;
@@ -545,8 +546,8 @@ microdesc_cache_clean(microdesc_cache_t *cache, time_t cutoff, int force)
size_t bytes_dropped = 0;
time_t now = time(NULL);
- /* If we don't know a live consensus, don't believe last_listed values: we
- * might be starting up after being down for a while. */
+ /* If we don't know a reasonably live consensus, don't believe last_listed
+ * values: we might be starting up after being down for a while. */
if (! force &&
! networkstatus_get_reasonably_live_consensus(now, FLAV_MICRODESC))
return;
@@ -971,6 +972,7 @@ update_microdesc_downloads(time_t now)
if (directory_too_idle_to_fetch_descriptors(options, now))
return;
+ /* Give up if we don't have a reasonably live consensus. */
consensus = networkstatus_get_reasonably_live_consensus(now, FLAV_MICRODESC);
if (!consensus)
return;
diff --git a/src/feature/nodelist/networkstatus.c b/src/feature/nodelist/networkstatus.c
index 65ea3cc491..e1063a0eac 100644
--- a/src/feature/nodelist/networkstatus.c
+++ b/src/feature/nodelist/networkstatus.c
@@ -1388,7 +1388,7 @@ networkstatus_get_dl_status_by_flavor_running,(consensus_flavor_t flavor))
}
/** Return the most recent consensus that we have downloaded, or NULL if we
- * don't have one. */
+ * don't have one. May return future or expired consensuses. */
MOCK_IMPL(networkstatus_t *,
networkstatus_get_latest_consensus,(void))
{
@@ -1399,7 +1399,7 @@ networkstatus_get_latest_consensus,(void))
}
/** Return the latest consensus we have whose flavor matches <b>f</b>, or NULL
- * if we don't have one. */
+ * if we don't have one. May return future or expired consensuses. */
MOCK_IMPL(networkstatus_t *,
networkstatus_get_latest_consensus_by_flavor,(consensus_flavor_t f))
{
@@ -1433,10 +1433,11 @@ networkstatus_is_live(const networkstatus_t *ns, time_t now)
return (ns->valid_after <= now && now <= ns->valid_until);
}
-/** Determine if <b>consensus</b> is valid or expired recently enough that
- * we can still use it.
+/** Determine if <b>consensus</b> is valid, or expired recently enough, or not
+ * too far in the future, so that we can still use it.
*
- * Return 1 if the consensus is reasonably live, or 0 if it is too old.
+ * Return 1 if the consensus is reasonably live, or 0 if it is too old or
+ * too new.
*/
int
networkstatus_consensus_reasonably_live(const networkstatus_t *consensus,
@@ -1445,29 +1446,42 @@ networkstatus_consensus_reasonably_live(const networkstatus_t *consensus,
if (BUG(!consensus))
return 0;
- return networkstatus_valid_until_is_reasonably_live(consensus->valid_until,
+ return networkstatus_valid_after_is_reasonably_live(consensus->valid_after,
+ now) &&
+ networkstatus_valid_until_is_reasonably_live(consensus->valid_until,
now);
}
+#define REASONABLY_LIVE_TIME (24*60*60)
+
+/** As networkstatus_consensus_reasonably_live, but takes a valid_after
+ * time, and checks to see if it is in the past, or not too far in the future.
+ */
+int
+networkstatus_valid_after_is_reasonably_live(time_t valid_after,
+ time_t now)
+{
+ return (now >= valid_after - REASONABLY_LIVE_TIME);
+}
+
/** As networkstatus_consensus_reasonably_live, but takes a valid_until
- * time rather than an entire consensus. */
+ * time, and checks to see if it is in the future, or not too far in the past.
+ */
int
networkstatus_valid_until_is_reasonably_live(time_t valid_until,
time_t now)
{
-#define REASONABLY_LIVE_TIME (24*60*60)
return (now <= valid_until + REASONABLY_LIVE_TIME);
}
/** As networkstatus_get_live_consensus(), but is way more tolerant of expired
- * consensuses. */
+ * and future consensuses. */
MOCK_IMPL(networkstatus_t *,
networkstatus_get_reasonably_live_consensus,(time_t now, int flavor))
{
networkstatus_t *consensus =
networkstatus_get_latest_consensus_by_flavor(flavor);
if (consensus &&
- consensus->valid_after <= now &&
networkstatus_consensus_reasonably_live(consensus, now))
return consensus;
else
@@ -2090,7 +2104,6 @@ networkstatus_set_current_consensus(const char *consensus,
nodelist_set_consensus(c);
- /* XXXXNM Microdescs: needs a non-ns variant. ???? NM*/
update_consensus_networkstatus_fetch_time(now);
/* Change the cell EWMA settings */
diff --git a/src/feature/nodelist/networkstatus.h b/src/feature/nodelist/networkstatus.h
index 3d212dd304..572b42cc5a 100644
--- a/src/feature/nodelist/networkstatus.h
+++ b/src/feature/nodelist/networkstatus.h
@@ -88,6 +88,8 @@ MOCK_DECL(networkstatus_t *, networkstatus_get_live_consensus,(time_t now));
int networkstatus_is_live(const networkstatus_t *ns, time_t now);
int networkstatus_consensus_reasonably_live(const networkstatus_t *consensus,
time_t now);
+int networkstatus_valid_after_is_reasonably_live(time_t valid_after,
+ time_t now);
int networkstatus_valid_until_is_reasonably_live(time_t valid_until,
time_t now);
MOCK_DECL(networkstatus_t *,networkstatus_get_reasonably_live_consensus,
diff --git a/src/feature/rend/rendclient.c b/src/feature/rend/rendclient.c
index 10b67ceda9..6ecb3eb3c6 100644
--- a/src/feature/rend/rendclient.c
+++ b/src/feature/rend/rendclient.c
@@ -150,8 +150,7 @@ rend_client_send_introduction(origin_circuit_t *introcirc,
while ((conn = connection_get_by_type_state_rendquery(CONN_TYPE_AP,
AP_CONN_STATE_CIRCUIT_WAIT, onion_address))) {
- connection_ap_mark_as_non_pending_circuit(TO_ENTRY_CONN(conn));
- conn->state = AP_CONN_STATE_RENDDESC_WAIT;
+ connection_ap_mark_as_waiting_for_renddesc(TO_ENTRY_CONN(conn));
}
}
@@ -864,8 +863,7 @@ rend_client_report_intro_point_failure(extend_info_t *failed_intro,
while ((conn = connection_get_by_type_state_rendquery(CONN_TYPE_AP,
AP_CONN_STATE_CIRCUIT_WAIT,
onion_address))) {
- connection_ap_mark_as_non_pending_circuit(TO_ENTRY_CONN(conn));
- conn->state = AP_CONN_STATE_RENDDESC_WAIT;
+ connection_ap_mark_as_waiting_for_renddesc(TO_ENTRY_CONN(conn));
}
return 0;
diff --git a/src/lib/err/backtrace.c b/src/lib/err/backtrace.c
index d18a595c34..b568c888c5 100644
--- a/src/lib/err/backtrace.c
+++ b/src/lib/err/backtrace.c
@@ -32,6 +32,9 @@
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
#include <errno.h>
#include <stdlib.h>
#include <string.h>
diff --git a/src/lib/net/inaddr_st.h b/src/lib/net/inaddr_st.h
index dc4c6e3a00..a6b7796268 100644
--- a/src/lib/net/inaddr_st.h
+++ b/src/lib/net/inaddr_st.h
@@ -28,6 +28,9 @@
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
#ifdef _WIN32
#include <winsock2.h>
@@ -60,7 +63,7 @@ struct in6_addr
/** @{ */
/** Many BSD variants seem not to define these. */
#if defined(__APPLE__) || defined(__darwin__) || \
- defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+ defined(__FreeBSD__) || defined(__NetBSD__) || defined(OpenBSD)
#ifndef s6_addr16
#define s6_addr16 __u6_addr.__u6_addr16
#endif
diff --git a/src/lib/net/socketpair.c b/src/lib/net/socketpair.c
index b23f08cab2..b4aeb6eba7 100644
--- a/src/lib/net/socketpair.c
+++ b/src/lib/net/socketpair.c
@@ -62,7 +62,7 @@ get_local_listener(int family, int type)
len = sizeof(sin);
} else {
sa = (struct sockaddr *) &sin6;
- sin6.sin6_family = AF_INET;
+ sin6.sin6_family = AF_INET6;
sin6.sin6_addr.s6_addr[15] = 1;
len = sizeof(sin6);
}
diff --git a/src/lib/process/process_unix.c b/src/lib/process/process_unix.c
index 57ca69a768..dd4ccbf603 100644
--- a/src/lib/process/process_unix.c
+++ b/src/lib/process/process_unix.c
@@ -183,8 +183,8 @@ process_unix_exec(process_t *process)
close(stdin_pipe[1]);
/** Cleanup standard out pipe. */
- close(stdin_pipe[0]);
- close(stdin_pipe[1]);
+ close(stdout_pipe[0]);
+ close(stdout_pipe[1]);
return PROCESS_STATUS_ERROR;
}
@@ -281,8 +281,8 @@ process_unix_exec(process_t *process)
close(stdin_pipe[1]);
/** Cleanup standard out pipe. */
- close(stdin_pipe[0]);
- close(stdin_pipe[1]);
+ close(stdout_pipe[0]);
+ close(stdout_pipe[1]);
/** Cleanup standard error pipe. */
close(stderr_pipe[0]);
diff --git a/src/lib/string/util_string.c b/src/lib/string/util_string.c
index e76e73046f..36e19d029c 100644
--- a/src/lib/string/util_string.c
+++ b/src/lib/string/util_string.c
@@ -212,21 +212,6 @@ strcmpstart(const char *s1, const char *s2)
return strncmp(s1, s2, n);
}
-/** Compare the s1_len-byte string <b>s1</b> with <b>s2</b>,
- * without depending on a terminating nul in s1. Sorting order is first by
- * length, then lexically; return values are as for strcmp.
- */
-int
-strcmp_len(const char *s1, const char *s2, size_t s1_len)
-{
- size_t s2_len = strlen(s2);
- if (s1_len < s2_len)
- return -1;
- if (s1_len > s2_len)
- return 1;
- return fast_memcmp(s1, s2, s2_len);
-}
-
/** Compares the first strlen(s2) characters of s1 with s2. Returns as for
* strcasecmp.
*/
diff --git a/src/lib/string/util_string.h b/src/lib/string/util_string.h
index 99467a27c3..6541afa4cb 100644
--- a/src/lib/string/util_string.h
+++ b/src/lib/string/util_string.h
@@ -33,7 +33,6 @@ int tor_strisnonupper(const char *s);
int tor_strisspace(const char *s);
int strcmp_opt(const char *s1, const char *s2);
int strcmpstart(const char *s1, const char *s2);
-int strcmp_len(const char *s1, const char *s2, size_t len);
int strcasecmpstart(const char *s1, const char *s2);
int strcmpend(const char *s1, const char *s2);
int strcasecmpend(const char *s1, const char *s2);
diff --git a/src/lib/time/compat_time.h b/src/lib/time/compat_time.h
index 44fab62de5..c5337e9998 100644
--- a/src/lib/time/compat_time.h
+++ b/src/lib/time/compat_time.h
@@ -15,6 +15,102 @@
* of tens of milliseconds.
*/
+/* Q: Should you use monotime or monotime_coarse as your source?
+ *
+ * A: Generally, you get better precision with monotime, but better
+ * performance with monotime_coarse.
+ *
+ * Q: Should you use monotime_t or monotime_coarse_t directly? Should you use
+ * usec? msec? "stamp units?"
+ *
+ * A: Using monotime_t and monotime_coarse_t directly is most time-efficient,
+ * since no conversion needs to happen. But they can potentially use more
+ * memory than you would need for a usec/msec/"stamp unit" count.
+ *
+ * Converting to usec or msec on some platforms, and working with them in
+ * general, creates a risk of doing a 64-bit division. 64-bit division is
+ * expensive on 32-bit platforms, which still do exist.
+ *
+ * The "stamp unit" type is designed to give a type that is cheap to convert
+ * from monotime_coarse, has resolution of about 1-2ms, and fits nicely in a
+ * 32-bit integer. Its downside is that it does not correspond directly
+ * to a natural unit of time.
+ *
+ * There is not much point in using "coarse usec" or "coarse nsec", since the
+ * current coarse monotime implementations give you on the order of
+ * milliseconds of precision.
+ *
+ * Q: So, what backends is monotime_coarse using?
+ *
+ * A: Generally speaking, it uses "whatever monotonic-ish time implemenation
+ * does not require a context switch." The various implementations provide
+ * this by having a view of the current time in a read-only memory page that
+ * is updated with a frequency corresponding to the kernel's tick count.
+ *
+ * On Windows, monotime_coarse uses GetCount64() [or GetTickCount() on
+ * obsolete systems]. MSDN claims that the resolution is "typically in the
+ * range of 10-16 msec", but it has said that for years. Storing
+ * monotime_coarse_t uses 8 bytes.
+ *
+ * On OSX/iOS, monotime_coarse uses uses mach_approximate_time() where
+ * available, and falls back to regular monotime. The precision is not
+ * documented, but the implementation is open-source: it reads from a page
+ * that the kernel updates. Storing monotime_coarse_t uses 8 bytes.
+ *
+ * On unixy systems, monotime_coarse uses clock_gettime() with
+ * CLOCK_MONOTONIC_COARSE where available, and falls back to CLOCK_MONOTONIC.
+ * It typically uses vdso tricks to read from a page that the kernel updates.
+ * Its precision fixed, but you can get it with clock_getres(): on my Linux
+ * desktop, it claims to be 1 msec, but it will depend on the system HZ
+ * setting. Storing monotime_coarse_t uses 16 bytes.
+ *
+ * [TODO: Try CLOCK_MONOTONIC_FAST on foobsd.]
+ *
+ * Q: What backends is regular monotonic time using?
+ *
+ * A: In general, regular monotime uses something that requires a system call.
+ * On platforms where system calls are cheap, you win! Otherwise, you lose.
+ *
+ * On Windows, monotonic time uses QuereyPerformanceCounter. Storing
+ * monotime_t costs 8 bytes.
+ *
+ * On OSX/Apple, monotonic time uses mach_absolute_time. Storing
+ * monotime_t costs 8 bytes.
+ *
+ * On unixy systems, monotonic time uses CLOCK_MONOTONIC. Storing
+ * monotime_t costs 16 bytes.
+ *
+ * Q: Tell me about the costs of converting to a 64-bit nsec, usec, or msec
+ * count.
+ *
+ * A: Windows, coarse: Cheap, since it's all multiplication.
+ *
+ * Windows, precise: Expensive on 32-bit: it needs 64-bit division.
+ *
+ * Apple, all: Expensive on 32-bit: it needs 64-bit division.
+ *
+ * Unixy, all: Fairly cheap, since the only division required is dividing
+ * tv_nsec 1000, and nanoseconds-per-second fits in a 32-bit value.
+ *
+ * All, "timestamp units": Cheap everywhere: it never divides.
+ *
+ * Q: This is only somewhat related, but how much precision could I hope for
+ * from a libevent time.?
+ *
+ * A: Actually, it's _very_ related if you're timing in order to have a
+ * timeout happen.
+ *
+ * On Windows, it uses select: you could in theory have a microsecond
+ * resolution, but it usually isn't that accurate.
+ *
+ * On OSX, iOS, and BSD, you have kqueue: You could in theory have a nanosecond
+ * resolution, but it usually isn't that accurate.
+ *
+ * On Linux, you have epoll: It has a millisecond resolution. Some recent
+ * Libevents can also use timerfd for higher resolution if
+ * EVENT_BASE_FLAG_PRECISE_TIMER is set: Tor doesn't set that flag.
+ */
+
#ifndef TOR_COMPAT_TIME_H
#define TOR_COMPAT_TIME_H
diff --git a/src/test/test-memwipe.c b/src/test/test-memwipe.c
index c879013ed6..b00e854a1c 100644
--- a/src/test/test-memwipe.c
+++ b/src/test/test-memwipe.c
@@ -12,6 +12,10 @@
#include <sys/types.h>
#include <stdlib.h>
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
static unsigned fill_a_buffer_memset(void) __attribute__((noinline));
static unsigned fill_a_buffer_memwipe(void) __attribute__((noinline));
static unsigned fill_a_buffer_nothing(void) __attribute__((noinline));
diff --git a/src/test/test_entrynodes.c b/src/test/test_entrynodes.c
index 16b14c0b73..069440a8ce 100644
--- a/src/test/test_entrynodes.c
+++ b/src/test/test_entrynodes.c
@@ -127,6 +127,9 @@ big_fake_network_cleanup(const struct testcase_t *testcase, void *ptr)
return 1; /* NOP */
}
+#define REASONABLY_FUTURE " reasonably-future"
+#define REASONABLY_PAST " reasonably-past"
+
/* Unittest setup function: Setup a fake network. */
static void *
big_fake_network_setup(const struct testcase_t *testcase)
@@ -138,9 +141,10 @@ big_fake_network_setup(const struct testcase_t *testcase)
const int N_NODES = 271;
const char *argument = testcase->setup_data;
- int reasonably_live_consensus = 0;
+ int reasonably_future_consensus = 0, reasonably_past_consensus = 0;
if (argument) {
- reasonably_live_consensus = strstr(argument, "reasonably-live") != NULL;
+ reasonably_future_consensus = strstr(argument, REASONABLY_FUTURE) != NULL;
+ reasonably_past_consensus = strstr(argument, REASONABLY_PAST) != NULL;
}
big_fake_net_nodes = smartlist_new();
@@ -198,11 +202,15 @@ big_fake_network_setup(const struct testcase_t *testcase)
dummy_state = tor_malloc_zero(sizeof(or_state_t));
dummy_consensus = tor_malloc_zero(sizeof(networkstatus_t));
- if (reasonably_live_consensus) {
- /* Make the dummy consensus valid from 4 hours ago, but expired an hour
+ if (reasonably_future_consensus) {
+ /* Make the dummy consensus valid in 6 hours, and expiring in 7 hours. */
+ dummy_consensus->valid_after = approx_time() + 6*3600;
+ dummy_consensus->valid_until = approx_time() + 7*3600;
+ } else if (reasonably_past_consensus) {
+ /* Make the dummy consensus valid from 16 hours ago, but expired 12 hours
* ago. */
- dummy_consensus->valid_after = approx_time() - 4*3600;
- dummy_consensus->valid_until = approx_time() - 3600;
+ dummy_consensus->valid_after = approx_time() - 16*3600;
+ dummy_consensus->valid_until = approx_time() - 12*3600;
} else {
/* Make the dummy consensus valid for an hour either side of now. */
dummy_consensus->valid_after = approx_time() - 3600;
@@ -3038,13 +3046,17 @@ static const struct testcase_setup_t upgrade_circuits = {
#define BFN_TEST(name) \
EN_TEST_BASE(name, TT_FORK, &big_fake_network, NULL), \
- { #name "_reasonably_live", test_entry_guard_ ## name, TT_FORK, \
- &big_fake_network, (void*)("reasonably-live") }
+ { #name "_reasonably_future", test_entry_guard_ ## name, TT_FORK, \
+ &big_fake_network, (void*)(REASONABLY_FUTURE) }, \
+ { #name "_reasonably_past", test_entry_guard_ ## name, TT_FORK, \
+ &big_fake_network, (void*)(REASONABLY_PAST) }
#define UPGRADE_TEST(name, arg) \
EN_TEST_BASE(name, TT_FORK, &upgrade_circuits, arg), \
- { #name "_reasonably_live", test_entry_guard_ ## name, TT_FORK, \
- &upgrade_circuits, (void*)(arg " reasonably-live") }
+ { #name "_reasonably_future", test_entry_guard_ ## name, TT_FORK, \
+ &upgrade_circuits, (void*)(arg REASONABLY_FUTURE) }, \
+ { #name "_reasonably_past", test_entry_guard_ ## name, TT_FORK, \
+ &upgrade_circuits, (void*)(arg REASONABLY_PAST) }
struct testcase_t entrynodes_tests[] = {
NO_PREFIX_TEST(node_preferred_orport),
diff --git a/src/test/test_hs_service.c b/src/test/test_hs_service.c
index b2aafc1cd6..ccb4d93feb 100644
--- a/src/test/test_hs_service.c
+++ b/src/test/test_hs_service.c
@@ -267,7 +267,7 @@ helper_clone_authorized_client(const hs_service_authorized_client_t *client)
/* Helper: Return a newly allocated service object with the identity keypair
* sets and the current descriptor. Then register it to the global map.
- * Caller should us hs_free_all() to free this service or remove it from the
+ * Caller should use hs_free_all() to free this service or remove it from the
* global map before freeing. */
static hs_service_t *
helper_create_service(void)
@@ -289,6 +289,20 @@ helper_create_service(void)
return service;
}
+/* Helper: Deallocate a given service object, its child objects and
+ * remove it from onion service map.
+ * */
+static void
+helper_destroy_service(hs_service_t *service)
+{
+ if (!service)
+ return;
+
+ remove_service(get_hs_service_map(), service);
+
+ hs_service_free(service);
+}
+
/* Helper: Return a newly allocated service object with clients. */
static hs_service_t *
helper_create_service_with_clients(int num_clients)
@@ -1626,6 +1640,7 @@ test_build_descriptors(void *arg)
{
int ret;
time_t now = time(NULL);
+ hs_service_t *last_service = NULL;
(void) arg;
@@ -1650,6 +1665,7 @@ test_build_descriptors(void *arg)
* is disabled. */
{
hs_service_t *service = helper_create_service();
+ last_service = service;
service_descriptor_free(service->desc_current);
service->desc_current = NULL;
@@ -1660,12 +1676,16 @@ test_build_descriptors(void *arg)
hs_desc_superencrypted_data_t *superencrypted;
superencrypted = &service->desc_current->desc->superencrypted_data;
tt_int_op(smartlist_len(superencrypted->clients), OP_EQ, 16);
+
+ helper_destroy_service(service);
+ last_service = NULL;
}
/* Generate a valid number of fake auth clients when the number of
* clients is zero. */
{
hs_service_t *service = helper_create_service_with_clients(0);
+ last_service = service;
service_descriptor_free(service->desc_current);
service->desc_current = NULL;
@@ -1673,12 +1693,16 @@ test_build_descriptors(void *arg)
hs_desc_superencrypted_data_t *superencrypted;
superencrypted = &service->desc_current->desc->superencrypted_data;
tt_int_op(smartlist_len(superencrypted->clients), OP_EQ, 16);
+
+ helper_destroy_service(service);
+ last_service = NULL;
}
/* Generate a valid number of fake auth clients when the number of
* clients is not a multiple of 16. */
{
hs_service_t *service = helper_create_service_with_clients(20);
+ last_service = service;
service_descriptor_free(service->desc_current);
service->desc_current = NULL;
@@ -1686,12 +1710,16 @@ test_build_descriptors(void *arg)
hs_desc_superencrypted_data_t *superencrypted;
superencrypted = &service->desc_current->desc->superencrypted_data;
tt_int_op(smartlist_len(superencrypted->clients), OP_EQ, 32);
+
+ helper_destroy_service(service);
+ last_service = NULL;
}
/* Do not generate any fake desc client when the number of clients is
* a multiple of 16 but not zero. */
{
hs_service_t *service = helper_create_service_with_clients(32);
+ last_service = service;
service_descriptor_free(service->desc_current);
service->desc_current = NULL;
@@ -1699,9 +1727,13 @@ test_build_descriptors(void *arg)
hs_desc_superencrypted_data_t *superencrypted;
superencrypted = &service->desc_current->desc->superencrypted_data;
tt_int_op(smartlist_len(superencrypted->clients), OP_EQ, 32);
+
+ helper_destroy_service(service);
+ last_service = NULL;
}
done:
+ helper_destroy_service(last_service);
hs_free_all();
}
diff --git a/src/test/test_options.c b/src/test/test_options.c
index 376d77626f..6506731823 100644
--- a/src/test/test_options.c
+++ b/src/test/test_options.c
@@ -23,6 +23,10 @@
#include "test/test_helpers.h"
#include "lib/net/resolve.h"
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+
#define NS_MODULE test_options
typedef struct {
diff --git a/src/test/test_routerlist.c b/src/test/test_routerlist.c
index 167b7a35ce..3e1e727429 100644
--- a/src/test/test_routerlist.c
+++ b/src/test/test_routerlist.c
@@ -305,7 +305,6 @@ test_router_pick_directory_server_impl(void *arg)
tt_assert(!networkstatus_consensus_is_bootstrapping(con_md->valid_until
+ 24*60*60));
/* These times are outside the test validity period */
- tt_assert(networkstatus_consensus_is_bootstrapping(now));
tt_assert(networkstatus_consensus_is_bootstrapping(now + 2*24*60*60));
tt_assert(networkstatus_consensus_is_bootstrapping(now - 2*24*60*60));
diff --git a/src/test/test_util.c b/src/test/test_util.c
index b983cbb0bf..5ffe2d6b1a 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -2153,15 +2153,6 @@ test_util_strmisc(void *arg)
tt_int_op(strcmp_opt(NULL, "foo"), OP_LT, 0);
tt_int_op(strcmp_opt("foo", NULL), OP_GT, 0);
- /* Test strcmp_len */
- tt_int_op(strcmp_len("foo", "bar", 3), OP_GT, 0);
- tt_int_op(strcmp_len("foo", "bar", 2), OP_LT, 0);
- tt_int_op(strcmp_len("foo2", "foo1", 4), OP_GT, 0);
- tt_int_op(strcmp_len("foo2", "foo1", 3), OP_LT, 0); /* Really stop at len */
- tt_int_op(strcmp_len("foo2", "foo", 3), OP_EQ, 0); /* Really stop at len */
- tt_int_op(strcmp_len("blah", "", 4), OP_GT, 0);
- tt_int_op(strcmp_len("blah", "", 0), OP_EQ, 0);
-
done:
tor_free(cp_tmp);
}