aboutsummaryrefslogtreecommitdiff
path: root/src/test/test_relaycell.c
diff options
context:
space:
mode:
authorMike Perry <mikeperry-git@torproject.org>2018-08-29 00:06:38 +0000
committerMike Perry <mikeperry-git@torproject.org>2018-08-29 04:12:15 +0000
commit144647031aa9e7eacc6f7cdd8fed663c7229b2aa (patch)
treee1fba569a81e9bcf4c8c72aa5ce8b522e3043ccb /src/test/test_relaycell.c
parentc56f63eadbc5b83b48e57235b194bd8f76b534bb (diff)
downloadtor-144647031aa9e7eacc6f7cdd8fed663c7229b2aa.tar.gz
tor-144647031aa9e7eacc6f7cdd8fed663c7229b2aa.zip
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.
Diffstat (limited to 'src/test/test_relaycell.c')
-rw-r--r--src/test/test_relaycell.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/src/test/test_relaycell.c b/src/test/test_relaycell.c
index 1570e15163..4c406a9b76 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
};