|
@@ -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);
|
|
|
|
|
|
|
|
|
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;
|
|
|
+
|
|
|
+
|
|
|
+ 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);
|
|
|
+
|
|
|
+
|
|
|
+ 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();
|
|
|
+
|
|
|
+
|
|
|
+ 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();
|
|
|
+
|
|
|
+
|
|
|
+ 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();
|
|
|
+
|
|
|
+
|
|
|
+ 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();
|
|
|
+
|
|
|
+
|
|
|
+ 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();
|
|
|
+
|
|
|
+
|
|
|
+ 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();
|
|
|
+
|
|
|
+
|
|
|
+ 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();
|
|
|
+
|
|
|
+
|
|
|
+ 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;
|
|
|
+
|
|
|
+ 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();
|
|
|
+
|
|
|
+
|
|
|
+ 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();
|
|
|
+
|
|
|
+
|
|
|
+ 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();
|
|
|
+
|
|
|
+
|
|
|
+ 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();
|
|
|
+
|
|
|
+
|
|
|
+ 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();
|
|
|
+
|
|
|
+
|
|
|
+ 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;
|
|
|
+
|
|
|
+
|
|
|
+ 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;
|
|
|
+
|
|
|
+
|
|
|
+ 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);
|
|
|
+
|
|
|
+
|
|
|
+ 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);
|
|
|
+
|
|
|
+
|
|
|
+ * 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);
|
|
|
+
|
|
|
+
|
|
|
+ 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);
|
|
|
+
|
|
|
+
|
|
|
+ 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);
|
|
|
+
|
|
|
+
|
|
|
+ for (i = 0; i < num/2; i++) {
|
|
|
+ tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
|
|
|
+ streams[i]),
|
|
|
+ OP_EQ, 1);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ for (i = 0; i < num/2; i++) {
|
|
|
+ tt_ptr_op(connection_half_edge_find_stream_id(circ->half_streams,
|
|
|
+ streams[i]),
|
|
|
+ OP_EQ, NULL);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ for (; i < num; i++) {
|
|
|
+ tt_ptr_op(connection_half_edge_find_stream_id(circ->half_streams,
|
|
|
+ streams[i]),
|
|
|
+ OP_NE, NULL);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ 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);
|
|
|
+
|
|
|
+
|
|
|
+ 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);
|
|
|
+
|
|
|
+
|
|
|
+ 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;
|
|
|
+
|
|
|
+
|
|
|
+ setup_full_capture_of_logs(LOG_WARN);
|
|
|
+
|
|
|
+
|
|
|
+ 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);
|
|
|
|
|
|
|
|
|
PACK_CELL(0, RELAY_COMMAND_END, "Data1234");
|
|
@@ -191,7 +667,7 @@ test_circbw_relay(void *arg)
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
PACK_CELL(1, RELAY_COMMAND_CONNECTED, "Data1234");
|
|
@@ -221,42 +697,43 @@ test_circbw_relay(void *arg)
|
|
|
ASSERT_UNCOUNTED_BW();
|
|
|
|
|
|
|
|
|
- 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();
|
|
|
|
|
|
|
|
|
- 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();
|
|
|
|
|
|
|
|
|
- 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();
|
|
|
|
|
|
|
|
|
- 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();
|
|
|
|
|
|
|
|
|
- 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();
|
|
|
|
|
|
|
|
|
- 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();
|
|
|
|
|
|
-
|
|
|
- PACK_CELL(1, RELAY_COMMAND_END, "Data1234");
|
|
|
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
|
|
|
- circ->cpath);
|
|
|
- ASSERT_COUNTED_BW();
|
|
|
-
|
|
|
-
|
|
|
- PACK_CELL(1, RELAY_COMMAND_END, "Data1234");
|
|
|
- connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
|
|
|
- circ->cpath);
|
|
|
- ASSERT_UNCOUNTED_BW();
|
|
|
-
|
|
|
|
|
|
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();
|
|
|
|
|
|
+
|
|
|
+ PACK_CELL(1, RELAY_COMMAND_END, "Data1234");
|
|
|
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
|
|
|
+ circ->cpath);
|
|
|
+ ASSERT_COUNTED_BW();
|
|
|
+
|
|
|
+
|
|
|
+ PACK_CELL(1, RELAY_COMMAND_END, "Data1234");
|
|
|
+ connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
|
|
|
+ circ->cpath);
|
|
|
+ ASSERT_UNCOUNTED_BW();
|
|
|
+
|
|
|
+
|
|
|
+ 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));
|
|
|
}
|
|
|
|
|
|
|
|
@@ -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
|
|
|
};
|
|
|
|