1 /* Copyright (c) 2014-2020, The Tor Project, Inc. */
2 /* See LICENSE for licensing information */
4 /* Unit tests for handling different kinds of relay cell */
6 #define CIRCUITLIST_PRIVATE
7 #define NETWORKSTATUS_PRIVATE
11 #include "core/or/circuit_st.h"
12 #include "core/or/or_circuit_st.h"
13 #include "core/or/origin_circuit_st.h"
14 #include "core/or/circuitlist.h"
15 #include "core/or/relay.h"
16 #include "core/or/sendme.h"
18 #include "feature/nodelist/networkstatus.h"
19 #include "feature/nodelist/networkstatus_st.h"
21 #include "lib/crypt_ops/crypto_digest.h"
23 #include "test/test.h"
24 #include "test/log_test_helpers.h"
27 setup_mock_consensus(void)
29 current_md_consensus
= current_ns_consensus
=
30 tor_malloc_zero(sizeof(networkstatus_t
));
31 current_md_consensus
->net_params
= smartlist_new();
32 current_md_consensus
->routerstatus_list
= smartlist_new();
36 free_mock_consensus(void)
38 SMARTLIST_FOREACH(current_md_consensus
->routerstatus_list
, void *, r
,
40 smartlist_free(current_md_consensus
->routerstatus_list
);
41 smartlist_free(current_ns_consensus
->net_params
);
42 tor_free(current_ns_consensus
);
46 test_v1_record_digest(void *arg
)
48 or_circuit_t
*or_circ
= NULL
;
49 circuit_t
*circ
= NULL
;
53 /* Create our dummy circuit. */
54 or_circ
= or_circuit_new(1, NULL
);
55 /* Points it to the OR circuit now. */
56 circ
= TO_CIRCUIT(or_circ
);
58 /* The package window has to be a multiple of CIRCWINDOW_INCREMENT minus 1
59 * in order to catch the CIRCWINDOW_INCREMENT-nth cell. Try something that
60 * shouldn't be noted. */
61 circ
->package_window
= CIRCWINDOW_INCREMENT
;
62 sendme_record_cell_digest_on_circ(circ
, NULL
);
63 tt_assert(!circ
->sendme_last_digests
);
65 /* This should work now. Package window at CIRCWINDOW_INCREMENT + 1. */
66 circ
->package_window
++;
67 sendme_record_cell_digest_on_circ(circ
, NULL
);
68 tt_assert(circ
->sendme_last_digests
);
69 tt_int_op(smartlist_len(circ
->sendme_last_digests
), OP_EQ
, 1);
71 /* Next cell in the package window shouldn't do anything. */
72 circ
->package_window
++;
73 sendme_record_cell_digest_on_circ(circ
, NULL
);
74 tt_int_op(smartlist_len(circ
->sendme_last_digests
), OP_EQ
, 1);
76 /* The next CIRCWINDOW_INCREMENT should add one more digest. */
77 circ
->package_window
= (CIRCWINDOW_INCREMENT
* 2) + 1;
78 sendme_record_cell_digest_on_circ(circ
, NULL
);
79 tt_int_op(smartlist_len(circ
->sendme_last_digests
), OP_EQ
, 2);
86 test_v1_consensus_params(void *arg
)
90 setup_mock_consensus();
91 tt_assert(current_md_consensus
);
94 smartlist_add(current_md_consensus
->net_params
,
95 (void *) "sendme_emit_min_version=0");
96 smartlist_add(current_md_consensus
->net_params
,
97 (void *) "sendme_accept_min_version=0");
98 tt_int_op(get_emit_min_version(), OP_EQ
, 0);
99 tt_int_op(get_accept_min_version(), OP_EQ
, 0);
100 smartlist_clear(current_md_consensus
->net_params
);
103 smartlist_add(current_md_consensus
->net_params
,
104 (void *) "sendme_emit_min_version=1");
105 smartlist_add(current_md_consensus
->net_params
,
106 (void *) "sendme_accept_min_version=1");
107 tt_int_op(get_emit_min_version(), OP_EQ
, 1);
108 tt_int_op(get_accept_min_version(), OP_EQ
, 1);
109 smartlist_clear(current_md_consensus
->net_params
);
111 /* Different values from each other. */
112 smartlist_add(current_md_consensus
->net_params
,
113 (void *) "sendme_emit_min_version=1");
114 smartlist_add(current_md_consensus
->net_params
,
115 (void *) "sendme_accept_min_version=0");
116 tt_int_op(get_emit_min_version(), OP_EQ
, 1);
117 tt_int_op(get_accept_min_version(), OP_EQ
, 0);
118 smartlist_clear(current_md_consensus
->net_params
);
120 /* Validate is the cell version is coherent with our internal default value
121 * and the one in the consensus. */
122 smartlist_add(current_md_consensus
->net_params
,
123 (void *) "sendme_accept_min_version=1");
124 /* Minimum acceptable value is 1. */
125 tt_int_op(cell_version_can_be_handled(1), OP_EQ
, true);
126 /* Minimum acceptable value is 1 so a cell version of 0 is refused. */
127 tt_int_op(cell_version_can_be_handled(0), OP_EQ
, false);
130 free_mock_consensus();
134 test_v1_build_cell(void *arg
)
136 uint8_t payload
[RELAY_PAYLOAD_SIZE
], digest
[DIGEST_LEN
];
138 crypto_digest_t
*cell_digest
= NULL
;
139 or_circuit_t
*or_circ
= NULL
;
140 circuit_t
*circ
= NULL
;
144 or_circ
= or_circuit_new(1, NULL
);
145 circ
= TO_CIRCUIT(or_circ
);
146 circ
->sendme_last_digests
= smartlist_new();
148 cell_digest
= crypto_digest_new();
149 tt_assert(cell_digest
);
150 crypto_digest_add_bytes(cell_digest
, "AAAAAAAAAAAAAAAAAAAA", 20);
151 crypto_digest_get_digest(cell_digest
, (char *) digest
, sizeof(digest
));
152 smartlist_add(circ
->sendme_last_digests
, tor_memdup(digest
, sizeof(digest
)));
154 /* SENDME v1 payload is 3 bytes + 20 bytes digest. See spec. */
155 ret
= build_cell_payload_v1(digest
, payload
);
156 tt_int_op(ret
, OP_EQ
, 23);
160 /* An empty payload means SENDME version 0 thus valid. */
161 tt_int_op(sendme_is_valid(circ
, payload
, 0), OP_EQ
, true);
162 /* Current phoney digest should have been popped. */
163 tt_int_op(smartlist_len(circ
->sendme_last_digests
), OP_EQ
, 0);
165 /* An unparseable cell means invalid. */
166 setup_full_capture_of_logs(LOG_INFO
);
167 tt_int_op(sendme_is_valid(circ
, (const uint8_t *) "A", 1), OP_EQ
, false);
168 expect_log_msg_containing("Unparseable SENDME cell received. "
170 teardown_capture_of_logs();
172 /* No cell digest recorded for this. */
173 setup_full_capture_of_logs(LOG_INFO
);
174 tt_int_op(sendme_is_valid(circ
, payload
, sizeof(payload
)), OP_EQ
, false);
175 expect_log_msg_containing("We received a SENDME but we have no cell digests "
176 "to match. Closing circuit.");
177 teardown_capture_of_logs();
179 /* Note the wrong digest in the circuit, cell should fail validation. */
180 circ
->package_window
= CIRCWINDOW_INCREMENT
+ 1;
181 sendme_record_cell_digest_on_circ(circ
, NULL
);
182 tt_int_op(smartlist_len(circ
->sendme_last_digests
), OP_EQ
, 1);
183 setup_full_capture_of_logs(LOG_INFO
);
184 tt_int_op(sendme_is_valid(circ
, payload
, sizeof(payload
)), OP_EQ
, false);
185 /* After a validation, the last digests is always popped out. */
186 tt_int_op(smartlist_len(circ
->sendme_last_digests
), OP_EQ
, 0);
187 expect_log_msg_containing("SENDME v1 cell digest do not match.");
188 teardown_capture_of_logs();
190 /* Record the cell digest into the circuit, cell should validate. */
191 memcpy(or_circ
->crypto
.sendme_digest
, digest
, sizeof(digest
));
192 circ
->package_window
= CIRCWINDOW_INCREMENT
+ 1;
193 sendme_record_cell_digest_on_circ(circ
, NULL
);
194 tt_int_op(smartlist_len(circ
->sendme_last_digests
), OP_EQ
, 1);
195 tt_int_op(sendme_is_valid(circ
, payload
, sizeof(payload
)), OP_EQ
, true);
196 /* After a validation, the last digests is always popped out. */
197 tt_int_op(smartlist_len(circ
->sendme_last_digests
), OP_EQ
, 0);
200 crypto_digest_free(cell_digest
);
205 test_cell_payload_pad(void *arg
)
207 size_t pad_offset
, payload_len
, expected_offset
;
211 /* Offset should be 0, not enough room for padding. */
212 payload_len
= RELAY_PAYLOAD_SIZE
;
213 pad_offset
= get_pad_cell_offset(payload_len
);
214 tt_int_op(pad_offset
, OP_EQ
, 0);
215 tt_int_op(CELL_PAYLOAD_SIZE
- pad_offset
, OP_LE
, CELL_PAYLOAD_SIZE
);
217 /* Still no room because we keep 4 extra bytes. */
218 pad_offset
= get_pad_cell_offset(payload_len
- 4);
219 tt_int_op(pad_offset
, OP_EQ
, 0);
220 tt_int_op(CELL_PAYLOAD_SIZE
- pad_offset
, OP_LE
, CELL_PAYLOAD_SIZE
);
222 /* We should have 1 byte of padding. Meaning, the offset should be the
223 * CELL_PAYLOAD_SIZE minus 1 byte. */
224 expected_offset
= CELL_PAYLOAD_SIZE
- 1;
225 pad_offset
= get_pad_cell_offset(payload_len
- 5);
226 tt_int_op(pad_offset
, OP_EQ
, expected_offset
);
227 tt_int_op(CELL_PAYLOAD_SIZE
- pad_offset
, OP_LE
, CELL_PAYLOAD_SIZE
);
229 /* Now some arbitrary small payload length. The cell size is header + 10 +
230 * extra 4 bytes we keep so the offset should be there. */
231 expected_offset
= RELAY_HEADER_SIZE
+ 10 + 4;
232 pad_offset
= get_pad_cell_offset(10);
233 tt_int_op(pad_offset
, OP_EQ
, expected_offset
);
234 tt_int_op(CELL_PAYLOAD_SIZE
- pad_offset
, OP_LE
, CELL_PAYLOAD_SIZE
);
236 /* Data length of 0. */
237 expected_offset
= RELAY_HEADER_SIZE
+ 4;
238 pad_offset
= get_pad_cell_offset(0);
239 tt_int_op(pad_offset
, OP_EQ
, expected_offset
);
240 tt_int_op(CELL_PAYLOAD_SIZE
- pad_offset
, OP_LE
, CELL_PAYLOAD_SIZE
);
247 test_cell_version_validation(void *arg
)
251 /* We currently only support up to SENDME_MAX_SUPPORTED_VERSION so we are
252 * going to test the boundaries there. */
254 tt_assert(cell_version_can_be_handled(SENDME_MAX_SUPPORTED_VERSION
));
256 /* Version below our supported should pass. */
257 tt_assert(cell_version_can_be_handled(SENDME_MAX_SUPPORTED_VERSION
- 1));
259 /* Extra version from our supported should fail. */
260 tt_assert(!cell_version_can_be_handled(SENDME_MAX_SUPPORTED_VERSION
+ 1));
262 /* Simple check for version 0. */
263 tt_assert(cell_version_can_be_handled(0));
265 /* We MUST handle the default cell version that we emit or accept. */
266 tt_assert(cell_version_can_be_handled(SENDME_EMIT_MIN_VERSION_DEFAULT
));
267 tt_assert(cell_version_can_be_handled(SENDME_ACCEPT_MIN_VERSION_DEFAULT
));
273 /* check our decisions about how much stuff to put into relay cells. */
275 test_package_payload_len(void *arg
)
278 /* this is not a real circuit: it only has the fields needed for this
280 circuit_t
*c
= tor_malloc_zero(sizeof(circuit_t
));
282 /* check initial conditions. */
283 circuit_reset_sendme_randomness(c
);
284 tt_assert(! c
->have_sent_sufficiently_random_cell
);
285 tt_int_op(c
->send_randomness_after_n_cells
, OP_GE
, CIRCWINDOW_INCREMENT
/ 2);
286 tt_int_op(c
->send_randomness_after_n_cells
, OP_LT
, CIRCWINDOW_INCREMENT
);
288 /* We have a bunch of cells before we need to send randomness, so the first
289 * few can be packaged full. */
290 int initial
= c
->send_randomness_after_n_cells
;
291 size_t n
= connection_edge_get_inbuf_bytes_to_package(10000, 0, c
);
292 tt_uint_op(RELAY_PAYLOAD_SIZE
, OP_EQ
, n
);
293 n
= connection_edge_get_inbuf_bytes_to_package(95000, 1, c
);
294 tt_uint_op(RELAY_PAYLOAD_SIZE
, OP_EQ
, n
);
295 tt_int_op(c
->send_randomness_after_n_cells
, OP_EQ
, initial
- 2);
297 /* If package_partial isn't set, we won't package a partially full cell at
299 n
= connection_edge_get_inbuf_bytes_to_package(RELAY_PAYLOAD_SIZE
-1, 0, c
);
300 tt_int_op(n
, OP_EQ
, 0);
301 /* no change in our state, since nothing was sent. */
302 tt_assert(! c
->have_sent_sufficiently_random_cell
);
303 tt_int_op(c
->send_randomness_after_n_cells
, OP_EQ
, initial
- 2);
305 /* If package_partial is set and the partial cell is not going to have
306 * _enough_ randomness, we package it, but we don't consider ourselves to
307 * have sent a sufficiently random cell. */
308 n
= connection_edge_get_inbuf_bytes_to_package(RELAY_PAYLOAD_SIZE
-1, 1, c
);
309 tt_int_op(n
, OP_EQ
, RELAY_PAYLOAD_SIZE
-1);
310 tt_assert(! c
->have_sent_sufficiently_random_cell
);
311 tt_int_op(c
->send_randomness_after_n_cells
, OP_EQ
, initial
- 3);
313 /* Make sure we set have_set_sufficiently_random_cell as appropriate. */
314 n
= connection_edge_get_inbuf_bytes_to_package(RELAY_PAYLOAD_SIZE
-64, 1, c
);
315 tt_int_op(n
, OP_EQ
, RELAY_PAYLOAD_SIZE
-64);
316 tt_assert(c
->have_sent_sufficiently_random_cell
);
317 tt_int_op(c
->send_randomness_after_n_cells
, OP_EQ
, initial
- 4);
319 /* Now let's look at what happens when we get down to zero. Since we have
320 * sent a sufficiently random cell, we will not force this one to have a gap.
322 c
->send_randomness_after_n_cells
= 0;
323 n
= connection_edge_get_inbuf_bytes_to_package(10000, 1, c
);
324 tt_int_op(n
, OP_EQ
, RELAY_PAYLOAD_SIZE
);
325 /* Now these will be reset. */
326 tt_assert(! c
->have_sent_sufficiently_random_cell
);
327 tt_int_op(c
->send_randomness_after_n_cells
, OP_GE
,
328 CIRCWINDOW_INCREMENT
/ 2 - 1);
330 /* What would happen if we hadn't sent a sufficiently random cell? */
331 c
->send_randomness_after_n_cells
= 0;
332 n
= connection_edge_get_inbuf_bytes_to_package(10000, 1, c
);
333 const size_t reduced_payload_size
= RELAY_PAYLOAD_SIZE
- 4 - 16;
334 tt_int_op(n
, OP_EQ
, reduced_payload_size
);
335 /* Now these will be reset. */
336 tt_assert(! c
->have_sent_sufficiently_random_cell
);
337 tt_int_op(c
->send_randomness_after_n_cells
, OP_GE
,
338 CIRCWINDOW_INCREMENT
/ 2 - 1);
340 /* Here is a fun case: if it's time to package a small cell, then
341 * package_partial==0 should mean we accept that many bytes.
343 c
->send_randomness_after_n_cells
= 0;
344 n
= connection_edge_get_inbuf_bytes_to_package(reduced_payload_size
, 0, c
);
345 tt_int_op(n
, OP_EQ
, reduced_payload_size
);
351 struct testcase_t sendme_tests
[] = {
352 { "v1_record_digest", test_v1_record_digest
, TT_FORK
,
354 { "v1_consensus_params", test_v1_consensus_params
, TT_FORK
,
356 { "v1_build_cell", test_v1_build_cell
, TT_FORK
,
358 { "cell_payload_pad", test_cell_payload_pad
, TT_FORK
,
360 { "cell_version_validation", test_cell_version_validation
, TT_FORK
,
362 { "package_payload_len", test_package_payload_len
, 0, NULL
, NULL
},