1 /* Copyright (c) 2001-2004, Roger Dingledine.
2 * Copyright (c) 2007-2021, The Tor Project, Inc. */
3 /* See LICENSE for licensing information */
7 * \brief Unit tests for many pieces of the lower level Tor modules.
11 #include "lib/crypt_ops/crypto_dh.h"
12 #include "lib/crypt_ops/crypto_rand.h"
13 #include "app/config/or_state_st.h"
14 #include "test/rng_test_helpers.h"
26 #endif /* defined(_WIN32) */
30 /* These macros pull in declarations for some functions and structures that
31 * are typically file-private. */
32 #define ROUTER_PRIVATE
33 #define CIRCUITSTATS_PRIVATE
34 #define CIRCUITLIST_PRIVATE
35 #define MAINLOOP_PRIVATE
36 #define STATEFILE_PRIVATE
38 #include "core/or/or.h"
39 #include "lib/err/backtrace.h"
40 #include "lib/buf/buffers.h"
41 #include "core/or/circuitlist.h"
42 #include "core/or/circuitstats.h"
43 #include "lib/compress/compress.h"
44 #include "app/config/config.h"
45 #include "core/or/connection_edge.h"
46 #include "core/or/extendinfo.h"
47 #include "test/test.h"
48 #include "core/mainloop/mainloop.h"
49 #include "lib/memarea/memarea.h"
50 #include "core/or/onion.h"
51 #include "core/crypto/onion_ntor.h"
52 #include "core/crypto/onion_fast.h"
53 #include "core/crypto/onion_tap.h"
54 #include "core/or/policies.h"
55 #include "lib/sandbox/sandbox.h"
56 #include "app/config/statefile.h"
57 #include "lib/crypt_ops/crypto_curve25519.h"
58 #include "feature/nodelist/networkstatus.h"
60 #include "core/or/extend_info_st.h"
61 #include "core/or/or_circuit_st.h"
62 #include "feature/relay/onion_queue.h"
64 /** Run unit tests for the onion handshake code. */
66 test_onion_handshake(void *arg
)
69 crypto_dh_t
*c_dh
= NULL
;
70 char c_buf
[TAP_ONIONSKIN_CHALLENGE_LEN
];
73 char s_buf
[TAP_ONIONSKIN_REPLY_LEN
];
77 crypto_pk_t
*pk
= NULL
, *pk2
= NULL
;
83 /* client handshake 1. */
84 memset(c_buf
, 0, TAP_ONIONSKIN_CHALLENGE_LEN
);
85 tt_assert(! onion_skin_TAP_create(pk
, &c_dh
, c_buf
));
87 for (i
= 1; i
<= 3; ++i
) {
90 /* server handshake: only one key known. */
93 /* server handshake: try the right key first. */
96 /* server handshake: try the right key second. */
100 memset(s_buf
, 0, TAP_ONIONSKIN_REPLY_LEN
);
101 memset(s_keys
, 0, 40);
102 tt_assert(! onion_skin_TAP_server_handshake(c_buf
, k1
, k2
,
105 /* client handshake 2 */
106 memset(c_keys
, 0, 40);
107 tt_assert(! onion_skin_TAP_client_handshake(c_dh
, s_buf
, c_keys
,
110 tt_mem_op(c_keys
,OP_EQ
, s_keys
, 40);
111 memset(s_buf
, 0, 40);
112 tt_mem_op(c_keys
,OP_NE
, s_buf
, 40);
115 crypto_dh_free(c_dh
);
121 test_bad_onion_handshake(void *arg
)
123 char junk_buf
[TAP_ONIONSKIN_CHALLENGE_LEN
];
124 char junk_buf2
[TAP_ONIONSKIN_CHALLENGE_LEN
];
126 crypto_dh_t
*c_dh
= NULL
;
127 char c_buf
[TAP_ONIONSKIN_CHALLENGE_LEN
];
130 char s_buf
[TAP_ONIONSKIN_REPLY_LEN
];
133 crypto_pk_t
*pk
= NULL
, *pk2
= NULL
;
138 pk2
= pk_generate(1);
140 /* Server: Case 1: the encrypted data is degenerate. */
141 memset(junk_buf
, 0, sizeof(junk_buf
));
142 crypto_pk_obsolete_public_hybrid_encrypt(pk
,
143 junk_buf2
, TAP_ONIONSKIN_CHALLENGE_LEN
,
144 junk_buf
, DH1024_KEY_LEN
,
145 PK_PKCS1_OAEP_PADDING
, 1);
147 onion_skin_TAP_server_handshake(junk_buf2
, pk
, NULL
,
150 /* Server: Case 2: the encrypted data is not long enough. */
151 memset(junk_buf
, 0, sizeof(junk_buf
));
152 memset(junk_buf2
, 0, sizeof(junk_buf2
));
153 crypto_pk_public_encrypt(pk
, junk_buf2
, sizeof(junk_buf2
),
154 junk_buf
, 48, PK_PKCS1_OAEP_PADDING
);
156 onion_skin_TAP_server_handshake(junk_buf2
, pk
, NULL
,
159 /* client handshake 1: do it straight. */
160 memset(c_buf
, 0, TAP_ONIONSKIN_CHALLENGE_LEN
);
161 tt_assert(! onion_skin_TAP_create(pk
, &c_dh
, c_buf
));
163 /* Server: Case 3: we just don't have the right key. */
165 onion_skin_TAP_server_handshake(c_buf
, pk2
, NULL
,
168 /* Server: Case 4: The RSA-encrypted portion is corrupt. */
171 onion_skin_TAP_server_handshake(c_buf
, pk
, NULL
,
175 /* (Let the server proceed) */
177 onion_skin_TAP_server_handshake(c_buf
, pk
, NULL
,
180 /* Client: Case 1: The server sent back junk. */
181 const char *msg
= NULL
;
184 onion_skin_TAP_client_handshake(c_dh
, s_buf
, c_keys
, 40, &msg
));
186 tt_str_op(msg
, OP_EQ
, "Digest DOES NOT MATCH on onion handshake. "
189 /* Let the client finish; make sure it can. */
192 onion_skin_TAP_client_handshake(c_dh
, s_buf
, c_keys
, 40, &msg
));
193 tt_mem_op(s_keys
,OP_EQ
, c_keys
, 40);
194 tt_ptr_op(msg
, OP_EQ
, NULL
);
196 /* Client: Case 2: The server sent back a degenerate DH. */
197 memset(s_buf
, 0, sizeof(s_buf
));
199 onion_skin_TAP_client_handshake(c_dh
, s_buf
, c_keys
, 40, &msg
));
200 tt_str_op(msg
, OP_EQ
, "DH computation failed.");
203 crypto_dh_free(c_dh
);
209 test_ntor_handshake(void *arg
)
212 ntor_handshake_state_t
*c_state
= NULL
;
213 uint8_t c_buf
[NTOR_ONIONSKIN_LEN
];
217 di_digest256_map_t
*s_keymap
=NULL
;
218 curve25519_keypair_t s_keypair
;
219 uint8_t s_buf
[NTOR_REPLY_LEN
];
223 const curve25519_public_key_t
*server_pubkey
;
224 uint8_t node_id
[20] = "abcdefghijklmnopqrst";
228 /* Make the server some keys */
229 curve25519_secret_key_generate(&s_keypair
.seckey
, 0);
230 curve25519_public_key_generate(&s_keypair
.pubkey
, &s_keypair
.seckey
);
231 dimap_add_entry(&s_keymap
, s_keypair
.pubkey
.public_key
, &s_keypair
);
232 server_pubkey
= &s_keypair
.pubkey
;
234 /* client handshake 1. */
235 memset(c_buf
, 0, NTOR_ONIONSKIN_LEN
);
236 tt_int_op(0, OP_EQ
, onion_skin_ntor_create(node_id
, server_pubkey
,
239 /* server handshake */
240 memset(s_buf
, 0, NTOR_REPLY_LEN
);
241 memset(s_keys
, 0, 40);
242 tt_int_op(0, OP_EQ
, onion_skin_ntor_server_handshake(c_buf
, s_keymap
, NULL
,
244 s_buf
, s_keys
, 400));
246 /* client handshake 2 */
247 memset(c_keys
, 0, 40);
248 tt_int_op(0, OP_EQ
, onion_skin_ntor_client_handshake(c_state
, s_buf
,
251 tt_mem_op(c_keys
,OP_EQ
, s_keys
, 400);
252 memset(s_buf
, 0, 40);
253 tt_mem_op(c_keys
,OP_NE
, s_buf
, 40);
255 /* Now try with a bogus server response. Zero input should trigger
256 * All The Problems. */
257 memset(c_keys
, 0, 400);
258 memset(s_buf
, 0, NTOR_REPLY_LEN
);
259 const char *msg
= NULL
;
260 tt_int_op(-1, OP_EQ
, onion_skin_ntor_client_handshake(c_state
, s_buf
,
262 tt_str_op(msg
, OP_EQ
, "Zero output from curve25519 handshake");
265 ntor_handshake_state_free(c_state
);
266 dimap_free(s_keymap
, NULL
);
270 test_fast_handshake(void *arg
)
272 /* tests for the obsolete "CREATE_FAST" handshake. */
274 fast_handshake_state_t
*state
= NULL
;
275 uint8_t client_handshake
[CREATE_FAST_LEN
];
276 uint8_t server_handshake
[CREATED_FAST_LEN
];
277 uint8_t s_keys
[100], c_keys
[100];
279 /* First, test an entire handshake. */
280 memset(client_handshake
, 0, sizeof(client_handshake
));
281 tt_int_op(0, OP_EQ
, fast_onionskin_create(&state
, client_handshake
));
282 tt_assert(! fast_mem_is_zero((char*)client_handshake
,
283 sizeof(client_handshake
)));
286 fast_server_handshake(client_handshake
, server_handshake
,
288 const char *msg
= NULL
;
290 fast_client_handshake(state
, server_handshake
, c_keys
, 100, &msg
));
291 tt_ptr_op(msg
, OP_EQ
, NULL
);
292 tt_mem_op(s_keys
, OP_EQ
, c_keys
, 100);
294 /* Now test a failing handshake. */
295 server_handshake
[0] ^= 3;
297 fast_client_handshake(state
, server_handshake
, c_keys
, 100, &msg
));
298 tt_str_op(msg
, OP_EQ
, "Digest DOES NOT MATCH on fast handshake. "
302 fast_handshake_state_free(state
);
305 /** Run unit tests for the onion queues. */
307 test_onion_queues(void *arg
)
309 uint8_t buf1
[TAP_ONIONSKIN_CHALLENGE_LEN
] = {0};
310 uint8_t buf2
[NTOR_ONIONSKIN_LEN
] = {0};
312 or_circuit_t
*circ1
= or_circuit_new(0, NULL
);
313 or_circuit_t
*circ2
= or_circuit_new(0, NULL
);
315 create_cell_t
*onionskin
= NULL
, *create2_ptr
;
316 create_cell_t
*create1
= tor_malloc_zero(sizeof(create_cell_t
));
317 create_cell_t
*create2
= tor_malloc_zero(sizeof(create_cell_t
));
319 create2_ptr
= create2
; /* remember, but do not free */
321 create_cell_init(create1
, CELL_CREATE
, ONION_HANDSHAKE_TYPE_TAP
,
322 TAP_ONIONSKIN_CHALLENGE_LEN
, buf1
);
323 create_cell_init(create2
, CELL_CREATE
, ONION_HANDSHAKE_TYPE_NTOR
,
324 NTOR_ONIONSKIN_LEN
, buf2
);
326 tt_int_op(0,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP
));
327 tt_int_op(0,OP_EQ
, onion_pending_add(circ1
, create1
));
329 tt_int_op(1,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP
));
331 tt_int_op(0,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR
));
332 tt_int_op(0,OP_EQ
, onion_pending_add(circ2
, create2
));
334 tt_int_op(1,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR
));
336 tt_ptr_op(circ2
,OP_EQ
, onion_next_task(&onionskin
));
337 tt_int_op(1,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP
));
338 tt_int_op(0,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR
));
339 tt_ptr_op(onionskin
, OP_EQ
, create2_ptr
);
341 clear_pending_onions();
342 tt_int_op(0,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP
));
343 tt_int_op(0,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR
));
346 circuit_free_(TO_CIRCUIT(circ1
));
347 circuit_free_(TO_CIRCUIT(circ2
));
354 * Test onion queue priority, separation, and resulting
357 * create and add a mix of TAP, NTOR2, and NTORv3. Ensure
358 * they all end up in the right queue. In particular, ntorv2
359 * and ntorv3 should share a queue, but TAP should be separate,
360 * and lower prioritt.
362 * We test this by way of adding TAP first, and then an interleaving
363 * order of ntor2 and ntor3, and check that the ntor2 and ntor3 are
364 * still interleaved, but TAP comes last. */
366 test_onion_queue_order(void *arg
)
368 uint8_t buf_tap
[TAP_ONIONSKIN_CHALLENGE_LEN
] = {0};
369 uint8_t buf_ntor
[NTOR_ONIONSKIN_LEN
] = {0};
370 uint8_t buf_ntor3
[CELL_PAYLOAD_SIZE
] = {0};
372 or_circuit_t
*circ_tap
= or_circuit_new(0, NULL
);
373 or_circuit_t
*circ_ntor
= or_circuit_new(0, NULL
);
374 or_circuit_t
*circ_ntor3
= or_circuit_new(0, NULL
);
376 create_cell_t
*onionskin
= NULL
;
377 create_cell_t
*create_tap1
= tor_malloc_zero(sizeof(create_cell_t
));
378 create_cell_t
*create_ntor1
= tor_malloc_zero(sizeof(create_cell_t
));
379 create_cell_t
*create_ntor2
= tor_malloc_zero(sizeof(create_cell_t
));
380 create_cell_t
*create_v3ntor1
= tor_malloc_zero(sizeof(create_cell_t
));
381 create_cell_t
*create_v3ntor2
= tor_malloc_zero(sizeof(create_cell_t
));
384 create_cell_init(create_tap1
, CELL_CREATE
, ONION_HANDSHAKE_TYPE_TAP
,
385 TAP_ONIONSKIN_CHALLENGE_LEN
, buf_tap
);
386 create_cell_init(create_ntor1
, CELL_CREATE
, ONION_HANDSHAKE_TYPE_NTOR
,
387 NTOR_ONIONSKIN_LEN
, buf_ntor
);
388 create_cell_init(create_ntor2
, CELL_CREATE
, ONION_HANDSHAKE_TYPE_NTOR
,
389 NTOR_ONIONSKIN_LEN
, buf_ntor
);
390 create_cell_init(create_v3ntor1
, CELL_CREATE2
, ONION_HANDSHAKE_TYPE_NTOR_V3
,
391 NTOR_ONIONSKIN_LEN
, buf_ntor3
);
392 create_cell_init(create_v3ntor2
, CELL_CREATE2
, ONION_HANDSHAKE_TYPE_NTOR_V3
,
393 NTOR_ONIONSKIN_LEN
, buf_ntor3
);
395 /* sanity check queue init */
396 tt_int_op(0,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP
));
397 tt_int_op(0,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR
));
398 tt_int_op(0,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR_V3
));
400 /* Add tap first so we can ensure it comes out last */
401 tt_int_op(0,OP_EQ
, onion_pending_add(circ_tap
, create_tap1
));
402 tt_int_op(1,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP
));
403 tt_int_op(0,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR
));
404 tt_int_op(0,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR_V3
));
406 /* Now add interleaving ntor2 and ntor3, to ensure they share
407 * the same queue and come out in this order */
408 tt_int_op(0,OP_EQ
, onion_pending_add(circ_ntor
, create_ntor1
));
409 tt_int_op(1,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP
));
410 tt_int_op(1,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR
));
411 tt_int_op(1,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR_V3
));
413 tt_int_op(0,OP_EQ
, onion_pending_add(circ_ntor3
, create_v3ntor1
));
414 tt_int_op(1,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP
));
415 tt_int_op(2,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR
));
416 tt_int_op(2,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR_V3
));
418 tt_int_op(0,OP_EQ
, onion_pending_add(circ_ntor
, create_ntor2
));
419 tt_int_op(1,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP
));
420 tt_int_op(3,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR
));
421 tt_int_op(3,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR_V3
));
423 tt_int_op(0,OP_EQ
, onion_pending_add(circ_ntor3
, create_v3ntor2
));
424 tt_int_op(1,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP
));
425 tt_int_op(4,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR
));
426 tt_int_op(4,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR_V3
));
428 /* Now remove 5 tasks, ensuring order and queue sizes */
429 tt_ptr_op(circ_ntor
, OP_EQ
, onion_next_task(&onionskin
));
430 tt_int_op(1,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP
));
431 tt_int_op(3,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR
));
432 tt_int_op(3,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR_V3
));
433 tt_ptr_op(onionskin
, OP_EQ
, create_ntor1
);
435 tt_ptr_op(circ_ntor3
, OP_EQ
, onion_next_task(&onionskin
));
436 tt_int_op(1,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP
));
437 tt_int_op(2,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR
));
438 tt_int_op(2,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR_V3
));
439 tt_ptr_op(onionskin
, OP_EQ
, create_v3ntor1
);
441 tt_ptr_op(circ_ntor
, OP_EQ
, onion_next_task(&onionskin
));
442 tt_int_op(1,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP
));
443 tt_int_op(1,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR
));
444 tt_int_op(1,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR_V3
));
445 tt_ptr_op(onionskin
, OP_EQ
, create_ntor2
);
447 tt_ptr_op(circ_ntor3
, OP_EQ
, onion_next_task(&onionskin
));
448 tt_int_op(1,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP
));
449 tt_int_op(0,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR
));
450 tt_int_op(0,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR_V3
));
451 tt_ptr_op(onionskin
, OP_EQ
, create_v3ntor2
);
453 tt_ptr_op(circ_tap
, OP_EQ
, onion_next_task(&onionskin
));
454 tt_int_op(0,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP
));
455 tt_int_op(0,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR
));
456 tt_int_op(0,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR_V3
));
457 tt_ptr_op(onionskin
, OP_EQ
, create_tap1
);
459 clear_pending_onions();
460 tt_int_op(0,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP
));
461 tt_int_op(0,OP_EQ
, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR
));
464 circuit_free_(TO_CIRCUIT(circ_tap
));
465 circuit_free_(TO_CIRCUIT(circ_ntor
));
466 circuit_free_(TO_CIRCUIT(circ_ntor3
));
467 tor_free(create_tap1
);
468 tor_free(create_ntor1
);
469 tor_free(create_ntor2
);
470 tor_free(create_v3ntor1
);
471 tor_free(create_v3ntor2
);
474 static int32_t cbtnummodes
= 10;
477 mock_xm_networkstatus_get_param(
478 const networkstatus_t
*ns
, const char *param_name
, int32_t default_val
,
479 int32_t min_val
, int32_t max_val
)
485 // only support cbtnummodes right now
486 tor_assert(strcmp(param_name
, "cbtnummodes")==0);
491 test_circuit_timeout_xm_alpha(void *arg
)
493 circuit_build_times_t cbt
;
496 circuit_build_times_init(&cbt
);
500 * 1. Create array of build times with 10 modes.
501 * 2. Make sure Xm calc is sane for 1,3,5,10,15,20 modes.
502 * 3. Make sure alpha calc is sane for 1,3,5,10,15,20 modes.
505 /* 110 build times, 9 modes, 8 mode ties, 10 abandoned */
506 build_time_t circuit_build_times
[] = {
507 100, 20, 1000, 500, 200, 5000, 30, 600, 200, 300, CBT_BUILD_ABANDONED
,
508 101, 21, 1001, 501, 201, 5001, 31, 601, 201, 301, CBT_BUILD_ABANDONED
,
509 102, 22, 1002, 502, 202, 5002, 32, 602, 202, 302, CBT_BUILD_ABANDONED
,
510 103, 23, 1003, 503, 203, 5003, 33, 603, 203, 303, CBT_BUILD_ABANDONED
,
511 104, 24, 1004, 504, 204, 5004, 34, 604, 204, 304, CBT_BUILD_ABANDONED
,
512 105, 25, 1005, 505, 205, 5005, 35, 605, 205, 305, CBT_BUILD_ABANDONED
,
513 106, 26, 1006, 506, 206, 5006, 36, 606, 206, 306, CBT_BUILD_ABANDONED
,
514 107, 27, 1007, 507, 207, 5007, 37, 607, 207, 307, CBT_BUILD_ABANDONED
,
515 108, 28, 1008, 508, 208, 5008, 38, 608, 208, 308, CBT_BUILD_ABANDONED
,
516 109, 29, 1009, 509, 209, 5009, 39, 609, 209, 309, CBT_BUILD_ABANDONED
519 memcpy(cbt
.circuit_build_times
, circuit_build_times
,
520 sizeof(circuit_build_times
));
521 cbt
.total_build_times
= 110;
523 MOCK(networkstatus_get_param
, mock_xm_networkstatus_get_param
);
525 #define CBT_ALPHA_PRECISION 0.00001
527 Xm
= circuit_build_times_get_xm(&cbt
);
528 alpha_ret
= circuit_build_times_update_alpha(&cbt
);
529 tt_int_op(alpha_ret
, OP_EQ
, 1);
530 tt_int_op(Xm
, OP_EQ
, 205);
531 tt_assert(fabs(cbt
.alpha
- 1.394401) < CBT_ALPHA_PRECISION
);
534 Xm
= circuit_build_times_get_xm(&cbt
);
535 alpha_ret
= circuit_build_times_update_alpha(&cbt
);
536 tt_int_op(alpha_ret
, OP_EQ
, 1);
537 tt_int_op(Xm
, OP_EQ
, 117);
538 tt_assert(fabs(cbt
.alpha
- 0.902313) < CBT_ALPHA_PRECISION
);
541 Xm
= circuit_build_times_get_xm(&cbt
);
542 alpha_ret
= circuit_build_times_update_alpha(&cbt
);
543 tt_int_op(alpha_ret
, OP_EQ
, 1);
544 tt_int_op(Xm
, OP_EQ
, 146);
545 tt_assert(fabs(cbt
.alpha
- 1.049032) < CBT_ALPHA_PRECISION
);
548 Xm
= circuit_build_times_get_xm(&cbt
);
549 alpha_ret
= circuit_build_times_update_alpha(&cbt
);
550 tt_int_op(alpha_ret
, OP_EQ
, 1);
551 tt_int_op(Xm
, OP_EQ
, 800);
552 tt_assert(fabs(cbt
.alpha
- 4.851754) < CBT_ALPHA_PRECISION
);
555 Xm
= circuit_build_times_get_xm(&cbt
);
556 alpha_ret
= circuit_build_times_update_alpha(&cbt
);
557 tt_int_op(alpha_ret
, OP_EQ
, 1);
558 tt_int_op(Xm
, OP_EQ
, 800);
559 tt_assert(fabs(cbt
.alpha
- 4.851754) < CBT_ALPHA_PRECISION
);
562 Xm
= circuit_build_times_get_xm(&cbt
);
563 alpha_ret
= circuit_build_times_update_alpha(&cbt
);
564 tt_int_op(alpha_ret
, OP_EQ
, 1);
565 tt_int_op(Xm
, OP_EQ
, 800);
566 tt_assert(fabs(cbt
.alpha
- 4.851754) < CBT_ALPHA_PRECISION
);
569 #undef CBT_ALPHA_PRECISION
570 UNMOCK(networkstatus_get_param
);
571 circuit_build_times_free_timeouts(&cbt
);
575 test_circuit_timeout(void *arg
)
578 * 1. Generate 1000 samples
579 * 2. Estimate parameters
580 * 3. If difference, repeat
583 * 6. Estimate parameters
584 * 7. compare differences
586 circuit_build_times_t initial
;
587 circuit_build_times_t estimate
;
588 circuit_build_times_t final
;
589 double timeout1
, timeout2
;
590 or_state_t
*state
=NULL
;
594 initialize_periodic_events();
596 circuit_build_times_init(&initial
);
597 circuit_build_times_init(&estimate
);
598 circuit_build_times_init(&final
);
600 state
= or_state_new();
602 // Use a deterministic RNG here, or else we'll get nondeterministic
603 // coverage in some of the circuitstats functions.
604 testing_enable_deterministic_rng();
606 circuitbuild_running_unit_tests();
607 #define timeout0 (build_time_t)(30*1000.0)
609 circuit_build_times_initial_alpha(&initial
,
610 CBT_DEFAULT_QUANTILE_CUTOFF
/100.0,
613 for (i
=0; i
< CBT_DEFAULT_MIN_CIRCUITS_TO_OBSERVE
; i
++) {
614 build_time_t sample
= circuit_build_times_generate_sample(&initial
,0,1);
616 circuit_build_times_add_time(&estimate
, sample
);
618 circuit_build_times_update_alpha(&estimate
);
619 timeout1
= circuit_build_times_calculate_timeout(&estimate
,
620 CBT_DEFAULT_QUANTILE_CUTOFF
/100.0);
621 circuit_build_times_set_timeout(&estimate
);
622 log_notice(LD_CIRC
, "Timeout1 is %f, Xm is %d", timeout1
, estimate
.Xm
);
624 } while (fabs(circuit_build_times_cdf(&initial
, timeout0
) -
625 circuit_build_times_cdf(&initial
, timeout1
)) > 0.02);
627 tt_int_op(estimate
.total_build_times
, OP_LE
, CBT_NCIRCUITS_TO_OBSERVE
);
629 circuit_build_times_update_state(&estimate
, state
);
630 circuit_build_times_free_timeouts(&final
);
631 tt_int_op(circuit_build_times_parse_state(&final
, state
), OP_EQ
, 0);
633 circuit_build_times_update_alpha(&final
);
634 timeout2
= circuit_build_times_calculate_timeout(&final
,
635 CBT_DEFAULT_QUANTILE_CUTOFF
/100.0);
637 circuit_build_times_set_timeout(&final
);
638 log_notice(LD_CIRC
, "Timeout2 is %f, Xm is %d", timeout2
, final
.Xm
);
640 /* 5% here because some accuracy is lost due to histogram conversion */
641 tt_assert(fabs(circuit_build_times_cdf(&initial
, timeout0
) -
642 circuit_build_times_cdf(&initial
, timeout2
)) < 0.05);
644 for (runs
= 0; runs
< 50; runs
++) {
645 int build_times_idx
= 0;
646 int total_build_times
= 0;
648 final
.close_ms
= final
.timeout_ms
= CBT_DEFAULT_TIMEOUT_INITIAL_VALUE
;
649 estimate
.close_ms
= estimate
.timeout_ms
650 = CBT_DEFAULT_TIMEOUT_INITIAL_VALUE
;
652 for (i
= 0; i
< CBT_DEFAULT_RECENT_CIRCUITS
*2; i
++) {
653 circuit_build_times_network_circ_success(&estimate
);
654 circuit_build_times_add_time(&estimate
,
655 circuit_build_times_generate_sample(&estimate
, 0,
656 CBT_DEFAULT_QUANTILE_CUTOFF
/100.0));
658 circuit_build_times_network_circ_success(&estimate
);
659 circuit_build_times_add_time(&final
,
660 circuit_build_times_generate_sample(&final
, 0,
661 CBT_DEFAULT_QUANTILE_CUTOFF
/100.0));
664 tt_assert(!circuit_build_times_network_check_changed(&estimate
));
665 tt_assert(!circuit_build_times_network_check_changed(&final
));
667 /* Reset liveness to be non-live */
668 final
.liveness
.network_last_live
= 0;
669 estimate
.liveness
.network_last_live
= 0;
671 build_times_idx
= estimate
.build_times_idx
;
672 total_build_times
= estimate
.total_build_times
;
674 tt_assert(circuit_build_times_network_check_live(&estimate
));
675 tt_assert(circuit_build_times_network_check_live(&final
));
677 circuit_build_times_count_close(&estimate
, 0,
678 (time_t)(approx_time()-estimate
.close_ms
/1000.0-1));
679 circuit_build_times_count_close(&final
, 0,
680 (time_t)(approx_time()-final
.close_ms
/1000.0-1));
682 tt_assert(!circuit_build_times_network_check_live(&estimate
));
683 tt_assert(!circuit_build_times_network_check_live(&final
));
685 log_info(LD_CIRC
, "idx: %d %d, tot: %d %d",
686 build_times_idx
, estimate
.build_times_idx
,
687 total_build_times
, estimate
.total_build_times
);
689 /* Check rollback index. Should match top of loop. */
690 tt_assert(build_times_idx
== estimate
.build_times_idx
);
691 // This can fail if estimate.total_build_times == 1000, because
692 // in that case, rewind actually causes us to lose timeouts
693 if (total_build_times
!= CBT_NCIRCUITS_TO_OBSERVE
)
694 tt_assert(total_build_times
== estimate
.total_build_times
);
696 /* Now simulate that the network has become live and we need
698 circuit_build_times_network_is_live(&estimate
);
699 circuit_build_times_network_is_live(&final
);
701 for (i
= 0; i
< CBT_DEFAULT_MAX_RECENT_TIMEOUT_COUNT
; i
++) {
702 circuit_build_times_count_timeout(&estimate
, 1);
704 if (i
< CBT_DEFAULT_MAX_RECENT_TIMEOUT_COUNT
-1) {
705 circuit_build_times_count_timeout(&final
, 1);
709 tt_int_op(estimate
.liveness
.after_firsthop_idx
, OP_EQ
, 0);
710 tt_assert(final
.liveness
.after_firsthop_idx
==
711 CBT_DEFAULT_MAX_RECENT_TIMEOUT_COUNT
-1);
713 tt_assert(circuit_build_times_network_check_live(&estimate
));
714 tt_assert(circuit_build_times_network_check_live(&final
));
716 circuit_build_times_count_timeout(&final
, 1);
718 /* Ensure return value for degenerate cases are clamped correctly */
719 initial
.alpha
= INT32_MAX
;
720 tt_assert(circuit_build_times_calculate_timeout(&initial
, .99999999) <=
723 tt_assert(circuit_build_times_calculate_timeout(&initial
, .5) <=
728 circuit_build_times_free_timeouts(&initial
);
729 circuit_build_times_free_timeouts(&estimate
);
730 circuit_build_times_free_timeouts(&final
);
731 or_state_free(state
);
732 teardown_periodic_events();
734 testing_disable_deterministic_rng();
738 { #name, test_ ## name , 0, NULL, NULL }
740 { #name, test_ ## name , TT_FORK, NULL, NULL }
742 static struct testcase_t test_array
[] = {
743 ENT(onion_handshake
),
744 { "bad_onion_handshake", test_bad_onion_handshake
, 0, NULL
, NULL
},
746 ENT(onion_queue_order
),
747 { "ntor_handshake", test_ntor_handshake
, 0, NULL
, NULL
},
748 { "fast_handshake", test_fast_handshake
, 0, NULL
, NULL
},
749 FORK(circuit_timeout
),
750 FORK(circuit_timeout_xm_alpha
),
755 struct testgroup_t testgroups
[] = {
757 { "accounting/", accounting_tests
},
758 { "addr/", addr_tests
},
759 { "address/", address_tests
},
760 { "address_set/", address_set_tests
},
761 { "bridges/", bridges_tests
},
762 { "buffer/", buffer_tests
},
763 { "bwmgt/", bwmgt_tests
},
764 { "cellfmt/", cell_format_tests
},
765 { "cellqueue/", cell_queue_tests
},
766 { "channel/", channel_tests
},
767 { "channelpadding/", channelpadding_tests
},
768 { "channeltls/", channeltls_tests
},
769 { "checkdir/", checkdir_tests
},
770 { "circuitbuild/", circuitbuild_tests
},
771 { "circuitpadding/", circuitpadding_tests
},
772 { "circuitlist/", circuitlist_tests
},
773 { "circuitmux/", circuitmux_tests
},
774 { "circuitmux_ewma/", circuitmux_ewma_tests
},
775 { "circuitstats/", circuitstats_tests
},
776 { "circuituse/", circuituse_tests
},
777 { "compat/libevent/", compat_libevent_tests
},
778 { "config/", config_tests
},
779 { "config/mgr/", confmgr_tests
},
780 { "config/parse/", confparse_tests
},
781 { "connection/", connection_tests
},
782 { "conscache/", conscache_tests
},
783 { "consdiff/", consdiff_tests
},
784 { "consdiffmgr/", consdiffmgr_tests
},
785 { "container/", container_tests
},
786 { "container/namemap/", namemap_tests
},
787 { "control/", controller_tests
},
788 { "control/btrack/", btrack_tests
},
789 { "control/event/", controller_event_tests
},
790 { "crypto/", crypto_tests
},
791 { "crypto/ope/", crypto_ope_tests
},
792 #ifdef ENABLE_OPENSSL
793 { "crypto/openssl/", crypto_openssl_tests
},
795 { "crypto/pem/", pem_tests
},
796 { "crypto/rng/", crypto_rng_tests
},
797 { "dir/", dir_tests
},
798 { "dir/auth/ports/", dirauth_port_tests
},
799 { "dir/auth/process_descs/", process_descs_tests
},
800 { "dir/md/", microdesc_tests
},
801 { "dirauth/dirvote/", dirvote_tests
},
802 { "dir/voting/flags/", voting_flags_tests
},
803 { "dir/voting/schedule/", voting_schedule_tests
},
804 { "dir_handle_get/", dir_handle_get_tests
},
805 { "dispatch/", dispatch_tests
, },
806 { "dns/", dns_tests
},
807 { "dos/", dos_tests
},
808 { "entryconn/", entryconn_tests
},
809 { "entrynodes/", entrynodes_tests
},
810 { "extorport/", extorport_tests
},
811 { "geoip/", geoip_tests
},
812 { "guardfraction/", guardfraction_tests
},
813 { "hs_cache/", hs_cache
},
814 { "hs_cell/", hs_cell_tests
},
815 { "hs_client/", hs_client_tests
},
816 { "hs_common/", hs_common_tests
},
817 { "hs_config/", hs_config_tests
},
818 { "hs_control/", hs_control_tests
},
819 { "hs_descriptor/", hs_descriptor
},
820 { "hs_dos/", hs_dos_tests
},
821 { "hs_intropoint/", hs_intropoint_tests
},
822 { "hs_metrics/", hs_metrics_tests
},
823 { "hs_ntor/", hs_ntor_tests
},
824 { "hs_ob/", hs_ob_tests
},
825 { "hs_service/", hs_service_tests
},
826 { "keypin/", keypin_tests
},
827 { "link-handshake/", link_handshake_tests
},
828 { "mainloop/", mainloop_tests
},
829 { "metrics/", metrics_tests
},
830 { "netinfo/", netinfo_tests
},
831 { "nodelist/", nodelist_tests
},
832 { "oom/", oom_tests
},
833 { "onion-handshake/ntor-v3/", ntor_v3_tests
},
834 { "oos/", oos_tests
},
835 { "options/", options_tests
},
836 { "options/act/", options_act_tests
},
837 { "parsecommon/", parsecommon_tests
},
838 { "periodic-event/" , periodic_event_tests
},
839 { "policy/" , policy_tests
},
840 { "prob_distr/", prob_distr_tests
},
841 { "procmon/", procmon_tests
},
842 { "process/", process_tests
},
843 { "proto/haproxy/", proto_haproxy_tests
},
844 { "proto/http/", proto_http_tests
},
845 { "proto/misc/", proto_misc_tests
},
846 { "protover/", protover_tests
},
848 { "pubsub/build/", pubsub_build_tests
},
849 { "pubsub/msg/", pubsub_msg_tests
},
850 { "relay/" , relay_tests
},
851 { "relaycell/", relaycell_tests
},
852 { "relaycrypt/", relaycrypt_tests
},
853 { "replaycache/", replaycache_tests
},
854 { "router/", router_tests
},
855 { "routerkeys/", routerkeys_tests
},
856 { "routerlist/", routerlist_tests
},
857 { "routerset/" , routerset_tests
},
858 #ifdef USE_LIBSECCOMP
859 { "sandbox/" , sandbox_tests
},
861 { "scheduler/", scheduler_tests
},
862 { "sendme/", sendme_tests
},
863 { "shared-random/", sr_tests
},
864 { "socks/", socks_tests
},
865 { "statefile/", statefile_tests
},
866 { "stats/", stats_tests
},
867 { "status/" , status_tests
},
868 { "storagedir/", storagedir_tests
},
869 { "token_bucket/", token_bucket_tests
},
870 { "tortls/", tortls_tests
},
872 { "tortls/openssl/", tortls_openssl_tests
},
874 { "tortls/x509/", x509_tests
},
875 { "util/", util_tests
},
876 { "util/format/", util_format_tests
},
877 { "util/handle/", handle_tests
},
878 { "util/logging/", logging_tests
},
879 { "util/process/", util_process_tests
},
880 { "util/thread/", thread_tests
},