tor-commits
Threads by month
- ----- 2025 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
November 2018
- 19 participants
- 2292 discussions

15 Nov '18
commit c56f63eadbc5b83b48e57235b194bd8f76b534bb
Author: Mike Perry <mikeperry-git(a)torproject.org>
Date: Sat Aug 4 19:38:38 2018 +0000
Ticket #25573: Track half-closed stream ids
We allow their CONNECTEDs, RESOLVEDs, ENDs, SENDMEs, and DATA cells to not
count as dropped until the windows are empty, or we get an END.
This commit does not change behavior. It only changes CIRC_BW event field
values.
---
changes/ticket25573 | 5 +
src/or/circpathbias.c | 53 +++++
src/or/circpathbias.h | 1 +
src/or/circuitlist.c | 8 +
src/or/connection_edge.c | 220 ++++++++++++++++++
src/or/connection_edge.h | 11 +
src/or/or.h | 25 +++
src/or/relay.c | 66 +++++-
src/test/test_relaycell.c | 561 +++++++++++++++++++++++++++++++++++++++++++---
9 files changed, 912 insertions(+), 38 deletions(-)
diff --git a/changes/ticket25573 b/changes/ticket25573
new file mode 100644
index 000000000..9939601b5
--- /dev/null
+++ b/changes/ticket25573
@@ -0,0 +1,5 @@
+ o Minor features (controller):
+ - For purposes of CIRC_BW-based dropped cell detection, track half-closed
+ stream ids, and allow their ENDs, SENDMEs, DATA and path bias check
+ cells to arrive without counting it as dropped until either the END arrvies,
+ or the windows are empty. Closes ticket 25573.
diff --git a/src/or/circpathbias.c b/src/or/circpathbias.c
index ff42bf91e..923941e5b 100644
--- a/src/or/circpathbias.c
+++ b/src/or/circpathbias.c
@@ -893,6 +893,7 @@ pathbias_check_probe_response(circuit_t *circ, const cell_t *cell)
/* Check nonce */
if (ipv4_host == ocirc->pathbias_probe_nonce) {
pathbias_mark_use_success(ocirc);
+ circuit_read_valid_data(ocirc, rh.length);
circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
log_info(LD_CIRC,
"Got valid path bias probe back for circ %d, stream %d.",
@@ -914,6 +915,58 @@ pathbias_check_probe_response(circuit_t *circ, const cell_t *cell)
}
/**
+ * Check if a cell is counts as valid data for a circuit,
+ * and if so, count it as valid.
+ */
+void
+pathbias_count_valid_cells(circuit_t *circ, const cell_t *cell)
+{
+ origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
+ relay_header_t rh;
+
+ relay_header_unpack(&rh, cell->payload);
+
+ /* Check to see if this is a cell from a previous connection,
+ * or is a request to close the circuit. */
+ switch (rh.command) {
+ case RELAY_COMMAND_END:
+ if (connection_half_edge_is_valid_end(ocirc->half_streams,
+ rh.stream_id)) {
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh.length);
+ }
+ break;
+
+ case RELAY_COMMAND_DATA:
+ if (connection_half_edge_is_valid_data(ocirc->half_streams,
+ rh.stream_id)) {
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh.length);
+ }
+ break;
+
+ case RELAY_COMMAND_SENDME:
+ if (connection_half_edge_is_valid_sendme(ocirc->half_streams,
+ rh.stream_id)) {
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh.length);
+ }
+ break;
+
+ case RELAY_COMMAND_CONNECTED:
+ if (connection_half_edge_is_valid_connected(ocirc->half_streams,
+ rh.stream_id)) {
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh.length);
+ }
+ break;
+
+ case RELAY_COMMAND_RESOLVED:
+ if (connection_half_edge_is_valid_resolved(ocirc->half_streams,
+ rh.stream_id)) {
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ), rh.length);
+ }
+ break;
+ }
+}
+
+/**
* Check if a circuit was used and/or closed successfully.
*
* If we attempted to use the circuit to carry a stream but failed
diff --git a/src/or/circpathbias.h b/src/or/circpathbias.h
index c9e572d2a..689b2a620 100644
--- a/src/or/circpathbias.h
+++ b/src/or/circpathbias.h
@@ -20,6 +20,7 @@ void pathbias_count_build_success(origin_circuit_t *circ);
int pathbias_count_build_attempt(origin_circuit_t *circ);
int pathbias_check_close(origin_circuit_t *circ, int reason);
int pathbias_check_probe_response(circuit_t *circ, const cell_t *cell);
+void pathbias_count_valid_cells(circuit_t *circ, const cell_t *cell);
void pathbias_count_use_attempt(origin_circuit_t *circ);
void pathbias_mark_use_success(origin_circuit_t *circ);
void pathbias_mark_use_rollback(origin_circuit_t *circ);
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index 45fff7cc1..a1efe9b74 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -1041,6 +1041,14 @@ circuit_free_(circuit_t *circ)
circuit_remove_from_origin_circuit_list(ocirc);
+ if (ocirc->half_streams) {
+ SMARTLIST_FOREACH_BEGIN(ocirc->half_streams, half_edge_t*,
+ half_conn) {
+ tor_free(half_conn);
+ } SMARTLIST_FOREACH_END(half_conn);
+ smartlist_free(ocirc->half_streams);
+ }
+
if (ocirc->build_state) {
extend_info_free(ocirc->build_state->chosen_exit);
circuit_free_cpath_node(ocirc->build_state->pending_final_cpath);
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 046369af6..91cefe9ff 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -136,6 +136,11 @@ static int connection_ap_process_natd(entry_connection_t *conn);
static int connection_exit_connect_dir(edge_connection_t *exitconn);
static int consider_plaintext_ports(entry_connection_t *conn, uint16_t port);
static int connection_ap_supports_optimistic_data(const entry_connection_t *);
+STATIC void connection_half_edge_add(const edge_connection_t *conn,
+ origin_circuit_t *circ);
+STATIC half_edge_t *connection_half_edge_find_stream_id(
+ const smartlist_t *half_conns,
+ streamid_t stream_id);
/** An AP stream has failed/finished. If it hasn't already sent back
* a socks reply, send one now (based on endreason). Also set
@@ -430,6 +435,12 @@ connection_edge_end(edge_connection_t *conn, uint8_t reason)
if (circ && !circ->marked_for_close) {
log_debug(LD_EDGE,"Sending end on conn (fd "TOR_SOCKET_T_FORMAT").",
conn->base_.s);
+
+ if (CIRCUIT_IS_ORIGIN(circ)) {
+ origin_circuit_t *origin_circ = TO_ORIGIN_CIRCUIT(circ);
+ connection_half_edge_add(conn, origin_circ);
+ }
+
connection_edge_send_command(conn, RELAY_COMMAND_END,
payload, payload_len);
/* We'll log warn if the connection was an hidden service and couldn't be
@@ -446,6 +457,215 @@ connection_edge_end(edge_connection_t *conn, uint8_t reason)
return 0;
}
+/**
+ * Helper function for bsearch.
+ *
+ * As per smartlist_bsearch, return < 0 if key preceeds member,
+ * > 0 if member preceeds key, and 0 if they are equal.
+ *
+ * This is equivalent to subtraction of the values of key - member
+ * (why does no one ever say that explicitly?).
+ */
+static int
+connection_half_edge_compare_bsearch(const void *key, const void **member)
+{
+ const half_edge_t *e2;
+ tor_assert(key);
+ tor_assert(member && *(half_edge_t**)member);
+ e2 = *(const half_edge_t **)member;
+
+ return *(const streamid_t*)key - e2->stream_id;
+}
+
+/**
+ * Add a half-closed connection to the list, to watch for activity.
+ *
+ * These connections are removed from the list upon receiving an end
+ * cell.
+ */
+STATIC void
+connection_half_edge_add(const edge_connection_t *conn,
+ origin_circuit_t *circ)
+{
+ half_edge_t *half_conn = NULL;
+ int insert_at = 0;
+ int ignored;
+
+ /* Double-check for re-insertion. This should not happen,
+ * but this check is cheap compared to the sort anyway */
+ if (connection_half_edge_find_stream_id(circ->half_streams,
+ conn->stream_id)) {
+ log_warn(LD_BUG, "Duplicate stream close for stream %d on circuit %d",
+ conn->stream_id, circ->global_identifier);
+ return;
+ }
+
+ half_conn = tor_malloc_zero(sizeof(half_edge_t));
+
+ if (!circ->half_streams) {
+ circ->half_streams = smartlist_new();
+ }
+
+ half_conn->stream_id = conn->stream_id;
+
+ // How many sendme's should I expect?
+ half_conn->sendmes_pending =
+ (STREAMWINDOW_START-conn->package_window)/STREAMWINDOW_INCREMENT;
+
+ // Is there a connected cell pending?
+ half_conn->connected_pending = conn->base_.state ==
+ AP_CONN_STATE_CONNECT_WAIT;
+
+ /* Data should only arrive if we're not waiting on a resolved cell.
+ * It can arrive after waiting on connected, because of optimistic
+ * data. */
+ if (conn->base_.state != AP_CONN_STATE_RESOLVE_WAIT) {
+ // How many more data cells can arrive on this id?
+ half_conn->data_pending = conn->deliver_window;
+ }
+
+ insert_at = smartlist_bsearch_idx(circ->half_streams, &half_conn->stream_id,
+ connection_half_edge_compare_bsearch,
+ &ignored);
+ smartlist_insert(circ->half_streams, insert_at, half_conn);
+}
+
+/**
+ * Find a stream_id_t in the list in O(lg(n)).
+ *
+ * Returns NULL if the list is empty or element is not found.
+ * Returns a pointer to the element if found.
+ */
+STATIC half_edge_t *
+connection_half_edge_find_stream_id(const smartlist_t *half_conns,
+ streamid_t stream_id)
+{
+ if (!half_conns)
+ return NULL;
+
+ return smartlist_bsearch(half_conns, &stream_id,
+ connection_half_edge_compare_bsearch);
+}
+
+/**
+ * Check if this stream_id is in a half-closed state. If so,
+ * check if it still has data cells pending, and decrement that
+ * window if so.
+ *
+ * Return 1 if the data window was not empty.
+ * Return 0 otherwise.
+ */
+int
+connection_half_edge_is_valid_data(const smartlist_t *half_conns,
+ streamid_t stream_id)
+{
+ half_edge_t *half = connection_half_edge_find_stream_id(half_conns,
+ stream_id);
+
+ if (!half)
+ return 0;
+
+ if (half->data_pending > 0) {
+ half->data_pending--;
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * Check if this stream_id is in a half-closed state. If so,
+ * check if it still has a connected cell pending, and decrement
+ * that window if so.
+ *
+ * Return 1 if the connected window was not empty.
+ * Return 0 otherwise.
+ */
+int
+connection_half_edge_is_valid_connected(const smartlist_t *half_conns,
+ streamid_t stream_id)
+{
+ half_edge_t *half = connection_half_edge_find_stream_id(half_conns,
+ stream_id);
+
+ if (!half)
+ return 0;
+
+ if (half->connected_pending) {
+ half->connected_pending = 0;
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * Check if this stream_id is in a half-closed state. If so,
+ * check if it still has sendme cells pending, and decrement that
+ * window if so.
+ *
+ * Return 1 if the sendme window was not empty.
+ * Return 0 otherwise.
+ */
+int
+connection_half_edge_is_valid_sendme(const smartlist_t *half_conns,
+ streamid_t stream_id)
+{
+ half_edge_t *half = connection_half_edge_find_stream_id(half_conns,
+ stream_id);
+
+ if (!half)
+ return 0;
+
+ if (half->sendmes_pending > 0) {
+ half->sendmes_pending--;
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * Check if this stream_id is in a half-closed state. If so, remove
+ * it from the list. No other data should come after the END cell.
+ *
+ * Return 1 if stream_id was in half-closed state.
+ * Return 0 otherwise.
+ */
+int
+connection_half_edge_is_valid_end(smartlist_t *half_conns,
+ streamid_t stream_id)
+{
+ half_edge_t *half;
+ int found, remove_idx;
+
+ if (!half_conns)
+ return 0;
+
+ remove_idx = smartlist_bsearch_idx(half_conns, &stream_id,
+ connection_half_edge_compare_bsearch,
+ &found);
+ if (!found)
+ return 0;
+
+ half = smartlist_get(half_conns, remove_idx);
+ smartlist_del_keeporder(half_conns, remove_idx);
+ tor_free(half);
+ return 1;
+}
+
+/**
+ * Streams that were used to send a RESOLVE cell are closed
+ * when they get the RESOLVED, without an end. So treat
+ * a RESOLVED just like an end, and remove from the list.
+ */
+int
+connection_half_edge_is_valid_resolved(smartlist_t *half_conns,
+ streamid_t stream_id)
+{
+ return connection_half_edge_is_valid_end(half_conns, stream_id);
+}
+
/** An error has just occurred on an operation on an edge connection
* <b>conn</b>. Extract the errno; convert it to an end reason, and send an
* appropriate relay end cell to the other end of the connection's circuit.
diff --git a/src/or/connection_edge.h b/src/or/connection_edge.h
index c6583d384..6dbba014c 100644
--- a/src/or/connection_edge.h
+++ b/src/or/connection_edge.h
@@ -122,6 +122,17 @@ void connection_ap_warn_and_unmark_if_pending_circ(
entry_connection_t *entry_conn,
const char *where);
+int connection_half_edge_is_valid_data(const smartlist_t *half_conns,
+ streamid_t stream_id);
+int connection_half_edge_is_valid_sendme(const smartlist_t *half_conns,
+ streamid_t stream_id);
+int connection_half_edge_is_valid_connected(const smartlist_t *half_conns,
+ streamid_t stream_id);
+int connection_half_edge_is_valid_end(smartlist_t *half_conns,
+ streamid_t stream_id);
+int connection_half_edge_is_valid_resolved(smartlist_t *half_conns,
+ streamid_t stream_id);
+
/** @name Begin-cell flags
*
* These flags are used in RELAY_BEGIN cells to change the default behavior
diff --git a/src/or/or.h b/src/or/or.h
index db8f9544f..98b7fc977 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -1745,6 +1745,27 @@ typedef struct edge_connection_t {
uint64_t dirreq_id;
} edge_connection_t;
+/**
+ * Struct to track a connection that we closed that the other end
+ * still thinks is open. Exists in origin_circuit_t.half_streams until
+ * we get an end cell or a resolved cell for this stream id.
+ */
+typedef struct half_edge_t {
+ /** stream_id for the half-closed connection */
+ streamid_t stream_id;
+
+ /** How many sendme's can the other end still send, based on how
+ * much data we had sent at the time of close */
+ int sendmes_pending;
+
+ /** How much more data can the other end still send, based on
+ * our deliver window */
+ int data_pending;
+
+ /** Is there a connected cell pending? */
+ int connected_pending : 1;
+} half_edge_t;
+
/** Subtype of edge_connection_t for an "entry connection" -- that is, a SOCKS
* connection, a DNS request, a TransPort connection or a NATD connection */
typedef struct entry_connection_t {
@@ -3261,6 +3282,10 @@ typedef struct origin_circuit_t {
* associated with this circuit. */
edge_connection_t *p_streams;
+ /** Smartlist of half-closed streams (half_edge_t*) that still
+ * have pending activity */
+ smartlist_t *half_streams;
+
/** Bytes read on this circuit since last call to
* control_event_circ_bandwidth_used(). Only used if we're configured
* to emit CIRC_BW events. */
diff --git a/src/or/relay.c b/src/or/relay.c
index 3632678af..13f2b56bc 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -239,7 +239,9 @@ circuit_receive_relay_cell(cell_t *cell, circuit_t *circ,
edge_connection_t *conn = NULL;
if (circ->purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING) {
- pathbias_check_probe_response(circ, cell);
+ if (pathbias_check_probe_response(circ, cell) == -1) {
+ pathbias_count_valid_cells(circ, cell);
+ }
/* We need to drop this cell no matter what to avoid code that expects
* a certain purpose (such as the hidserv code). */
@@ -1545,6 +1547,17 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
"stream_id. Dropping.");
return 0;
} else if (!conn) {
+ if (CIRCUIT_IS_ORIGIN(circ)) {
+ origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
+ if (connection_half_edge_is_valid_data(ocirc->half_streams,
+ rh.stream_id)) {
+ circuit_read_valid_data(ocirc, rh.length);
+ log_info(domain,
+ "data cell on circ %u valid on half-closed "
+ "stream id %d", ocirc->global_identifier, rh.stream_id);
+ }
+ }
+
log_info(domain,"data cell dropped, unknown stream (streamid %d).",
rh.stream_id);
return 0;
@@ -1586,6 +1599,20 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
reason = rh.length > 0 ?
get_uint8(cell->payload+RELAY_HEADER_SIZE) : END_STREAM_REASON_MISC;
if (!conn) {
+ if (CIRCUIT_IS_ORIGIN(circ)) {
+ origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
+ if (connection_half_edge_is_valid_end(ocirc->half_streams,
+ rh.stream_id)) {
+
+ circuit_read_valid_data(ocirc, rh.length);
+ log_info(domain,
+ "end cell (%s) on circ %u valid on half-closed "
+ "stream id %d",
+ stream_end_reason_to_string(reason),
+ ocirc->global_identifier, rh.stream_id);
+ return 0;
+ }
+ }
log_info(domain,"end cell (%s) dropped, unknown stream.",
stream_end_reason_to_string(reason));
return 0;
@@ -1730,6 +1757,19 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
"'connected' unsupported while open. Closing circ.");
return -END_CIRC_REASON_TORPROTOCOL;
}
+
+ if (CIRCUIT_IS_ORIGIN(circ)) {
+ origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
+ if (connection_half_edge_is_valid_connected(ocirc->half_streams,
+ rh.stream_id)) {
+ circuit_read_valid_data(ocirc, rh.length);
+ log_info(domain,
+ "connected cell on circ %u valid on half-closed "
+ "stream id %d", ocirc->global_identifier, rh.stream_id);
+ return 0;
+ }
+ }
+
log_info(domain,
"'connected' received on circid %u for streamid %d, "
"no conn attached anymore. Ignoring.",
@@ -1778,6 +1818,17 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
return 0;
}
if (!conn) {
+ if (CIRCUIT_IS_ORIGIN(circ)) {
+ origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
+ if (connection_half_edge_is_valid_sendme(ocirc->half_streams,
+ rh.stream_id)) {
+ circuit_read_valid_data(ocirc, rh.length);
+ log_info(domain,
+ "sendme cell on circ %u valid on half-closed "
+ "stream id %d", ocirc->global_identifier, rh.stream_id);
+ }
+ }
+
log_info(domain,"sendme cell dropped, unknown stream (streamid %d).",
rh.stream_id);
return 0;
@@ -1841,6 +1892,19 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
"'resolved' unsupported while open. Closing circ.");
return -END_CIRC_REASON_TORPROTOCOL;
}
+
+ if (CIRCUIT_IS_ORIGIN(circ)) {
+ origin_circuit_t *ocirc = TO_ORIGIN_CIRCUIT(circ);
+ if (connection_half_edge_is_valid_resolved(ocirc->half_streams,
+ rh.stream_id)) {
+ circuit_read_valid_data(ocirc, rh.length);
+ log_info(domain,
+ "resolved cell on circ %u valid on half-closed "
+ "stream id %d", ocirc->global_identifier, rh.stream_id);
+ return 0;
+ }
+ }
+
log_info(domain,
"'resolved' received, no conn attached anymore. Ignoring.");
return 0;
diff --git a/src/test/test_relaycell.c b/src/test/test_relaycell.c
index 1bd17b73b..1570e1516 100644
--- a/src/test/test_relaycell.c
+++ b/src/test/test_relaycell.c
@@ -10,9 +10,11 @@
#include "config.h"
#include "connection.h"
#include "crypto.h"
+#include "crypto_rand.h"
#include "circuitbuild.h"
#include "circuitlist.h"
#include "connection_edge.h"
+#include "log_test_helpers.h"
#include "relay.h"
#include "test.h"
@@ -29,6 +31,18 @@ void connection_free_minimal(connection_t*);
int connected_cell_format_payload(uint8_t *payload_out,
const tor_addr_t *addr,
uint32_t ttl);
+int pathbias_count_valid_cells(origin_circuit_t *circ,
+ cell_t *cell);
+half_edge_t *connection_half_edge_find_stream_id(
+ const smartlist_t *half_conns,
+ streamid_t stream_id);
+void connection_half_edge_add(const edge_connection_t *conn,
+ origin_circuit_t *circ);
+
+int mock_send_command(streamid_t stream_id, circuit_t *circ,
+ uint8_t relay_command, const char *payload,
+ size_t payload_len, crypt_path_t *cpath_layer,
+ const char *filename, int lineno);
/* Mock replacement for connection_ap_hannshake_socks_resolved() */
static void
@@ -119,19 +133,38 @@ mock_start_reading(connection_t *conn)
return;
}
-static void
-test_circbw_relay(void *arg)
+int
+mock_send_command(streamid_t stream_id, circuit_t *circ,
+ uint8_t relay_command, const char *payload,
+ size_t payload_len, crypt_path_t *cpath_layer,
+ const char *filename, int lineno)
+{
+ (void)stream_id; (void)circ;
+ (void)relay_command; (void)payload;
+ (void)payload_len; (void)cpath_layer;
+ (void)filename; (void)lineno;
+
+ return 0;
+}
+
+static entry_connection_t *
+fake_entry_conn(origin_circuit_t *oncirc, streamid_t id)
{
- cell_t cell;
- relay_header_t rh;
- tor_addr_t addr;
edge_connection_t *edgeconn;
entry_connection_t *entryconn;
- origin_circuit_t *circ;
- int delivered = 0;
- int overhead = 0;
- (void)arg;
+ entryconn = entry_connection_new(CONN_TYPE_AP, AF_INET);
+ edgeconn = ENTRY_TO_EDGE_CONN(entryconn);
+ edgeconn->base_.state = AP_CONN_STATE_CONNECT_WAIT;
+ edgeconn->deliver_window = STREAMWINDOW_START;
+ edgeconn->package_window = STREAMWINDOW_START;
+
+ edgeconn->stream_id = id;
+ edgeconn->on_circuit = TO_CIRCUIT(oncirc);
+ edgeconn->cpath_layer = oncirc->cpath;
+
+ return entryconn;
+}
#define PACK_CELL(id, cmd, body_s) do { \
memset(&cell, 0, sizeof(cell)); \
@@ -154,18 +187,461 @@ test_circbw_relay(void *arg)
tt_int_op(circ->n_overhead_read_circ_bw, OP_EQ, overhead); \
} while (0)
+static int
+subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
+{
+ cell_t cell;
+ relay_header_t rh;
+ edge_connection_t *edgeconn;
+ entry_connection_t *entryconn2=NULL;
+ entry_connection_t *entryconn3=NULL;
+ entry_connection_t *entryconn4=NULL;
+ int delivered = circ->n_delivered_read_circ_bw;
+ int overhead = circ->n_overhead_read_circ_bw;
+
+ /* Make new entryconns */
+ entryconn2 = fake_entry_conn(circ, init_id);
+ entryconn2->socks_request->has_finished = 1;
+ entryconn3 = fake_entry_conn(circ, init_id+1);
+ entryconn3->socks_request->has_finished = 1;
+ entryconn4 = fake_entry_conn(circ, init_id+2);
+ entryconn4->socks_request->has_finished = 1;
+ edgeconn = ENTRY_TO_EDGE_CONN(entryconn2);
+ edgeconn->package_window = 23;
+ edgeconn->base_.state = AP_CONN_STATE_OPEN;
+
+ int data_cells = edgeconn->deliver_window;
+ int sendme_cells = (STREAMWINDOW_START-edgeconn->package_window)
+ /STREAMWINDOW_INCREMENT;
+ ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
+ connection_edge_reached_eof(edgeconn);
+
+ /* Data cell not in the half-opened list */
+ PACK_CELL(4000, RELAY_COMMAND_DATA, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(circ, &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Sendme cell not in the half-opened list */
+ PACK_CELL(4000, RELAY_COMMAND_SENDME, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(circ, &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Connected cell not in the half-opened list */
+ PACK_CELL(4000, RELAY_COMMAND_CONNECTED, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(circ, &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Resolved cell not in the half-opened list */
+ PACK_CELL(4000, RELAY_COMMAND_RESOLVED, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(circ, &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Connected cell: not counted -- we were open */
+ edgeconn = ENTRY_TO_EDGE_CONN(entryconn2);
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_CONNECTED, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(circ, &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* DATA cells up to limit */
+ while (data_cells > 0) {
+ ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(circ, &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_COUNTED_BW();
+ data_cells--;
+ }
+ ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(circ, &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* SENDME cells up to limit */
+ while (sendme_cells > 0) {
+ ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_SENDME, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(circ, &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_COUNTED_BW();
+ sendme_cells--;
+ }
+ ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_SENDME, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(circ, &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Only one END cell */
+ ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(circ, &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_COUNTED_BW();
+
+ ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(circ, &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ edgeconn = ENTRY_TO_EDGE_CONN(entryconn3);
+ edgeconn->base_.state = AP_CONN_STATE_OPEN;
+ ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
+ /* sendme cell on open entryconn with full window */
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_SENDME, "Data1234");
+ int ret =
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ circ->cpath);
+ tt_int_op(ret, OP_EQ, -END_CIRC_REASON_TORPROTOCOL);
+ ASSERT_UNCOUNTED_BW();
+
+ /* connected cell on a after EOF */
+ ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
+ edgeconn->base_.state = AP_CONN_STATE_CONNECT_WAIT;
+ connection_edge_reached_eof(edgeconn);
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_CONNECTED, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(circ, &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_COUNTED_BW();
+
+ ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_CONNECTED, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(circ, &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* DATA and SENDME after END cell */
+ ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(circ, &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_COUNTED_BW();
+
+ ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_SENDME, "Data1234");
+ ret =
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ tt_int_op(ret, OP_NE, -END_CIRC_REASON_TORPROTOCOL);
+ ASSERT_UNCOUNTED_BW();
+
+ ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(circ, &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Resolved: 1 counted, more not */
+ edgeconn = ENTRY_TO_EDGE_CONN(entryconn4);
+ entryconn4->socks_request->command = SOCKS_COMMAND_RESOLVE;
+ edgeconn->base_.state = AP_CONN_STATE_RESOLVE_WAIT;
+ edgeconn->on_circuit = TO_CIRCUIT(circ);
+ ENTRY_TO_CONN(entryconn4)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn4)->outbuf_flushlen = 0;
+ connection_edge_reached_eof(edgeconn);
+
+ ENTRY_TO_CONN(entryconn4)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn4)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_RESOLVED,
+ "\x04\x04\x12\x00\x00\x01\x00\x00\x02\x00");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(circ, &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_COUNTED_BW();
+
+ ENTRY_TO_CONN(entryconn4)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn4)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_RESOLVED,
+ "\x04\x04\x12\x00\x00\x01\x00\x00\x02\x00");
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Data not counted after resolved */
+ ENTRY_TO_CONN(entryconn4)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn4)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(circ, &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* End not counted after resolved */
+ ENTRY_TO_CONN(entryconn4)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn4)->outbuf_flushlen = 0;
+ PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
+ if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ pathbias_count_valid_cells(circ, &cell);
+ else
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ connection_free_minimal(ENTRY_TO_CONN(entryconn2));
+ connection_free_minimal(ENTRY_TO_CONN(entryconn3));
+ connection_free_minimal(ENTRY_TO_CONN(entryconn4));
+ return 1;
+ done:
+ connection_free_minimal(ENTRY_TO_CONN(entryconn2));
+ connection_free_minimal(ENTRY_TO_CONN(entryconn3));
+ connection_free_minimal(ENTRY_TO_CONN(entryconn4));
+ return 0;
+}
+
+static int
+halfstream_insert(origin_circuit_t *circ, edge_connection_t *edgeconn,
+ streamid_t *streams, int num, int random)
+{
+ int inserted = 0;
+
+ /* Insert num random elements */
+ while (inserted < num) {
+ streamid_t id;
+
+ if (random)
+ id = (streamid_t)crypto_rand_int(65535)+1;
+ else
+ id = get_unique_stream_id_by_circ(circ);
+
+ edgeconn->stream_id = id;
+
+ /* Ensure it isn't there */
+ if (connection_half_edge_find_stream_id(circ->half_streams, id)) {
+ continue;
+ }
+
+ connection_half_edge_add(edgeconn, circ);
+ if (streams)
+ streams[inserted] = id;
+ inserted++;
+ }
+
+ return inserted;
+}
+
+static void
+subtest_halfstream_insertremove(int num)
+{
+ origin_circuit_t *circ =
+ helper_create_origin_circuit(CIRCUIT_PURPOSE_C_GENERAL, 0);
+ edge_connection_t *edgeconn;
+ entry_connection_t *entryconn;
+ streamid_t *streams = tor_malloc_zero(num*sizeof(streamid_t));
+ int i = 0;
+
+ circ->cpath->state = CPATH_STATE_AWAITING_KEYS;
+ circ->cpath->deliver_window = CIRCWINDOW_START;
+
+ entryconn = fake_entry_conn(circ, 23);
+ edgeconn = ENTRY_TO_EDGE_CONN(entryconn);
+
+ /* Explicity test all operations on an absent stream list */
+ tt_int_op(connection_half_edge_is_valid_data(circ->half_streams,
+ 23), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_connected(circ->half_streams,
+ 23), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_sendme(circ->half_streams,
+ 23), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_resolved(circ->half_streams,
+ 23), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
+ 23), OP_EQ, 0);
+
+ /* Insert a duplicate element; verify that other elements absent;
+ * ensure removing it once works */
+ edgeconn->stream_id = 23;
+ connection_half_edge_add(edgeconn, circ);
+ connection_half_edge_add(edgeconn, circ);
+ connection_half_edge_add(edgeconn, circ);
+
+ /* Verify that other elements absent */
+ tt_int_op(connection_half_edge_is_valid_data(circ->half_streams,
+ 22), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_connected(circ->half_streams,
+ 22), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_sendme(circ->half_streams,
+ 22), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_resolved(circ->half_streams,
+ 22), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
+ 22), OP_EQ, 0);
+
+ tt_int_op(connection_half_edge_is_valid_data(circ->half_streams,
+ 24), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_connected(circ->half_streams,
+ 24), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_sendme(circ->half_streams,
+ 24), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_resolved(circ->half_streams,
+ 24), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
+ 24), OP_EQ, 0);
+
+ /* Verify we only remove it once */
+ tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
+ 23), OP_EQ, 1);
+ tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
+ 23), OP_EQ, 0);
+
+ halfstream_insert(circ, edgeconn, streams, num, 1);
+
+ /* Remove half of them */
+ for (i = 0; i < num/2; i++) {
+ tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
+ streams[i]),
+ OP_EQ, 1);
+ }
+
+ /* Verify first half of list is gone */
+ for (i = 0; i < num/2; i++) {
+ tt_ptr_op(connection_half_edge_find_stream_id(circ->half_streams,
+ streams[i]),
+ OP_EQ, NULL);
+ }
+
+ /* Verify second half of list is present */
+ for (; i < num; i++) {
+ tt_ptr_op(connection_half_edge_find_stream_id(circ->half_streams,
+ streams[i]),
+ OP_NE, NULL);
+ }
+
+ /* Remove other half. Verify list is empty. */
+ for (i = num/2; i < num; i++) {
+ tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
+ streams[i]),
+ OP_EQ, 1);
+ }
+ tt_int_op(smartlist_len(circ->half_streams), OP_EQ, 0);
+
+ /* Explicity test all operations on an empty stream list */
+ tt_int_op(connection_half_edge_is_valid_data(circ->half_streams,
+ 23), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_connected(circ->half_streams,
+ 23), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_sendme(circ->half_streams,
+ 23), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_resolved(circ->half_streams,
+ 23), OP_EQ, 0);
+ tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
+ 23), OP_EQ, 0);
+
+ /* For valgrind, leave some around then free the circ */
+ halfstream_insert(circ, edgeconn, NULL, 10, 0);
+
+ done:
+ tor_free(streams);
+ circuit_free_(TO_CIRCUIT(circ));
+ connection_free_minimal(ENTRY_TO_CONN(entryconn));
+}
+
+static void
+test_halfstream_insertremove(void *arg)
+{
+ (void)arg;
+
+ /* Suppress the WARN message we generate in this test */
+ setup_full_capture_of_logs(LOG_WARN);
+
+ /* Test insertion and removal with a few different sizes */
+ subtest_halfstream_insertremove(10);
+ subtest_halfstream_insertremove(100);
+ subtest_halfstream_insertremove(1000);
+}
+
+static void
+test_circbw_relay(void *arg)
+{
+ cell_t cell;
+ relay_header_t rh;
+ tor_addr_t addr;
+ edge_connection_t *edgeconn;
+ entry_connection_t *entryconn1=NULL;
+ origin_circuit_t *circ;
+ int delivered = 0;
+ int overhead = 0;
+
+ (void)arg;
+
MOCK(connection_mark_unattached_ap_, mock_connection_mark_unattached_ap_);
MOCK(connection_start_reading, mock_start_reading);
MOCK(connection_mark_for_close_internal_, mock_mark_for_close);
+ MOCK(relay_send_command_from_edge_, mock_send_command);
- entryconn = entry_connection_new(CONN_TYPE_AP, AF_INET);
- edgeconn = ENTRY_TO_EDGE_CONN(entryconn);
- edgeconn->base_.state = AP_CONN_STATE_CONNECT_WAIT;
- edgeconn->deliver_window = 1000;
circ = helper_create_origin_circuit(CIRCUIT_PURPOSE_C_GENERAL, 0);
- edgeconn->cpath_layer = circ->cpath;
circ->cpath->state = CPATH_STATE_AWAITING_KEYS;
- circ->cpath->deliver_window = 1000;
+ circ->cpath->deliver_window = CIRCWINDOW_START;
+
+ entryconn1 = fake_entry_conn(circ, 1);
+ edgeconn = ENTRY_TO_EDGE_CONN(entryconn1);
/* Stream id 0: Not counted */
PACK_CELL(0, RELAY_COMMAND_END, "Data1234");
@@ -191,7 +667,7 @@ test_circbw_relay(void *arg)
/* Properly formatted resolved cell in correct state: counted */
edgeconn->base_.state = AP_CONN_STATE_RESOLVE_WAIT;
- entryconn->socks_request->command = SOCKS_COMMAND_RESOLVE;
+ entryconn1->socks_request->command = SOCKS_COMMAND_RESOLVE;
edgeconn->on_circuit = TO_CIRCUIT(circ);
PACK_CELL(1, RELAY_COMMAND_RESOLVED,
"\x04\x04\x12\x00\x00\x01\x00\x00\x02\x00");
@@ -200,7 +676,7 @@ test_circbw_relay(void *arg)
ASSERT_COUNTED_BW();
edgeconn->base_.state = AP_CONN_STATE_OPEN;
- entryconn->socks_request->has_finished = 1;
+ entryconn1->socks_request->has_finished = 1;
/* Connected cell after open: not counted */
PACK_CELL(1, RELAY_COMMAND_CONNECTED, "Data1234");
@@ -221,42 +697,43 @@ test_circbw_relay(void *arg)
ASSERT_UNCOUNTED_BW();
/* Data cell on stream 0: not counted */
- PACK_CELL(1, RELAY_COMMAND_DATA, "Data1234");
+ PACK_CELL(0, RELAY_COMMAND_DATA, "Data1234");
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
circ->cpath);
ASSERT_UNCOUNTED_BW();
/* Data cell on open connection: counted */
- ENTRY_TO_CONN(entryconn)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn1)->marked_for_close = 0;
PACK_CELL(1, RELAY_COMMAND_DATA, "Data1234");
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
circ->cpath);
ASSERT_COUNTED_BW();
/* Empty Data cell on open connection: not counted */
- ENTRY_TO_CONN(entryconn)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn1)->marked_for_close = 0;
PACK_CELL(1, RELAY_COMMAND_DATA, "");
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
circ->cpath);
ASSERT_UNCOUNTED_BW();
/* Sendme on valid stream: counted */
- ENTRY_TO_CONN(entryconn)->outbuf_flushlen = 0;
+ edgeconn->package_window -= STREAMWINDOW_INCREMENT;
+ ENTRY_TO_CONN(entryconn1)->outbuf_flushlen = 0;
PACK_CELL(1, RELAY_COMMAND_SENDME, "Data1234");
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
circ->cpath);
ASSERT_COUNTED_BW();
/* Sendme on valid stream with full window: not counted */
- ENTRY_TO_CONN(entryconn)->outbuf_flushlen = 0;
+ ENTRY_TO_CONN(entryconn1)->outbuf_flushlen = 0;
PACK_CELL(1, RELAY_COMMAND_SENDME, "Data1234");
- edgeconn->package_window = 500;
+ edgeconn->package_window = STREAMWINDOW_START;
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
circ->cpath);
ASSERT_UNCOUNTED_BW();
/* Sendme on unknown stream: not counted */
- ENTRY_TO_CONN(entryconn)->outbuf_flushlen = 0;
+ ENTRY_TO_CONN(entryconn1)->outbuf_flushlen = 0;
PACK_CELL(1, RELAY_COMMAND_SENDME, "Data1234");
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -275,18 +752,6 @@ test_circbw_relay(void *arg)
circ->cpath);
ASSERT_COUNTED_BW();
- /* End cell on non-closed connection: counted */
- PACK_CELL(1, RELAY_COMMAND_END, "Data1234");
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
- circ->cpath);
- ASSERT_COUNTED_BW();
-
- /* End cell on connection that already got one: not counted */
- PACK_CELL(1, RELAY_COMMAND_END, "Data1234");
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
- circ->cpath);
- ASSERT_UNCOUNTED_BW();
-
/* Invalid extended cell: not counted */
PACK_CELL(1, RELAY_COMMAND_EXTENDED2, "Data1234");
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
@@ -312,12 +777,33 @@ test_circbw_relay(void *arg)
circ->cpath);
ASSERT_COUNTED_BW();
+ /* End cell on non-closed connection: counted */
+ PACK_CELL(1, RELAY_COMMAND_END, "Data1234");
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
+ circ->cpath);
+ ASSERT_COUNTED_BW();
+
+ /* End cell on connection that already got one: not counted */
+ PACK_CELL(1, RELAY_COMMAND_END, "Data1234");
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
+ circ->cpath);
+ ASSERT_UNCOUNTED_BW();
+
+ /* Simulate closed stream on entryconn, then test: */
+ if (!subtest_circbw_halfclosed(circ, 2))
+ goto done;
+
+ circ->base_.purpose = CIRCUIT_PURPOSE_PATH_BIAS_TESTING;
+ if (!subtest_circbw_halfclosed(circ, 6))
+ goto done;
+
done:
UNMOCK(connection_start_reading);
UNMOCK(connection_mark_unattached_ap_);
UNMOCK(connection_mark_for_close_internal_);
+ UNMOCK(relay_send_command_from_edge_);
circuit_free_(TO_CIRCUIT(circ));
- connection_free_minimal(ENTRY_TO_CONN(entryconn));
+ connection_free_minimal(ENTRY_TO_CONN(entryconn1));
}
/* Tests for connection_edge_process_resolved_cell().
@@ -505,6 +991,7 @@ test_relaycell_resolved(void *arg)
struct testcase_t relaycell_tests[] = {
{ "resolved", test_relaycell_resolved, TT_FORK, NULL, NULL },
{ "circbw", test_circbw_relay, TT_FORK, NULL, NULL },
+ { "halfstream", test_halfstream_insertremove, TT_FORK, NULL, NULL },
END_OF_TESTCASES
};
1
0

[tor/maint-0.3.4] Ticket #25573: Check half-opened stream ids when choosing a new one
by nickm@torproject.org 15 Nov '18
by nickm@torproject.org 15 Nov '18
15 Nov '18
commit 144647031aa9e7eacc6f7cdd8fed663c7229b2aa
Author: Mike Perry <mikeperry-git(a)torproject.org>
Date: Wed Aug 29 00:06:38 2018 +0000
Ticket #25573: Check half-opened stream ids when choosing a new one
Avoid data corrupton by avoiding mixing up old stream ids with new ones.
This commit changes client behavior.
---
src/or/connection_edge.c | 5 ++++
src/test/test_relaycell.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 65 insertions(+)
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 91cefe9ff..1060e7461 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -2813,6 +2813,11 @@ get_unique_stream_id_by_circ(origin_circuit_t *circ)
for (tmpconn = circ->p_streams; tmpconn; tmpconn=tmpconn->next_stream)
if (tmpconn->stream_id == test_stream_id)
goto again;
+
+ if (connection_half_edge_find_stream_id(circ->half_streams,
+ test_stream_id))
+ goto again;
+
return test_stream_id;
}
diff --git a/src/test/test_relaycell.c b/src/test/test_relaycell.c
index 1570e1516..4c406a9b7 100644
--- a/src/test/test_relaycell.c
+++ b/src/test/test_relaycell.c
@@ -618,6 +618,65 @@ test_halfstream_insertremove(void *arg)
}
static void
+test_halfstream_wrap(void *arg)
+{
+ origin_circuit_t *circ =
+ helper_create_origin_circuit(CIRCUIT_PURPOSE_C_GENERAL, 0);
+ edge_connection_t *edgeconn;
+ entry_connection_t *entryconn;
+
+ circ->cpath->state = CPATH_STATE_AWAITING_KEYS;
+ circ->cpath->deliver_window = CIRCWINDOW_START;
+
+ entryconn = fake_entry_conn(circ, 23);
+ edgeconn = ENTRY_TO_EDGE_CONN(entryconn);
+
+ (void)arg;
+
+ /* Suppress the WARN message we generate in this test */
+ setup_full_capture_of_logs(LOG_WARN);
+ MOCK(connection_mark_for_close_internal_, mock_mark_for_close);
+
+ /* Verify that get_unique_stream_id_by_circ() can wrap uint16_t */
+ circ->next_stream_id = 65530;
+ halfstream_insert(circ, edgeconn, NULL, 7, 0);
+ tt_int_op(circ->next_stream_id, OP_EQ, 2);
+ tt_int_op(smartlist_len(circ->half_streams), OP_EQ, 7);
+
+ /* Insert full-1 */
+ halfstream_insert(circ, edgeconn, NULL,
+ 65534-smartlist_len(circ->half_streams), 0);
+ tt_int_op(smartlist_len(circ->half_streams), OP_EQ, 65534);
+
+ /* Verify that we can get_unique_stream_id_by_circ() successfully */
+ edgeconn->stream_id = get_unique_stream_id_by_circ(circ);
+ tt_int_op(edgeconn->stream_id, OP_NE, 0); /* 0 is failure */
+
+ /* Insert an opened stream on the circ with that id */
+ ENTRY_TO_CONN(entryconn)->marked_for_close = 0;
+ ENTRY_TO_CONN(entryconn)->outbuf_flushlen = 0;
+ edgeconn->base_.state = AP_CONN_STATE_CONNECT_WAIT;
+ circ->p_streams = edgeconn;
+
+ /* Verify that get_unique_stream_id_by_circ() fails */
+ tt_int_op(get_unique_stream_id_by_circ(circ), OP_EQ, 0); /* 0 is failure */
+
+ /* eof the one opened stream. Verify it is now in half-closed */
+ tt_int_op(smartlist_len(circ->half_streams), OP_EQ, 65534);
+ connection_edge_reached_eof(edgeconn);
+ tt_int_op(smartlist_len(circ->half_streams), OP_EQ, 65535);
+
+ /* Verify get_unique_stream_id_by_circ() fails due to full half-closed */
+ circ->p_streams = NULL;
+ tt_int_op(get_unique_stream_id_by_circ(circ), OP_EQ, 0); /* 0 is failure */
+
+ done:
+ circuit_free_(TO_CIRCUIT(circ));
+ connection_free_minimal(ENTRY_TO_CONN(entryconn));
+ UNMOCK(connection_mark_for_close_internal_);
+}
+
+static void
test_circbw_relay(void *arg)
{
cell_t cell;
@@ -992,6 +1051,7 @@ struct testcase_t relaycell_tests[] = {
{ "resolved", test_relaycell_resolved, TT_FORK, NULL, NULL },
{ "circbw", test_circbw_relay, TT_FORK, NULL, NULL },
{ "halfstream", test_halfstream_insertremove, TT_FORK, NULL, NULL },
+ { "streamwrap", test_halfstream_wrap, TT_FORK, NULL, NULL },
END_OF_TESTCASES
};
1
0

15 Nov '18
commit ce894e20b597d2d21b56ac8a8f13d1ea4063731d
Author: Mike Perry <mikeperry-git(a)torproject.org>
Date: Tue Aug 7 04:23:33 2018 +0000
Ticket #25573: Count TRUNCATED cells.
TRUNCATED cells were ignored while in path bias. Now they are obeyed, and
cause us to tear down the circuit. The actual impact is minimal, since we
would just wait around for a probe that would never arrive before.
This commit changes client behavior.
---
src/or/circpathbias.c | 10 ++++++++++
src/or/circuitbuild.c | 3 +--
src/or/circuitbuild.h | 3 +--
src/or/relay.c | 9 ++++++++-
src/test/test_relaycell.c | 18 ++++++++++++++++++
5 files changed, 38 insertions(+), 5 deletions(-)
diff --git a/src/or/circpathbias.c b/src/or/circpathbias.c
index 923941e5b..3cdd16261 100644
--- a/src/or/circpathbias.c
+++ b/src/or/circpathbias.c
@@ -929,6 +929,16 @@ pathbias_count_valid_cells(circuit_t *circ, const cell_t *cell)
/* Check to see if this is a cell from a previous connection,
* or is a request to close the circuit. */
switch (rh.command) {
+ case RELAY_COMMAND_TRUNCATED:
+ /* Truncated cells can arrive on path bias circs. When they do,
+ * just process them. This closes the circ, but it was junk anyway.
+ * No reason to wait for the probe. */
+ circuit_read_valid_data(ocirc, rh.length);
+ circuit_truncated(TO_ORIGIN_CIRCUIT(circ),
+ get_uint8(cell->payload + RELAY_HEADER_SIZE));
+
+ break;
+
case RELAY_COMMAND_END:
if (connection_half_edge_is_valid_end(ocirc->half_streams,
rh.stream_id)) {
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index 3d1c9c1ab..8f17f2786 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -1419,13 +1419,12 @@ circuit_finish_handshake(origin_circuit_t *circ,
* just give up: force circ to close, and return 0.
*/
int
-circuit_truncated(origin_circuit_t *circ, crypt_path_t *layer, int reason)
+circuit_truncated(origin_circuit_t *circ, int reason)
{
// crypt_path_t *victim;
// connection_t *stream;
tor_assert(circ);
- tor_assert(layer);
/* XXX Since we don't send truncates currently, getting a truncated
* means that a connection broke or an extend failed. For now,
diff --git a/src/or/circuitbuild.h b/src/or/circuitbuild.h
index 0184898e2..e3d30c110 100644
--- a/src/or/circuitbuild.h
+++ b/src/or/circuitbuild.h
@@ -37,8 +37,7 @@ int circuit_init_cpath_crypto(crypt_path_t *cpath,
struct created_cell_t;
int circuit_finish_handshake(origin_circuit_t *circ,
const struct created_cell_t *created_cell);
-int circuit_truncated(origin_circuit_t *circ, crypt_path_t *layer,
- int reason);
+int circuit_truncated(origin_circuit_t *circ, int reason);
int onionskin_answer(or_circuit_t *circ,
const struct created_cell_t *created_cell,
const char *keys, size_t keys_len,
diff --git a/src/or/relay.c b/src/or/relay.c
index 13f2b56bc..81bb94d5a 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -1748,7 +1748,14 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
"'truncated' unsupported at non-origin. Dropping.");
return 0;
}
- circuit_truncated(TO_ORIGIN_CIRCUIT(circ), layer_hint,
+
+ /* Count the truncated as valid, for completeness. The
+ * circuit is being torn down anyway, though. */
+ if (CIRCUIT_IS_ORIGIN(circ)) {
+ circuit_read_valid_data(TO_ORIGIN_CIRCUIT(circ),
+ rh.length);
+ }
+ circuit_truncated(TO_ORIGIN_CIRCUIT(circ),
get_uint8(cell->payload + RELAY_HEADER_SIZE));
return 0;
case RELAY_COMMAND_CONNECTED:
diff --git a/src/test/test_relaycell.c b/src/test/test_relaycell.c
index 4c406a9b7..3f84ee830 100644
--- a/src/test/test_relaycell.c
+++ b/src/test/test_relaycell.c
@@ -116,6 +116,16 @@ mock_connection_mark_unattached_ap_(entry_connection_t *conn, int endreason,
}
static void
+mock_mark_circ_for_close(circuit_t *circ, int reason, int line,
+ const char *file)
+{
+ (void)reason; (void)line; (void)file;
+
+ circ->marked_for_close = 1;
+ return;
+}
+
+static void
mock_mark_for_close(connection_t *conn,
int line, const char *file)
{
@@ -694,6 +704,7 @@ test_circbw_relay(void *arg)
MOCK(connection_start_reading, mock_start_reading);
MOCK(connection_mark_for_close_internal_, mock_mark_for_close);
MOCK(relay_send_command_from_edge_, mock_send_command);
+ MOCK(circuit_mark_for_close_, mock_mark_circ_for_close);
circ = helper_create_origin_circuit(CIRCUIT_PURPOSE_C_GENERAL, 0);
circ->cpath->state = CPATH_STATE_AWAITING_KEYS;
@@ -856,11 +867,18 @@ test_circbw_relay(void *arg)
if (!subtest_circbw_halfclosed(circ, 6))
goto done;
+ /* Path bias: truncated */
+ tt_int_op(circ->base_.marked_for_close, OP_EQ, 0);
+ PACK_CELL(0, RELAY_COMMAND_TRUNCATED, "Data1234");
+ pathbias_count_valid_cells(circ, &cell);
+ tt_int_op(circ->base_.marked_for_close, OP_EQ, 1);
+
done:
UNMOCK(connection_start_reading);
UNMOCK(connection_mark_unattached_ap_);
UNMOCK(connection_mark_for_close_internal_);
UNMOCK(relay_send_command_from_edge_);
+ UNMOCK(circuit_mark_for_close_);
circuit_free_(TO_CIRCUIT(circ));
connection_free_minimal(ENTRY_TO_CONN(entryconn1));
}
1
0

[tor/maint-0.3.4] Teach the OOM module to handle half-open stream info. #27686
by nickm@torproject.org 15 Nov '18
by nickm@torproject.org 15 Nov '18
15 Nov '18
commit ab92f934212f0f91f74cd171211117d20a28cc1e
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Fri Sep 14 10:16:27 2018 -0400
Teach the OOM module to handle half-open stream info. #27686
---
src/or/circuitlist.c | 21 ++++++++++++++++++---
src/or/connection_edge.c | 24 ++++++++++++++++++++++--
src/or/connection_edge.h | 6 +++++-
src/or/relay.c | 2 +-
4 files changed, 46 insertions(+), 7 deletions(-)
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index a1efe9b74..ad9b902ac 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -1042,9 +1042,9 @@ circuit_free_(circuit_t *circ)
circuit_remove_from_origin_circuit_list(ocirc);
if (ocirc->half_streams) {
- SMARTLIST_FOREACH_BEGIN(ocirc->half_streams, half_edge_t*,
+ SMARTLIST_FOREACH_BEGIN(ocirc->half_streams, half_edge_t *,
half_conn) {
- tor_free(half_conn);
+ half_edge_free(half_conn);
} SMARTLIST_FOREACH_END(half_conn);
smartlist_free(ocirc->half_streams);
}
@@ -2324,6 +2324,20 @@ n_cells_in_circ_queues(const circuit_t *c)
return n;
}
+/** Return the number of bytes allocated for <b>c</c>'s half-open streams. */
+static size_t
+circuit_alloc_in_half_streams(const circuit_t *c)
+{
+ if (! CIRCUIT_IS_ORIGIN(c)) {
+ return 0;
+ }
+ const origin_circuit_t *ocirc = CONST_TO_ORIGIN_CIRCUIT(c);
+ if (ocirc->half_streams)
+ return smartlist_len(ocirc->half_streams) * sizeof(half_edge_t);
+ else
+ return 0;
+}
+
/**
* Return the age of the oldest cell queued on <b>c</b>, in timestamp units.
* Return 0 if there are no cells queued on c. Requires that <b>now</b> be
@@ -2558,6 +2572,7 @@ circuits_handle_oom(size_t current_allocation)
/* Now, kill the circuit. */
n = n_cells_in_circ_queues(circ);
+ const size_t half_stream_alloc = circuit_alloc_in_half_streams(circ);
if (! circ->marked_for_close) {
circuit_mark_for_close(circ, END_CIRC_REASON_RESOURCELIMIT);
}
@@ -2567,6 +2582,7 @@ circuits_handle_oom(size_t current_allocation)
++n_circuits_killed;
mem_recovered += n * packed_cell_mem_cost();
+ mem_recovered += half_stream_alloc;
mem_recovered += freed;
if (mem_recovered >= mem_to_recover)
@@ -2711,4 +2727,3 @@ assert_circuit_ok,(const circuit_t *c))
tor_assert(!or_circ || !or_circ->rend_splice);
}
}
-
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 1060e7461..eea364ffd 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -477,6 +477,9 @@ connection_half_edge_compare_bsearch(const void *key, const void **member)
return *(const streamid_t*)key - e2->stream_id;
}
+/** Total number of half_edge_t objects allocated */
+static size_t n_half_conns_allocated = 0;
+
/**
* Add a half-closed connection to the list, to watch for activity.
*
@@ -501,6 +504,7 @@ connection_half_edge_add(const edge_connection_t *conn,
}
half_conn = tor_malloc_zero(sizeof(half_edge_t));
+ ++n_half_conns_allocated;
if (!circ->half_streams) {
circ->half_streams = smartlist_new();
@@ -530,6 +534,23 @@ connection_half_edge_add(const edge_connection_t *conn,
smartlist_insert(circ->half_streams, insert_at, half_conn);
}
+/** Release space held by <b>he</b> */
+void
+half_edge_free_(half_edge_t *he)
+{
+ if (!he)
+ return;
+ --n_half_conns_allocated;
+ tor_free(he);
+}
+
+/** Return the number of bytes devoted to storing info on half-open streams. */
+size_t
+half_streams_get_total_allocation(void)
+{
+ return n_half_conns_allocated * sizeof(half_edge_t);
+}
+
/**
* Find a stream_id_t in the list in O(lg(n)).
*
@@ -650,7 +671,7 @@ connection_half_edge_is_valid_end(smartlist_t *half_conns,
half = smartlist_get(half_conns, remove_idx);
smartlist_del_keeporder(half_conns, remove_idx);
- tor_free(half);
+ half_edge_free(half);
return 1;
}
@@ -4412,4 +4433,3 @@ connection_edge_free_all(void)
pending_entry_connections = NULL;
mainloop_event_free(attach_pending_entry_connections_ev);
}
-
diff --git a/src/or/connection_edge.h b/src/or/connection_edge.h
index 6dbba014c..7bef01e40 100644
--- a/src/or/connection_edge.h
+++ b/src/or/connection_edge.h
@@ -133,6 +133,11 @@ int connection_half_edge_is_valid_end(smartlist_t *half_conns,
int connection_half_edge_is_valid_resolved(smartlist_t *half_conns,
streamid_t stream_id);
+size_t half_streams_get_total_allocation(void);
+void half_edge_free_(half_edge_t *he);
+#define half_edge_free(he) \
+ FREE_AND_NULL(half_edge_t, half_edge_free_, (he))
+
/** @name Begin-cell flags
*
* These flags are used in RELAY_BEGIN cells to change the default behavior
@@ -205,4 +210,3 @@ STATIC int connection_ap_process_http_connect(entry_connection_t *conn);
#endif /* defined(CONNECTION_EDGE_PRIVATE) */
#endif /* !defined(TOR_CONNECTION_EDGE_H) */
-
diff --git a/src/or/relay.c b/src/or/relay.c
index 81bb94d5a..497afe756 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -2586,6 +2586,7 @@ cell_queues_check_size(void)
{
time_t now = time(NULL);
size_t alloc = cell_queues_get_total_allocation();
+ alloc += half_streams_get_total_allocation();
alloc += buf_get_total_allocation();
alloc += tor_compress_get_total_allocation();
const size_t rend_cache_total = rend_cache_get_total_allocation();
@@ -3142,4 +3143,3 @@ circuit_queue_streams_are_blocked(circuit_t *circ)
return circ->streams_blocked_on_p_chan;
}
}
-
1
0

[tor/maint-0.3.4] Merge branch 'bug25573-034-typefix' into maint-0.3.4
by nickm@torproject.org 15 Nov '18
by nickm@torproject.org 15 Nov '18
15 Nov '18
commit 80a6228aacc9083fae07d4373d9c41017420e6b9
Merge: 15e752e6b 6d33f6563
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Thu Nov 15 16:58:16 2018 -0500
Merge branch 'bug25573-034-typefix' into maint-0.3.4
changes/ticket25573 | 5 +
src/common/container.c | 2 +-
src/common/container.h | 2 +-
src/or/circpathbias.c | 63 +++++
src/or/circpathbias.h | 1 +
src/or/circuitbuild.c | 3 +-
src/or/circuitbuild.h | 3 +-
src/or/circuitlist.c | 8 +
src/or/connection_edge.c | 220 ++++++++++++++++
src/or/connection_edge.h | 17 ++
src/or/or.h | 25 ++
src/or/relay.c | 75 +++++-
src/test/test_relaycell.c | 641 ++++++++++++++++++++++++++++++++++++++++++----
13 files changed, 1014 insertions(+), 51 deletions(-)
1
0

[tor/maint-0.3.4] Fix duplicate declaration of pathbias_count_valid_cells.
by nickm@torproject.org 15 Nov '18
by nickm@torproject.org 15 Nov '18
15 Nov '18
commit 7fd61cf536543283353b618d5bba9a1db637ed14
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Sun Sep 16 13:45:43 2018 -0400
Fix duplicate declaration of pathbias_count_valid_cells.
---
src/test/test_relaycell.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/test/test_relaycell.c b/src/test/test_relaycell.c
index 3f84ee830..ee495cada 100644
--- a/src/test/test_relaycell.c
+++ b/src/test/test_relaycell.c
@@ -31,8 +31,8 @@ void connection_free_minimal(connection_t*);
int connected_cell_format_payload(uint8_t *payload_out,
const tor_addr_t *addr,
uint32_t ttl);
-int pathbias_count_valid_cells(origin_circuit_t *circ,
- cell_t *cell);
+void pathbias_count_valid_cells(origin_circuit_t *circ,
+ cell_t *cell);
half_edge_t *connection_half_edge_find_stream_id(
const smartlist_t *half_conns,
streamid_t stream_id);
@@ -1072,4 +1072,3 @@ struct testcase_t relaycell_tests[] = {
{ "streamwrap", test_halfstream_wrap, TT_FORK, NULL, NULL },
END_OF_TESTCASES
};
-
1
0

[tor/maint-0.3.5] Use the correct function signatures in test_relaycell.c
by nickm@torproject.org 15 Nov '18
by nickm@torproject.org 15 Nov '18
15 Nov '18
commit 6d33f65638734593d10c5c3a5e2eb9d7bdff8000
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Tue Sep 18 15:07:02 2018 -0400
Use the correct function signatures in test_relaycell.c
This is now officially an antipattern: please let's never copy a
function declaration in two places again. That's what headers are
for.
---
src/or/connection_edge.c | 5 ----
src/or/connection_edge.h | 6 +++++
src/test/test_relaycell.c | 65 ++++++++++++++++++++---------------------------
3 files changed, 34 insertions(+), 42 deletions(-)
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 1060e7461..3170dc493 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -136,11 +136,6 @@ static int connection_ap_process_natd(entry_connection_t *conn);
static int connection_exit_connect_dir(edge_connection_t *exitconn);
static int consider_plaintext_ports(entry_connection_t *conn, uint16_t port);
static int connection_ap_supports_optimistic_data(const entry_connection_t *);
-STATIC void connection_half_edge_add(const edge_connection_t *conn,
- origin_circuit_t *circ);
-STATIC half_edge_t *connection_half_edge_find_stream_id(
- const smartlist_t *half_conns,
- streamid_t stream_id);
/** An AP stream has failed/finished. If it hasn't already sent back
* a socks reply, send one now (based on endreason). Also set
diff --git a/src/or/connection_edge.h b/src/or/connection_edge.h
index 6dbba014c..c607c963e 100644
--- a/src/or/connection_edge.h
+++ b/src/or/connection_edge.h
@@ -202,6 +202,12 @@ STATIC void connection_ap_handshake_rewrite(entry_connection_t *conn,
rewrite_result_t *out);
STATIC int connection_ap_process_http_connect(entry_connection_t *conn);
+struct half_edge_t;
+STATIC void connection_half_edge_add(const edge_connection_t *conn,
+ origin_circuit_t *circ);
+STATIC struct half_edge_t *connection_half_edge_find_stream_id(
+ const smartlist_t *half_conns,
+ streamid_t stream_id);
#endif /* defined(CONNECTION_EDGE_PRIVATE) */
#endif /* !defined(TOR_CONNECTION_EDGE_H) */
diff --git a/src/test/test_relaycell.c b/src/test/test_relaycell.c
index ee495cada..2fc0288f6 100644
--- a/src/test/test_relaycell.c
+++ b/src/test/test_relaycell.c
@@ -5,6 +5,9 @@
#define RELAY_PRIVATE
#define CIRCUITLIST_PRIVATE
+#define CONNECTION_EDGE_PRIVATE
+#define CONNECTION_PRIVATE
+
#include "or.h"
#include "main.h"
#include "config.h"
@@ -18,6 +21,11 @@
#include "relay.h"
#include "test.h"
+#include "log_test_helpers.h"
+
+#include "circpathbias.h"
+#include "connection_edge.h"
+
static int srm_ncalls;
static entry_connection_t *srm_conn;
static int srm_atype;
@@ -27,23 +35,6 @@ static uint8_t srm_answer[512];
static int srm_ttl;
static time_t srm_expires;
-void connection_free_minimal(connection_t*);
-int connected_cell_format_payload(uint8_t *payload_out,
- const tor_addr_t *addr,
- uint32_t ttl);
-void pathbias_count_valid_cells(origin_circuit_t *circ,
- cell_t *cell);
-half_edge_t *connection_half_edge_find_stream_id(
- const smartlist_t *half_conns,
- streamid_t stream_id);
-void connection_half_edge_add(const edge_connection_t *conn,
- origin_circuit_t *circ);
-
-int mock_send_command(streamid_t stream_id, circuit_t *circ,
- uint8_t relay_command, const char *payload,
- size_t payload_len, crypt_path_t *cpath_layer,
- const char *filename, int lineno);
-
/* Mock replacement for connection_ap_hannshake_socks_resolved() */
static void
socks_resolved_mock(entry_connection_t *conn,
@@ -143,7 +134,7 @@ mock_start_reading(connection_t *conn)
return;
}
-int
+static int
mock_send_command(streamid_t stream_id, circuit_t *circ,
uint8_t relay_command, const char *payload,
size_t payload_len, crypt_path_t *cpath_layer,
@@ -230,7 +221,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
/* Data cell not in the half-opened list */
PACK_CELL(4000, RELAY_COMMAND_DATA, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -239,7 +230,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
/* Sendme cell not in the half-opened list */
PACK_CELL(4000, RELAY_COMMAND_SENDME, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -248,7 +239,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
/* Connected cell not in the half-opened list */
PACK_CELL(4000, RELAY_COMMAND_CONNECTED, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -257,7 +248,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
/* Resolved cell not in the half-opened list */
PACK_CELL(4000, RELAY_COMMAND_RESOLVED, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -267,7 +258,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
edgeconn = ENTRY_TO_EDGE_CONN(entryconn2);
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_CONNECTED, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -279,7 +270,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -290,7 +281,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -302,7 +293,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_SENDME, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -313,7 +304,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_SENDME, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -324,7 +315,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -334,7 +325,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -359,7 +350,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
connection_edge_reached_eof(edgeconn);
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_CONNECTED, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -369,7 +360,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_CONNECTED, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -380,7 +371,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -399,7 +390,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -419,7 +410,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_RESOLVED,
"\x04\x04\x12\x00\x00\x01\x00\x00\x02\x00");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -438,7 +429,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
ENTRY_TO_CONN(entryconn4)->outbuf_flushlen = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -449,7 +440,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
ENTRY_TO_CONN(entryconn4)->outbuf_flushlen = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -870,7 +861,7 @@ test_circbw_relay(void *arg)
/* Path bias: truncated */
tt_int_op(circ->base_.marked_for_close, OP_EQ, 0);
PACK_CELL(0, RELAY_COMMAND_TRUNCATED, "Data1234");
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
tt_int_op(circ->base_.marked_for_close, OP_EQ, 1);
done:
1
0

[tor/maint-0.3.4] Use the correct function signatures in test_relaycell.c
by nickm@torproject.org 15 Nov '18
by nickm@torproject.org 15 Nov '18
15 Nov '18
commit 6d33f65638734593d10c5c3a5e2eb9d7bdff8000
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Tue Sep 18 15:07:02 2018 -0400
Use the correct function signatures in test_relaycell.c
This is now officially an antipattern: please let's never copy a
function declaration in two places again. That's what headers are
for.
---
src/or/connection_edge.c | 5 ----
src/or/connection_edge.h | 6 +++++
src/test/test_relaycell.c | 65 ++++++++++++++++++++---------------------------
3 files changed, 34 insertions(+), 42 deletions(-)
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 1060e7461..3170dc493 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -136,11 +136,6 @@ static int connection_ap_process_natd(entry_connection_t *conn);
static int connection_exit_connect_dir(edge_connection_t *exitconn);
static int consider_plaintext_ports(entry_connection_t *conn, uint16_t port);
static int connection_ap_supports_optimistic_data(const entry_connection_t *);
-STATIC void connection_half_edge_add(const edge_connection_t *conn,
- origin_circuit_t *circ);
-STATIC half_edge_t *connection_half_edge_find_stream_id(
- const smartlist_t *half_conns,
- streamid_t stream_id);
/** An AP stream has failed/finished. If it hasn't already sent back
* a socks reply, send one now (based on endreason). Also set
diff --git a/src/or/connection_edge.h b/src/or/connection_edge.h
index 6dbba014c..c607c963e 100644
--- a/src/or/connection_edge.h
+++ b/src/or/connection_edge.h
@@ -202,6 +202,12 @@ STATIC void connection_ap_handshake_rewrite(entry_connection_t *conn,
rewrite_result_t *out);
STATIC int connection_ap_process_http_connect(entry_connection_t *conn);
+struct half_edge_t;
+STATIC void connection_half_edge_add(const edge_connection_t *conn,
+ origin_circuit_t *circ);
+STATIC struct half_edge_t *connection_half_edge_find_stream_id(
+ const smartlist_t *half_conns,
+ streamid_t stream_id);
#endif /* defined(CONNECTION_EDGE_PRIVATE) */
#endif /* !defined(TOR_CONNECTION_EDGE_H) */
diff --git a/src/test/test_relaycell.c b/src/test/test_relaycell.c
index ee495cada..2fc0288f6 100644
--- a/src/test/test_relaycell.c
+++ b/src/test/test_relaycell.c
@@ -5,6 +5,9 @@
#define RELAY_PRIVATE
#define CIRCUITLIST_PRIVATE
+#define CONNECTION_EDGE_PRIVATE
+#define CONNECTION_PRIVATE
+
#include "or.h"
#include "main.h"
#include "config.h"
@@ -18,6 +21,11 @@
#include "relay.h"
#include "test.h"
+#include "log_test_helpers.h"
+
+#include "circpathbias.h"
+#include "connection_edge.h"
+
static int srm_ncalls;
static entry_connection_t *srm_conn;
static int srm_atype;
@@ -27,23 +35,6 @@ static uint8_t srm_answer[512];
static int srm_ttl;
static time_t srm_expires;
-void connection_free_minimal(connection_t*);
-int connected_cell_format_payload(uint8_t *payload_out,
- const tor_addr_t *addr,
- uint32_t ttl);
-void pathbias_count_valid_cells(origin_circuit_t *circ,
- cell_t *cell);
-half_edge_t *connection_half_edge_find_stream_id(
- const smartlist_t *half_conns,
- streamid_t stream_id);
-void connection_half_edge_add(const edge_connection_t *conn,
- origin_circuit_t *circ);
-
-int mock_send_command(streamid_t stream_id, circuit_t *circ,
- uint8_t relay_command, const char *payload,
- size_t payload_len, crypt_path_t *cpath_layer,
- const char *filename, int lineno);
-
/* Mock replacement for connection_ap_hannshake_socks_resolved() */
static void
socks_resolved_mock(entry_connection_t *conn,
@@ -143,7 +134,7 @@ mock_start_reading(connection_t *conn)
return;
}
-int
+static int
mock_send_command(streamid_t stream_id, circuit_t *circ,
uint8_t relay_command, const char *payload,
size_t payload_len, crypt_path_t *cpath_layer,
@@ -230,7 +221,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
/* Data cell not in the half-opened list */
PACK_CELL(4000, RELAY_COMMAND_DATA, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -239,7 +230,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
/* Sendme cell not in the half-opened list */
PACK_CELL(4000, RELAY_COMMAND_SENDME, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -248,7 +239,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
/* Connected cell not in the half-opened list */
PACK_CELL(4000, RELAY_COMMAND_CONNECTED, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -257,7 +248,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
/* Resolved cell not in the half-opened list */
PACK_CELL(4000, RELAY_COMMAND_RESOLVED, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -267,7 +258,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
edgeconn = ENTRY_TO_EDGE_CONN(entryconn2);
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_CONNECTED, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -279,7 +270,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -290,7 +281,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -302,7 +293,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_SENDME, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -313,7 +304,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_SENDME, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -324,7 +315,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -334,7 +325,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -359,7 +350,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
connection_edge_reached_eof(edgeconn);
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_CONNECTED, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -369,7 +360,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_CONNECTED, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -380,7 +371,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -399,7 +390,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -419,7 +410,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_RESOLVED,
"\x04\x04\x12\x00\x00\x01\x00\x00\x02\x00");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -438,7 +429,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
ENTRY_TO_CONN(entryconn4)->outbuf_flushlen = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -449,7 +440,7 @@ subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
ENTRY_TO_CONN(entryconn4)->outbuf_flushlen = 0;
PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
else
connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
circ->cpath);
@@ -870,7 +861,7 @@ test_circbw_relay(void *arg)
/* Path bias: truncated */
tt_int_op(circ->base_.marked_for_close, OP_EQ, 0);
PACK_CELL(0, RELAY_COMMAND_TRUNCATED, "Data1234");
- pathbias_count_valid_cells(circ, &cell);
+ pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
tt_int_op(circ->base_.marked_for_close, OP_EQ, 1);
done:
1
0

[tor/maint-0.3.4] Merge remote-tracking branch 'public/ticket27686_034' into maint-0.3.4
by nickm@torproject.org 15 Nov '18
by nickm@torproject.org 15 Nov '18
15 Nov '18
commit fe1fb4b0c3ed175eccacbc1491ccab75375173bb
Merge: 80a6228aa ab92f9342
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Thu Nov 15 17:01:54 2018 -0500
Merge remote-tracking branch 'public/ticket27686_034' into maint-0.3.4
src/or/circuitlist.c | 21 ++++++++++++++++++---
src/or/connection_edge.c | 23 ++++++++++++++++++++++-
src/or/connection_edge.h | 6 +++++-
src/or/relay.c | 2 +-
4 files changed, 46 insertions(+), 6 deletions(-)
1
0

15 Nov '18
commit 7d70f67deaeea1a3dc80a763f13bcec5d7a2425d
Author: juga0 <juga(a)riseup.net>
Date: Sun Jun 3 09:31:19 2018 +0000
Check bandwidth changes only if small uptime
to upload a new descriptor.
---
src/or/router.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/src/or/router.c b/src/or/router.c
index 31f2ff00d..ab916fb6e 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -2425,13 +2425,24 @@ mark_my_descriptor_dirty(const char *reason)
* if our previous bandwidth estimate was exactly 0. */
#define MAX_BANDWIDTH_CHANGE_FREQ (3*60*60)
+/** Maximum uptime to republish our descriptor because of large shifts in
+ * estimated bandwidth. */
+#define MAX_UPTIME_BANDWIDTH_CHANGE (24*60*60)
+
/** Check whether bandwidth has changed a lot since the last time we announced
- * bandwidth. If so, mark our descriptor dirty. */
+ * bandwidth while the uptime is smaller than MAX_UPTIME_BANDWIDTH_CHANGE.
+ * If so, mark our descriptor dirty. */
void
check_descriptor_bandwidth_changed(time_t now)
{
static time_t last_changed = 0;
uint64_t prev, cur;
+
+ /* If the relay uptime is bigger than MAX_UPTIME_BANDWIDTH_CHANGE,
+ * the next regularly scheduled descriptor update (18h) will be enough */
+ if (get_uptime() > MAX_UPTIME_BANDWIDTH_CHANGE)
+ return;
+
if (!router_get_my_routerinfo())
return;
1
0