aboutsummaryrefslogtreecommitdiff
path: root/src/or/rephist.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/or/rephist.c')
-rw-r--r--src/or/rephist.c706
1 files changed, 309 insertions, 397 deletions
diff --git a/src/or/rephist.c b/src/or/rephist.c
index 2844c4d74e..67e4d3150f 100644
--- a/src/or/rephist.c
+++ b/src/or/rephist.c
@@ -84,9 +84,13 @@
#include "router.h"
#include "routerlist.h"
#include "ht.h"
+#include "channelpadding.h"
+
+#include "channelpadding.h"
+#include "connection_or.h"
static void bw_arrays_init(void);
-static void predicted_ports_init(void);
+static void predicted_ports_alloc(void);
/** Total number of bytes currently allocated in fields used by rephist.c. */
uint64_t rephist_total_alloc=0;
@@ -106,38 +110,12 @@ uint32_t rephist_total_num=0;
* 20X as much as one that ended a month ago, and routers that have had no
* uptime data for about half a year will get forgotten.) */
-/** History of an OR-\>OR link. */
-typedef struct link_history_t {
- /** When did we start tracking this list? */
- time_t since;
- /** When did we most recently note a change to this link */
- time_t changed;
- /** How many times did extending from OR1 to OR2 succeed? */
- unsigned long n_extend_ok;
- /** How many times did extending from OR1 to OR2 fail? */
- unsigned long n_extend_fail;
-} link_history_t;
-
/** History of an OR. */
typedef struct or_history_t {
/** When did we start tracking this OR? */
time_t since;
/** When did we most recently note a change to this OR? */
time_t changed;
- /** How many times did we successfully connect? */
- unsigned long n_conn_ok;
- /** How many times did we try to connect and fail?*/
- unsigned long n_conn_fail;
- /** How many seconds have we been connected to this OR before
- * 'up_since'? */
- unsigned long uptime;
- /** How many seconds have we been unable to connect to this OR before
- * 'down_since'? */
- unsigned long downtime;
- /** If nonzero, we have been connected since this time. */
- time_t up_since;
- /** If nonzero, we have been unable to connect since this time. */
- time_t down_since;
/** The address at which we most recently connected to this OR
* successfully. */
@@ -159,12 +137,46 @@ typedef struct or_history_t {
time_t start_of_downtime;
unsigned long weighted_uptime;
unsigned long total_weighted_time;
-
- /** Map from hex OR2 identity digest to a link_history_t for the link
- * from this OR to OR2. */
- digestmap_t *link_history_map;
} or_history_t;
+/**
+ * This structure holds accounting needed to calculate the padding overhead.
+ */
+typedef struct padding_counts_t {
+ /** Total number of cells we have received, including padding */
+ uint64_t read_cell_count;
+ /** Total number of cells we have sent, including padding */
+ uint64_t write_cell_count;
+ /** Total number of CELL_PADDING cells we have received */
+ uint64_t read_pad_cell_count;
+ /** Total number of CELL_PADDING cells we have sent */
+ uint64_t write_pad_cell_count;
+ /** Total number of read cells on padding-enabled conns */
+ uint64_t enabled_read_cell_count;
+ /** Total number of sent cells on padding-enabled conns */
+ uint64_t enabled_write_cell_count;
+ /** Total number of read CELL_PADDING cells on padding-enabled cons */
+ uint64_t enabled_read_pad_cell_count;
+ /** Total number of sent CELL_PADDING cells on padding-enabled cons */
+ uint64_t enabled_write_pad_cell_count;
+ /** Total number of RELAY_DROP cells we have received */
+ uint64_t read_drop_cell_count;
+ /** Total number of RELAY_DROP cells we have sent */
+ uint64_t write_drop_cell_count;
+ /** The maximum number of padding timers we've seen in 24 hours */
+ uint64_t maximum_chanpad_timers;
+ /** When did we first copy padding_current into padding_published? */
+ char first_published_at[ISO_TIME_LEN+1];
+} padding_counts_t;
+
+/** Holds the current values of our padding statistics.
+ * It is not published until it is transferred to padding_published. */
+static padding_counts_t padding_current;
+
+/** Remains fixed for a 24 hour period, and then is replaced
+ * by a redacted copy of padding_current */
+static padding_counts_t padding_published;
+
/** When did we last multiply all routers' weighted_run_length and
* total_run_weights by STABILITY_ALPHA? */
static time_t stability_last_downrated = 0;
@@ -190,7 +202,6 @@ get_or_history(const char* id)
hist = tor_malloc_zero(sizeof(or_history_t));
rephist_total_alloc += sizeof(or_history_t);
rephist_total_num++;
- hist->link_history_map = digestmap_new();
hist->since = hist->changed = time(NULL);
tor_addr_make_unspec(&hist->last_reached_addr);
digestmap_set(history_map, id, hist);
@@ -198,166 +209,23 @@ get_or_history(const char* id)
return hist;
}
-/** Return the link_history_t for the link from the first named OR to
- * the second, creating it if necessary. (ORs are identified by
- * identity digest.)
- */
-static link_history_t *
-get_link_history(const char *from_id, const char *to_id)
-{
- or_history_t *orhist;
- link_history_t *lhist;
- orhist = get_or_history(from_id);
- if (!orhist)
- return NULL;
- if (tor_digest_is_zero(to_id))
- return NULL;
- lhist = digestmap_get(orhist->link_history_map, to_id);
- if (!lhist) {
- lhist = tor_malloc_zero(sizeof(link_history_t));
- rephist_total_alloc += sizeof(link_history_t);
- lhist->since = lhist->changed = time(NULL);
- digestmap_set(orhist->link_history_map, to_id, lhist);
- }
- return lhist;
-}
-
-/** Helper: free storage held by a single link history entry. */
-static void
-free_link_history_(void *val)
-{
- rephist_total_alloc -= sizeof(link_history_t);
- tor_free(val);
-}
-
/** Helper: free storage held by a single OR history entry. */
static void
free_or_history(void *_hist)
{
or_history_t *hist = _hist;
- digestmap_free(hist->link_history_map, free_link_history_);
rephist_total_alloc -= sizeof(or_history_t);
rephist_total_num--;
tor_free(hist);
}
-/** Update an or_history_t object <b>hist</b> so that its uptime/downtime
- * count is up-to-date as of <b>when</b>.
- */
-static void
-update_or_history(or_history_t *hist, time_t when)
-{
- tor_assert(hist);
- if (hist->up_since) {
- tor_assert(!hist->down_since);
- hist->uptime += (when - hist->up_since);
- hist->up_since = when;
- } else if (hist->down_since) {
- hist->downtime += (when - hist->down_since);
- hist->down_since = when;
- }
-}
-
/** Initialize the static data structures for tracking history. */
void
rep_hist_init(void)
{
history_map = digestmap_new();
bw_arrays_init();
- predicted_ports_init();
-}
-
-/** Helper: note that we are no longer connected to the router with history
- * <b>hist</b>. If <b>failed</b>, the connection failed; otherwise, it was
- * closed correctly. */
-static void
-mark_or_down(or_history_t *hist, time_t when, int failed)
-{
- if (hist->up_since) {
- hist->uptime += (when - hist->up_since);
- hist->up_since = 0;
- }
- if (failed && !hist->down_since) {
- hist->down_since = when;
- }
-}
-
-/** Helper: note that we are connected to the router with history
- * <b>hist</b>. */
-static void
-mark_or_up(or_history_t *hist, time_t when)
-{
- if (hist->down_since) {
- hist->downtime += (when - hist->down_since);
- hist->down_since = 0;
- }
- if (!hist->up_since) {
- hist->up_since = when;
- }
-}
-
-/** Remember that an attempt to connect to the OR with identity digest
- * <b>id</b> failed at <b>when</b>.
- */
-void
-rep_hist_note_connect_failed(const char* id, time_t when)
-{
- or_history_t *hist;
- hist = get_or_history(id);
- if (!hist)
- return;
- ++hist->n_conn_fail;
- mark_or_down(hist, when, 1);
- hist->changed = when;
-}
-
-/** Remember that an attempt to connect to the OR with identity digest
- * <b>id</b> succeeded at <b>when</b>.
- */
-void
-rep_hist_note_connect_succeeded(const char* id, time_t when)
-{
- or_history_t *hist;
- hist = get_or_history(id);
- if (!hist)
- return;
- ++hist->n_conn_ok;
- mark_or_up(hist, when);
- hist->changed = when;
-}
-
-/** Remember that we intentionally closed our connection to the OR
- * with identity digest <b>id</b> at <b>when</b>.
- */
-void
-rep_hist_note_disconnect(const char* id, time_t when)
-{
- or_history_t *hist;
- hist = get_or_history(id);
- if (!hist)
- return;
- mark_or_down(hist, when, 0);
- hist->changed = when;
-}
-
-/** Remember that our connection to the OR with identity digest
- * <b>id</b> had an error and stopped working at <b>when</b>.
- */
-void
-rep_hist_note_connection_died(const char* id, time_t when)
-{
- or_history_t *hist;
- if (!id) {
- /* If conn has no identity, it didn't complete its handshake, or something
- * went wrong. Ignore it.
- */
- return;
- }
- hist = get_or_history(id);
- if (!hist)
- return;
- mark_or_down(hist, when, 1);
- hist->changed = when;
+ predicted_ports_alloc();
}
/** We have just decided that this router with identity digest <b>id</b> is
@@ -496,7 +364,6 @@ rep_hist_make_router_pessimal(const char *id, time_t when)
tor_assert(hist);
rep_hist_note_router_unreachable(id, when);
- mark_or_down(hist, when, 1);
hist->weighted_run_length = 0;
hist->weighted_uptime = 0;
@@ -673,57 +540,17 @@ rep_hist_have_measured_enough_stability(void)
return started_tracking_stability < time(NULL) - 4*60*60;
}
-/** Remember that we successfully extended from the OR with identity
- * digest <b>from_id</b> to the OR with identity digest
- * <b>to_name</b>.
- */
-void
-rep_hist_note_extend_succeeded(const char *from_id, const char *to_id)
-{
- link_history_t *hist;
- /* log_fn(LOG_WARN, "EXTEND SUCCEEDED: %s->%s",from_name,to_name); */
- hist = get_link_history(from_id, to_id);
- if (!hist)
- return;
- ++hist->n_extend_ok;
- hist->changed = time(NULL);
-}
-
-/** Remember that we tried to extend from the OR with identity digest
- * <b>from_id</b> to the OR with identity digest <b>to_name</b>, but
- * failed.
- */
-void
-rep_hist_note_extend_failed(const char *from_id, const char *to_id)
-{
- link_history_t *hist;
- /* log_fn(LOG_WARN, "EXTEND FAILED: %s->%s",from_name,to_name); */
- hist = get_link_history(from_id, to_id);
- if (!hist)
- return;
- ++hist->n_extend_fail;
- hist->changed = time(NULL);
-}
-
/** Log all the reliability data we have remembered, with the chosen
* severity.
*/
void
rep_hist_dump_stats(time_t now, int severity)
{
- digestmap_iter_t *lhist_it;
digestmap_iter_t *orhist_it;
- const char *name1, *name2, *digest1, *digest2;
+ const char *name1, *digest1;
char hexdigest1[HEX_DIGEST_LEN+1];
- char hexdigest2[HEX_DIGEST_LEN+1];
or_history_t *or_history;
- link_history_t *link_history;
- void *or_history_p, *link_history_p;
- double uptime;
- char buffer[2048];
- size_t len;
- int ret;
- unsigned long upt, downt;
+ void *or_history_p;
const node_t *node;
rep_history_clean(now - get_options()->RephistTrackTime);
@@ -743,52 +570,12 @@ rep_hist_dump_stats(time_t now, int severity)
else
name1 = "(unknown)";
base16_encode(hexdigest1, sizeof(hexdigest1), digest1, DIGEST_LEN);
- update_or_history(or_history, now);
- upt = or_history->uptime;
- downt = or_history->downtime;
s = get_stability(or_history, now);
stability = (long)s;
- if (upt+downt) {
- uptime = ((double)upt) / (upt+downt);
- } else {
- uptime=1.0;
- }
tor_log(severity, LD_HIST,
- "OR %s [%s]: %ld/%ld good connections; uptime %ld/%ld sec (%.2f%%); "
- "wmtbf %lu:%02lu:%02lu",
+ "OR %s [%s]: wmtbf %lu:%02lu:%02lu",
name1, hexdigest1,
- or_history->n_conn_ok, or_history->n_conn_fail+or_history->n_conn_ok,
- upt, upt+downt, uptime*100.0,
stability/3600, (stability/60)%60, stability%60);
-
- if (!digestmap_isempty(or_history->link_history_map)) {
- strlcpy(buffer, " Extend attempts: ", sizeof(buffer));
- len = strlen(buffer);
- for (lhist_it = digestmap_iter_init(or_history->link_history_map);
- !digestmap_iter_done(lhist_it);
- lhist_it = digestmap_iter_next(or_history->link_history_map,
- lhist_it)) {
- digestmap_iter_get(lhist_it, &digest2, &link_history_p);
- if ((node = node_get_by_id(digest2)) && node_get_nickname(node))
- name2 = node_get_nickname(node);
- else
- name2 = "(unknown)";
-
- link_history = (link_history_t*) link_history_p;
-
- base16_encode(hexdigest2, sizeof(hexdigest2), digest2, DIGEST_LEN);
- ret = tor_snprintf(buffer+len, 2048-len, "%s [%s](%ld/%ld); ",
- name2,
- hexdigest2,
- link_history->n_extend_ok,
- link_history->n_extend_ok+link_history->n_extend_fail);
- if (ret<0)
- break;
- else
- len += ret;
- }
- tor_log(severity, LD_HIST, "%s", buffer);
- }
}
}
@@ -800,10 +587,9 @@ rep_history_clean(time_t before)
{
int authority = authdir_mode(get_options());
or_history_t *or_history;
- link_history_t *link_history;
- void *or_history_p, *link_history_p;
- digestmap_iter_t *orhist_it, *lhist_it;
- const char *d1, *d2;
+ void *or_history_p;
+ digestmap_iter_t *orhist_it;
+ const char *d1;
orhist_it = digestmap_iter_init(history_map);
while (!digestmap_iter_done(orhist_it)) {
@@ -820,19 +606,6 @@ rep_history_clean(time_t before)
free_or_history(or_history);
continue;
}
- for (lhist_it = digestmap_iter_init(or_history->link_history_map);
- !digestmap_iter_done(lhist_it); ) {
- digestmap_iter_get(lhist_it, &d2, &link_history_p);
- link_history = link_history_p;
- if (link_history->changed < before) {
- lhist_it = digestmap_iter_next_rmv(or_history->link_history_map,
- lhist_it);
- rephist_total_alloc -= sizeof(link_history_t);
- tor_free(link_history);
- continue;
- }
- lhist_it = digestmap_iter_next(or_history->link_history_map,lhist_it);
- }
orhist_it = digestmap_iter_next(history_map, orhist_it);
}
}
@@ -905,9 +678,9 @@ rep_hist_record_mtbf_data(time_t now, int missing_means_down)
base16_encode(dbuf, sizeof(dbuf), digest, DIGEST_LEN);
if (missing_means_down && hist->start_of_run &&
- !router_get_by_id_digest(digest)) {
+ !connection_or_digest_is_known_relay(digest)) {
/* We think this relay is running, but it's not listed in our
- * routerlist. Somehow it fell out without telling us it went
+ * consensus. Somehow it fell out without telling us it went
* down. Complain and also correct it. */
log_info(LD_HIST,
"Relay '%s' is listed as up in rephist, but it's not in "
@@ -1316,9 +1089,12 @@ bw_array_new(void)
return b;
}
+#define bw_array_free(val) \
+ FREE_AND_NULL(bw_array_t, bw_array_free_, (val))
+
/** Free storage held by bandwidth array <b>b</b>. */
static void
-bw_array_free(bw_array_t *b)
+bw_array_free_(bw_array_t *b)
{
if (!b) {
return;
@@ -1758,6 +1534,42 @@ typedef struct predicted_port_t {
/** A list of port numbers that have been used recently. */
static smartlist_t *predicted_ports_list=NULL;
+/** How long do we keep predicting circuits? */
+static int prediction_timeout=0;
+/** When was the last time we added a prediction entry (HS or port) */
+static time_t last_prediction_add_time=0;
+
+/**
+ * How much time left until we stop predicting circuits?
+ */
+int
+predicted_ports_prediction_time_remaining(time_t now)
+{
+ time_t idle_delta;
+
+ /* Protect against overflow of return value. This can happen if the clock
+ * jumps backwards in time. Update the last prediction time (aka last
+ * active time) to prevent it. This update is preferable to using monotonic
+ * time because it prevents clock jumps into the past from simply causing
+ * very long idle timeouts while the monotonic time stands still. */
+ if (last_prediction_add_time > now) {
+ last_prediction_add_time = now;
+ idle_delta = 0;
+ } else {
+ idle_delta = now - last_prediction_add_time;
+ }
+
+ /* Protect against underflow of the return value. This can happen for very
+ * large periods of inactivity/system sleep. */
+ if (idle_delta > prediction_timeout)
+ return 0;
+
+ if (BUG((prediction_timeout - idle_delta) > INT_MAX)) {
+ return INT_MAX;
+ }
+
+ return (int)(prediction_timeout - idle_delta);
+}
/** We just got an application request for a connection with
* port <b>port</b>. Remember it for the future, so we can keep
@@ -1767,28 +1579,47 @@ static void
add_predicted_port(time_t now, uint16_t port)
{
predicted_port_t *pp = tor_malloc(sizeof(predicted_port_t));
+
+ // If the list is empty, re-randomize predicted ports lifetime
+ if (!any_predicted_circuits(now)) {
+ prediction_timeout = channelpadding_get_circuits_available_timeout();
+ }
+
+ last_prediction_add_time = now;
+
+ log_info(LD_CIRC,
+ "New port prediction added. Will continue predictive circ building "
+ "for %d more seconds.",
+ predicted_ports_prediction_time_remaining(now));
+
pp->port = port;
pp->time = now;
rephist_total_alloc += sizeof(*pp);
smartlist_add(predicted_ports_list, pp);
}
-/** Initialize whatever memory and structs are needed for predicting
+/**
+ * Allocate whatever memory and structs are needed for predicting
* which ports will be used. Also seed it with port 80, so we'll build
* circuits on start-up.
*/
static void
-predicted_ports_init(void)
+predicted_ports_alloc(void)
{
predicted_ports_list = smartlist_new();
- add_predicted_port(time(NULL), 80); /* add one to kickstart us */
+}
+
+void
+predicted_ports_init(void)
+{
+ add_predicted_port(time(NULL), 443); // Add a port to get us started
}
/** Free whatever memory is needed for predicting which ports will
* be used.
*/
static void
-predicted_ports_free(void)
+predicted_ports_free_all(void)
{
rephist_total_alloc -=
smartlist_len(predicted_ports_list)*sizeof(predicted_port_t);
@@ -1812,6 +1643,12 @@ rep_hist_note_used_port(time_t now, uint16_t port)
SMARTLIST_FOREACH_BEGIN(predicted_ports_list, predicted_port_t *, pp) {
if (pp->port == port) {
pp->time = now;
+
+ last_prediction_add_time = now;
+ log_info(LD_CIRC,
+ "New port prediction added. Will continue predictive circ "
+ "building for %d more seconds.",
+ predicted_ports_prediction_time_remaining(now));
return;
}
} SMARTLIST_FOREACH_END(pp);
@@ -1828,7 +1665,8 @@ rep_hist_get_predicted_ports(time_t now)
int predicted_circs_relevance_time;
smartlist_t *out = smartlist_new();
tor_assert(predicted_ports_list);
- predicted_circs_relevance_time = get_options()->PredictedPortsRelevanceTime;
+
+ predicted_circs_relevance_time = prediction_timeout;
/* clean out obsolete entries */
SMARTLIST_FOREACH_BEGIN(predicted_ports_list, predicted_port_t *, pp) {
@@ -1888,6 +1726,18 @@ static time_t predicted_internal_capacity_time = 0;
void
rep_hist_note_used_internal(time_t now, int need_uptime, int need_capacity)
{
+ // If the list is empty, re-randomize predicted ports lifetime
+ if (!any_predicted_circuits(now)) {
+ prediction_timeout = channelpadding_get_circuits_available_timeout();
+ }
+
+ last_prediction_add_time = now;
+
+ log_info(LD_CIRC,
+ "New port prediction added. Will continue predictive circ building "
+ "for %d more seconds.",
+ predicted_ports_prediction_time_remaining(now));
+
predicted_internal_time = now;
if (need_uptime)
predicted_internal_uptime_time = now;
@@ -1901,7 +1751,8 @@ rep_hist_get_predicted_internal(time_t now, int *need_uptime,
int *need_capacity)
{
int predicted_circs_relevance_time;
- predicted_circs_relevance_time = get_options()->PredictedPortsRelevanceTime;
+
+ predicted_circs_relevance_time = prediction_timeout;
if (!predicted_internal_time) { /* initialize it */
predicted_internal_time = now;
@@ -1923,7 +1774,7 @@ int
any_predicted_circuits(time_t now)
{
int predicted_circs_relevance_time;
- predicted_circs_relevance_time = get_options()->PredictedPortsRelevanceTime;
+ predicted_circs_relevance_time = prediction_timeout;
return smartlist_len(predicted_ports_list) ||
predicted_internal_time + predicted_circs_relevance_time >= now;
@@ -1949,105 +1800,6 @@ rep_hist_circbuilding_dormant(time_t now)
return 1;
}
-/** Structure to track how many times we've done each public key operation. */
-static struct {
- /** How many directory objects have we signed? */
- unsigned long n_signed_dir_objs;
- /** How many routerdescs have we signed? */
- unsigned long n_signed_routerdescs;
- /** How many directory objects have we verified? */
- unsigned long n_verified_dir_objs;
- /** How many routerdescs have we verified */
- unsigned long n_verified_routerdescs;
- /** How many onionskins have we encrypted to build circuits? */
- unsigned long n_onionskins_encrypted;
- /** How many onionskins have we decrypted to do circuit build requests? */
- unsigned long n_onionskins_decrypted;
- /** How many times have we done the TLS handshake as a client? */
- unsigned long n_tls_client_handshakes;
- /** How many times have we done the TLS handshake as a server? */
- unsigned long n_tls_server_handshakes;
- /** How many PK operations have we done as a hidden service client? */
- unsigned long n_rend_client_ops;
- /** How many PK operations have we done as a hidden service midpoint? */
- unsigned long n_rend_mid_ops;
- /** How many PK operations have we done as a hidden service provider? */
- unsigned long n_rend_server_ops;
-} pk_op_counts = {0,0,0,0,0,0,0,0,0,0,0};
-
-/** Increment the count of the number of times we've done <b>operation</b>. */
-void
-note_crypto_pk_op(pk_op_t operation)
-{
- switch (operation)
- {
- case SIGN_DIR:
- pk_op_counts.n_signed_dir_objs++;
- break;
- case SIGN_RTR:
- pk_op_counts.n_signed_routerdescs++;
- break;
- case VERIFY_DIR:
- pk_op_counts.n_verified_dir_objs++;
- break;
- case VERIFY_RTR:
- pk_op_counts.n_verified_routerdescs++;
- break;
- case ENC_ONIONSKIN:
- pk_op_counts.n_onionskins_encrypted++;
- break;
- case DEC_ONIONSKIN:
- pk_op_counts.n_onionskins_decrypted++;
- break;
- case TLS_HANDSHAKE_C:
- pk_op_counts.n_tls_client_handshakes++;
- break;
- case TLS_HANDSHAKE_S:
- pk_op_counts.n_tls_server_handshakes++;
- break;
- case REND_CLIENT:
- pk_op_counts.n_rend_client_ops++;
- break;
- case REND_MID:
- pk_op_counts.n_rend_mid_ops++;
- break;
- case REND_SERVER:
- pk_op_counts.n_rend_server_ops++;
- break;
- default:
- log_warn(LD_BUG, "Unknown pk operation %d", operation);
- }
-}
-
-/** Log the number of times we've done each public/private-key operation. */
-void
-dump_pk_ops(int severity)
-{
- tor_log(severity, LD_HIST,
- "PK operations: %lu directory objects signed, "
- "%lu directory objects verified, "
- "%lu routerdescs signed, "
- "%lu routerdescs verified, "
- "%lu onionskins encrypted, "
- "%lu onionskins decrypted, "
- "%lu client-side TLS handshakes, "
- "%lu server-side TLS handshakes, "
- "%lu rendezvous client operations, "
- "%lu rendezvous middle operations, "
- "%lu rendezvous server operations.",
- pk_op_counts.n_signed_dir_objs,
- pk_op_counts.n_verified_dir_objs,
- pk_op_counts.n_signed_routerdescs,
- pk_op_counts.n_verified_routerdescs,
- pk_op_counts.n_onionskins_encrypted,
- pk_op_counts.n_onionskins_decrypted,
- pk_op_counts.n_tls_client_handshakes,
- pk_op_counts.n_tls_server_handshakes,
- pk_op_counts.n_rend_client_ops,
- pk_op_counts.n_rend_mid_ops,
- pk_op_counts.n_rend_server_ops);
-}
-
/*** Exit port statistics ***/
/* Some constants */
@@ -2536,7 +2288,7 @@ rep_hist_format_buffer_stats(time_t now)
processed_cells_string,
queued_cells_string,
time_in_queue_string,
- (number_of_circuits + SHARES - 1) / SHARES);
+ CEIL_DIV(number_of_circuits, SHARES));
tor_free(processed_cells_string);
tor_free(queued_cells_string);
tor_free(time_in_queue_string);
@@ -2715,7 +2467,7 @@ rep_hist_desc_stats_write(time_t now)
}
/** Called to note that we've served a given descriptor (by
- * digest). Incrememnts the count of descriptors served, and the number
+ * digest). Increments the count of descriptors served, and the number
* of times we've served this descriptor. */
void
rep_hist_note_desc_served(const char * desc)
@@ -2812,7 +2564,7 @@ HT_GENERATE2(bidimap, bidi_map_entry_t, node, bidi_map_ent_hash,
/* DOCDOC bidi_map_free */
static void
-bidi_map_free(void)
+bidi_map_free_all(void)
{
bidi_map_entry_t **ptr, **next, *ent;
for (ptr = HT_START(bidimap, &bidi_map); ptr; ptr = next) {
@@ -2832,7 +2584,7 @@ rep_hist_reset_conn_stats(time_t now)
mostly_read = 0;
mostly_written = 0;
both_read_and_written = 0;
- bidi_map_free();
+ bidi_map_free_all();
}
/** Stop collecting connection stats in a way that we can re-start doing
@@ -3021,9 +2773,12 @@ hs_stats_new(void)
return new_hs_stats;
}
+#define hs_stats_free(val) \
+ FREE_AND_NULL(hs_stats_t, hs_stats_free_, (val))
+
/** Free an hs_stats_t structure. */
static void
-hs_stats_free(hs_stats_t *victim_hs_stats)
+hs_stats_free_(hs_stats_t *victim_hs_stats)
{
if (!victim_hs_stats) {
return;
@@ -3210,8 +2965,7 @@ rep_hist_hs_stats_write(time_t now)
return start_of_hs_stats_interval + WRITE_STATS_INTERVAL;
}
-#define MAX_LINK_PROTO_TO_LOG 4
-static uint64_t link_proto_count[MAX_LINK_PROTO_TO_LOG+1][2];
+static uint64_t link_proto_count[MAX_LINK_PROTO+1][2];
/** Note that we negotiated link protocol version <b>link_proto</b>, on
* a connection that started here iff <b>started_here</b> is true.
@@ -3220,7 +2974,7 @@ void
rep_hist_note_negotiated_link_proto(unsigned link_proto, int started_here)
{
started_here = !!started_here; /* force to 0 or 1 */
- if (link_proto > MAX_LINK_PROTO_TO_LOG) {
+ if (link_proto > MAX_LINK_PROTO) {
log_warn(LD_BUG, "Can't log link protocol %u", link_proto);
return;
}
@@ -3228,6 +2982,165 @@ rep_hist_note_negotiated_link_proto(unsigned link_proto, int started_here)
link_proto_count[link_proto][started_here]++;
}
+/**
+ * Update the maximum count of total pending channel padding timers
+ * in this period.
+ */
+void
+rep_hist_padding_count_timers(uint64_t num_timers)
+{
+ if (num_timers > padding_current.maximum_chanpad_timers) {
+ padding_current.maximum_chanpad_timers = num_timers;
+ }
+}
+
+/**
+ * Count a cell that we sent for padding overhead statistics.
+ *
+ * RELAY_COMMAND_DROP and CELL_PADDING are accounted separately. Both should be
+ * counted for PADDING_TYPE_TOTAL.
+ */
+void
+rep_hist_padding_count_write(padding_type_t type)
+{
+ switch (type) {
+ case PADDING_TYPE_DROP:
+ padding_current.write_drop_cell_count++;
+ break;
+ case PADDING_TYPE_CELL:
+ padding_current.write_pad_cell_count++;
+ break;
+ case PADDING_TYPE_TOTAL:
+ padding_current.write_cell_count++;
+ break;
+ case PADDING_TYPE_ENABLED_TOTAL:
+ padding_current.enabled_write_cell_count++;
+ break;
+ case PADDING_TYPE_ENABLED_CELL:
+ padding_current.enabled_write_pad_cell_count++;
+ break;
+ }
+}
+
+/**
+ * Count a cell that we've received for padding overhead statistics.
+ *
+ * RELAY_COMMAND_DROP and CELL_PADDING are accounted separately. Both should be
+ * counted for PADDING_TYPE_TOTAL.
+ */
+void
+rep_hist_padding_count_read(padding_type_t type)
+{
+ switch (type) {
+ case PADDING_TYPE_DROP:
+ padding_current.read_drop_cell_count++;
+ break;
+ case PADDING_TYPE_CELL:
+ padding_current.read_pad_cell_count++;
+ break;
+ case PADDING_TYPE_TOTAL:
+ padding_current.read_cell_count++;
+ break;
+ case PADDING_TYPE_ENABLED_TOTAL:
+ padding_current.enabled_read_cell_count++;
+ break;
+ case PADDING_TYPE_ENABLED_CELL:
+ padding_current.enabled_read_pad_cell_count++;
+ break;
+ }
+}
+
+/**
+ * Reset our current padding statistics. Called once every 24 hours.
+ */
+void
+rep_hist_reset_padding_counts(void)
+{
+ memset(&padding_current, 0, sizeof(padding_current));
+}
+
+/**
+ * Copy our current cell counts into a structure for listing in our
+ * extra-info descriptor. Also perform appropriate rounding and redaction.
+ *
+ * This function is called once every 24 hours.
+ */
+#define MIN_CELL_COUNTS_TO_PUBLISH 1
+#define ROUND_CELL_COUNTS_TO 10000
+void
+rep_hist_prep_published_padding_counts(time_t now)
+{
+ memcpy(&padding_published, &padding_current, sizeof(padding_published));
+
+ if (padding_published.read_cell_count < MIN_CELL_COUNTS_TO_PUBLISH ||
+ padding_published.write_cell_count < MIN_CELL_COUNTS_TO_PUBLISH) {
+ memset(&padding_published, 0, sizeof(padding_published));
+ return;
+ }
+
+ format_iso_time(padding_published.first_published_at, now);
+#define ROUND_AND_SET_COUNT(x) (x) = round_uint64_to_next_multiple_of((x), \
+ ROUND_CELL_COUNTS_TO)
+ ROUND_AND_SET_COUNT(padding_published.read_pad_cell_count);
+ ROUND_AND_SET_COUNT(padding_published.write_pad_cell_count);
+ ROUND_AND_SET_COUNT(padding_published.read_drop_cell_count);
+ ROUND_AND_SET_COUNT(padding_published.write_drop_cell_count);
+ ROUND_AND_SET_COUNT(padding_published.write_cell_count);
+ ROUND_AND_SET_COUNT(padding_published.read_cell_count);
+ ROUND_AND_SET_COUNT(padding_published.enabled_read_cell_count);
+ ROUND_AND_SET_COUNT(padding_published.enabled_read_pad_cell_count);
+ ROUND_AND_SET_COUNT(padding_published.enabled_write_cell_count);
+ ROUND_AND_SET_COUNT(padding_published.enabled_write_pad_cell_count);
+#undef ROUND_AND_SET_COUNT
+}
+
+/**
+ * Returns an allocated string for extra-info documents for publishing
+ * padding statistics from the last 24 hour interval.
+ */
+char *
+rep_hist_get_padding_count_lines(void)
+{
+ char *result = NULL;
+
+ if (!padding_published.read_cell_count ||
+ !padding_published.write_cell_count) {
+ return NULL;
+ }
+
+ tor_asprintf(&result, "padding-counts %s (%d s)"
+ " bin-size="U64_FORMAT
+ " write-drop="U64_FORMAT
+ " write-pad="U64_FORMAT
+ " write-total="U64_FORMAT
+ " read-drop="U64_FORMAT
+ " read-pad="U64_FORMAT
+ " read-total="U64_FORMAT
+ " enabled-read-pad="U64_FORMAT
+ " enabled-read-total="U64_FORMAT
+ " enabled-write-pad="U64_FORMAT
+ " enabled-write-total="U64_FORMAT
+ " max-chanpad-timers="U64_FORMAT
+ "\n",
+ padding_published.first_published_at,
+ REPHIST_CELL_PADDING_COUNTS_INTERVAL,
+ U64_PRINTF_ARG(ROUND_CELL_COUNTS_TO),
+ U64_PRINTF_ARG(padding_published.write_drop_cell_count),
+ U64_PRINTF_ARG(padding_published.write_pad_cell_count),
+ U64_PRINTF_ARG(padding_published.write_cell_count),
+ U64_PRINTF_ARG(padding_published.read_drop_cell_count),
+ U64_PRINTF_ARG(padding_published.read_pad_cell_count),
+ U64_PRINTF_ARG(padding_published.read_cell_count),
+ U64_PRINTF_ARG(padding_published.enabled_read_pad_cell_count),
+ U64_PRINTF_ARG(padding_published.enabled_read_cell_count),
+ U64_PRINTF_ARG(padding_published.enabled_write_pad_cell_count),
+ U64_PRINTF_ARG(padding_published.enabled_write_cell_count),
+ U64_PRINTF_ARG(padding_published.maximum_chanpad_timers)
+ );
+
+ return result;
+}
+
/** Log a heartbeat message explaining how many connections of each link
* protocol version we have used.
*/
@@ -3277,8 +3190,8 @@ rep_hist_free_all(void)
tor_free(exit_bytes_read);
tor_free(exit_bytes_written);
tor_free(exit_streams);
- predicted_ports_free();
- bidi_map_free();
+ predicted_ports_free_all();
+ bidi_map_free_all();
if (circuits_for_buffer_stats) {
SMARTLIST_FOREACH(circuits_for_buffer_stats, circ_buffer_stats_t *, s,
@@ -3292,4 +3205,3 @@ rep_hist_free_all(void)
tor_assert_nonfatal(rephist_total_alloc == 0);
tor_assert_nonfatal_once(rephist_total_num == 0);
}
-