mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 21:23:58 +01:00
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.
This commit is contained in:
parent
c56f63eadb
commit
144647031a
@ -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;
|
||||
}
|
||||
|
||||
|
@ -617,6 +617,65 @@ test_halfstream_insertremove(void *arg)
|
||||
subtest_halfstream_insertremove(1000);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@ -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
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user