Line data Source code
1 : /* Copyright (c) 2001-2004, Roger Dingledine.
2 : * Copyright (c) 2007-2021, The Tor Project, Inc. */
3 : /* See LICENSE for licensing information */
4 :
5 : /**
6 : * \file test.c
7 : * \brief Unit tests for many pieces of the lower level Tor modules.
8 : **/
9 :
10 : #include "orconfig.h"
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"
15 :
16 : #include <stdio.h>
17 : #ifdef HAVE_FCNTL_H
18 : #include <fcntl.h>
19 : #endif
20 :
21 : #ifdef _WIN32
22 : /* For mkdir() */
23 : #include <direct.h>
24 : #else
25 : #include <dirent.h>
26 : #endif /* defined(_WIN32) */
27 :
28 : #include <math.h>
29 :
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
37 :
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 "app/config/statefile.h"
56 : #include "lib/crypt_ops/crypto_curve25519.h"
57 : #include "feature/nodelist/networkstatus.h"
58 :
59 : #include "core/or/extend_info_st.h"
60 : #include "core/or/or_circuit_st.h"
61 : #include "feature/relay/onion_queue.h"
62 :
63 : /** Run unit tests for the onion handshake code. */
64 : static void
65 1 : test_onion_handshake(void *arg)
66 : {
67 : /* client-side */
68 1 : crypto_dh_t *c_dh = NULL;
69 1 : char c_buf[TAP_ONIONSKIN_CHALLENGE_LEN];
70 1 : char c_keys[40];
71 : /* server-side */
72 1 : char s_buf[TAP_ONIONSKIN_REPLY_LEN];
73 1 : char s_keys[40];
74 1 : int i;
75 : /* shared */
76 1 : crypto_pk_t *pk = NULL, *pk2 = NULL;
77 :
78 1 : (void)arg;
79 1 : pk = pk_generate(0);
80 1 : pk2 = pk_generate(1);
81 :
82 : /* client handshake 1. */
83 1 : memset(c_buf, 0, TAP_ONIONSKIN_CHALLENGE_LEN);
84 1 : tt_assert(! onion_skin_TAP_create(pk, &c_dh, c_buf));
85 :
86 4 : for (i = 1; i <= 3; ++i) {
87 3 : crypto_pk_t *k1, *k2;
88 3 : if (i==1) {
89 : /* server handshake: only one key known. */
90 : k1 = pk; k2 = NULL;
91 2 : } else if (i==2) {
92 : /* server handshake: try the right key first. */
93 : k1 = pk; k2 = pk2;
94 : } else {
95 : /* server handshake: try the right key second. */
96 1 : k1 = pk2; k2 = pk;
97 : }
98 :
99 3 : memset(s_buf, 0, TAP_ONIONSKIN_REPLY_LEN);
100 3 : memset(s_keys, 0, 40);
101 3 : tt_assert(! onion_skin_TAP_server_handshake(c_buf, k1, k2,
102 : s_buf, s_keys, 40));
103 :
104 : /* client handshake 2 */
105 3 : memset(c_keys, 0, 40);
106 3 : tt_assert(! onion_skin_TAP_client_handshake(c_dh, s_buf, c_keys,
107 : 40, NULL));
108 :
109 3 : tt_mem_op(c_keys,OP_EQ, s_keys, 40);
110 3 : memset(s_buf, 0, 40);
111 3 : tt_mem_op(c_keys,OP_NE, s_buf, 40);
112 : }
113 1 : done:
114 1 : crypto_dh_free(c_dh);
115 1 : crypto_pk_free(pk);
116 1 : crypto_pk_free(pk2);
117 1 : }
118 :
119 : static void
120 1 : test_bad_onion_handshake(void *arg)
121 : {
122 1 : char junk_buf[TAP_ONIONSKIN_CHALLENGE_LEN];
123 1 : char junk_buf2[TAP_ONIONSKIN_CHALLENGE_LEN];
124 : /* client-side */
125 1 : crypto_dh_t *c_dh = NULL;
126 1 : char c_buf[TAP_ONIONSKIN_CHALLENGE_LEN];
127 1 : char c_keys[40];
128 : /* server-side */
129 1 : char s_buf[TAP_ONIONSKIN_REPLY_LEN];
130 1 : char s_keys[40];
131 : /* shared */
132 1 : crypto_pk_t *pk = NULL, *pk2 = NULL;
133 :
134 1 : (void)arg;
135 :
136 1 : pk = pk_generate(0);
137 1 : pk2 = pk_generate(1);
138 :
139 : /* Server: Case 1: the encrypted data is degenerate. */
140 1 : memset(junk_buf, 0, sizeof(junk_buf));
141 1 : crypto_pk_obsolete_public_hybrid_encrypt(pk,
142 : junk_buf2, TAP_ONIONSKIN_CHALLENGE_LEN,
143 : junk_buf, DH1024_KEY_LEN,
144 : PK_PKCS1_OAEP_PADDING, 1);
145 1 : tt_int_op(-1, OP_EQ,
146 : onion_skin_TAP_server_handshake(junk_buf2, pk, NULL,
147 : s_buf, s_keys, 40));
148 :
149 : /* Server: Case 2: the encrypted data is not long enough. */
150 1 : memset(junk_buf, 0, sizeof(junk_buf));
151 1 : memset(junk_buf2, 0, sizeof(junk_buf2));
152 1 : crypto_pk_public_encrypt(pk, junk_buf2, sizeof(junk_buf2),
153 : junk_buf, 48, PK_PKCS1_OAEP_PADDING);
154 1 : tt_int_op(-1, OP_EQ,
155 : onion_skin_TAP_server_handshake(junk_buf2, pk, NULL,
156 : s_buf, s_keys, 40));
157 :
158 : /* client handshake 1: do it straight. */
159 1 : memset(c_buf, 0, TAP_ONIONSKIN_CHALLENGE_LEN);
160 1 : tt_assert(! onion_skin_TAP_create(pk, &c_dh, c_buf));
161 :
162 : /* Server: Case 3: we just don't have the right key. */
163 1 : tt_int_op(-1, OP_EQ,
164 : onion_skin_TAP_server_handshake(c_buf, pk2, NULL,
165 : s_buf, s_keys, 40));
166 :
167 : /* Server: Case 4: The RSA-encrypted portion is corrupt. */
168 1 : c_buf[64] ^= 33;
169 1 : tt_int_op(-1, OP_EQ,
170 : onion_skin_TAP_server_handshake(c_buf, pk, NULL,
171 : s_buf, s_keys, 40));
172 1 : c_buf[64] ^= 33;
173 :
174 : /* (Let the server proceed) */
175 1 : tt_int_op(0, OP_EQ,
176 : onion_skin_TAP_server_handshake(c_buf, pk, NULL,
177 : s_buf, s_keys, 40));
178 :
179 : /* Client: Case 1: The server sent back junk. */
180 1 : const char *msg = NULL;
181 1 : s_buf[64] ^= 33;
182 1 : tt_int_op(-1, OP_EQ,
183 : onion_skin_TAP_client_handshake(c_dh, s_buf, c_keys, 40, &msg));
184 1 : s_buf[64] ^= 33;
185 1 : tt_str_op(msg, OP_EQ, "Digest DOES NOT MATCH on onion handshake. "
186 : "Bug or attack.");
187 :
188 : /* Let the client finish; make sure it can. */
189 1 : msg = NULL;
190 1 : tt_int_op(0, OP_EQ,
191 : onion_skin_TAP_client_handshake(c_dh, s_buf, c_keys, 40, &msg));
192 1 : tt_mem_op(s_keys,OP_EQ, c_keys, 40);
193 1 : tt_ptr_op(msg, OP_EQ, NULL);
194 :
195 : /* Client: Case 2: The server sent back a degenerate DH. */
196 1 : memset(s_buf, 0, sizeof(s_buf));
197 1 : tt_int_op(-1, OP_EQ,
198 : onion_skin_TAP_client_handshake(c_dh, s_buf, c_keys, 40, &msg));
199 1 : tt_str_op(msg, OP_EQ, "DH computation failed.");
200 :
201 1 : done:
202 1 : crypto_dh_free(c_dh);
203 1 : crypto_pk_free(pk);
204 1 : crypto_pk_free(pk2);
205 1 : }
206 :
207 : static void
208 1 : test_ntor_handshake(void *arg)
209 : {
210 : /* client-side */
211 1 : ntor_handshake_state_t *c_state = NULL;
212 1 : uint8_t c_buf[NTOR_ONIONSKIN_LEN];
213 1 : uint8_t c_keys[400];
214 :
215 : /* server-side */
216 1 : di_digest256_map_t *s_keymap=NULL;
217 1 : curve25519_keypair_t s_keypair;
218 1 : uint8_t s_buf[NTOR_REPLY_LEN];
219 1 : uint8_t s_keys[400];
220 :
221 : /* shared */
222 1 : const curve25519_public_key_t *server_pubkey;
223 1 : uint8_t node_id[20] = "abcdefghijklmnopqrst";
224 :
225 1 : (void) arg;
226 :
227 : /* Make the server some keys */
228 1 : curve25519_secret_key_generate(&s_keypair.seckey, 0);
229 1 : curve25519_public_key_generate(&s_keypair.pubkey, &s_keypair.seckey);
230 1 : dimap_add_entry(&s_keymap, s_keypair.pubkey.public_key, &s_keypair);
231 1 : server_pubkey = &s_keypair.pubkey;
232 :
233 : /* client handshake 1. */
234 1 : memset(c_buf, 0, NTOR_ONIONSKIN_LEN);
235 1 : tt_int_op(0, OP_EQ, onion_skin_ntor_create(node_id, server_pubkey,
236 : &c_state, c_buf));
237 :
238 : /* server handshake */
239 1 : memset(s_buf, 0, NTOR_REPLY_LEN);
240 1 : memset(s_keys, 0, 40);
241 1 : tt_int_op(0, OP_EQ, onion_skin_ntor_server_handshake(c_buf, s_keymap, NULL,
242 : node_id,
243 : s_buf, s_keys, 400));
244 :
245 : /* client handshake 2 */
246 1 : memset(c_keys, 0, 40);
247 1 : tt_int_op(0, OP_EQ, onion_skin_ntor_client_handshake(c_state, s_buf,
248 : c_keys, 400, NULL));
249 :
250 1 : tt_mem_op(c_keys,OP_EQ, s_keys, 400);
251 1 : memset(s_buf, 0, 40);
252 1 : tt_mem_op(c_keys,OP_NE, s_buf, 40);
253 :
254 : /* Now try with a bogus server response. Zero input should trigger
255 : * All The Problems. */
256 1 : memset(c_keys, 0, 400);
257 1 : memset(s_buf, 0, NTOR_REPLY_LEN);
258 1 : const char *msg = NULL;
259 1 : tt_int_op(-1, OP_EQ, onion_skin_ntor_client_handshake(c_state, s_buf,
260 : c_keys, 400, &msg));
261 1 : tt_str_op(msg, OP_EQ, "Zero output from curve25519 handshake");
262 :
263 1 : done:
264 1 : ntor_handshake_state_free(c_state);
265 1 : dimap_free(s_keymap, NULL);
266 1 : }
267 :
268 : static void
269 1 : test_fast_handshake(void *arg)
270 : {
271 : /* tests for the obsolete "CREATE_FAST" handshake. */
272 1 : (void) arg;
273 1 : fast_handshake_state_t *state = NULL;
274 1 : uint8_t client_handshake[CREATE_FAST_LEN];
275 1 : uint8_t server_handshake[CREATED_FAST_LEN];
276 1 : uint8_t s_keys[100], c_keys[100];
277 :
278 : /* First, test an entire handshake. */
279 1 : memset(client_handshake, 0, sizeof(client_handshake));
280 1 : tt_int_op(0, OP_EQ, fast_onionskin_create(&state, client_handshake));
281 1 : tt_assert(! fast_mem_is_zero((char*)client_handshake,
282 : sizeof(client_handshake)));
283 :
284 1 : tt_int_op(0, OP_EQ,
285 : fast_server_handshake(client_handshake, server_handshake,
286 : s_keys, 100));
287 1 : const char *msg = NULL;
288 1 : tt_int_op(0, OP_EQ,
289 : fast_client_handshake(state, server_handshake, c_keys, 100, &msg));
290 1 : tt_ptr_op(msg, OP_EQ, NULL);
291 1 : tt_mem_op(s_keys, OP_EQ, c_keys, 100);
292 :
293 : /* Now test a failing handshake. */
294 1 : server_handshake[0] ^= 3;
295 1 : tt_int_op(-1, OP_EQ,
296 : fast_client_handshake(state, server_handshake, c_keys, 100, &msg));
297 1 : tt_str_op(msg, OP_EQ, "Digest DOES NOT MATCH on fast handshake. "
298 : "Bug or attack.");
299 :
300 1 : done:
301 1 : fast_handshake_state_free(state);
302 1 : }
303 :
304 : /** Run unit tests for the onion queues. */
305 : static void
306 1 : test_onion_queues(void *arg)
307 : {
308 1 : uint8_t buf1[TAP_ONIONSKIN_CHALLENGE_LEN] = {0};
309 1 : uint8_t buf2[NTOR_ONIONSKIN_LEN] = {0};
310 :
311 1 : or_circuit_t *circ1 = or_circuit_new(0, NULL);
312 1 : or_circuit_t *circ2 = or_circuit_new(0, NULL);
313 :
314 1 : create_cell_t *onionskin = NULL, *create2_ptr;
315 1 : create_cell_t *create1 = tor_malloc_zero(sizeof(create_cell_t));
316 1 : create_cell_t *create2 = tor_malloc_zero(sizeof(create_cell_t));
317 1 : (void)arg;
318 1 : create2_ptr = create2; /* remember, but do not free */
319 :
320 1 : create_cell_init(create1, CELL_CREATE, ONION_HANDSHAKE_TYPE_TAP,
321 : TAP_ONIONSKIN_CHALLENGE_LEN, buf1);
322 1 : create_cell_init(create2, CELL_CREATE, ONION_HANDSHAKE_TYPE_NTOR,
323 : NTOR_ONIONSKIN_LEN, buf2);
324 :
325 1 : tt_int_op(0,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP));
326 1 : tt_int_op(0,OP_EQ, onion_pending_add(circ1, create1));
327 1 : create1 = NULL;
328 1 : tt_int_op(1,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP));
329 :
330 1 : tt_int_op(0,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR));
331 1 : tt_int_op(0,OP_EQ, onion_pending_add(circ2, create2));
332 1 : create2 = NULL;
333 1 : tt_int_op(1,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR));
334 :
335 1 : tt_ptr_op(circ2,OP_EQ, onion_next_task(&onionskin));
336 1 : tt_int_op(1,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP));
337 1 : tt_int_op(0,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR));
338 1 : tt_ptr_op(onionskin, OP_EQ, create2_ptr);
339 :
340 1 : clear_pending_onions();
341 1 : tt_int_op(0,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_TAP));
342 1 : tt_int_op(0,OP_EQ, onion_num_pending(ONION_HANDSHAKE_TYPE_NTOR));
343 :
344 1 : done:
345 1 : circuit_free_(TO_CIRCUIT(circ1));
346 1 : circuit_free_(TO_CIRCUIT(circ2));
347 1 : tor_free(create1);
348 1 : tor_free(create2);
349 1 : tor_free(onionskin);
350 1 : }
351 :
352 : static int32_t cbtnummodes = 10;
353 :
354 : static int32_t
355 12 : mock_xm_networkstatus_get_param(
356 : const networkstatus_t *ns, const char *param_name, int32_t default_val,
357 : int32_t min_val, int32_t max_val)
358 : {
359 12 : (void)ns;
360 12 : (void)default_val;
361 12 : (void)min_val;
362 12 : (void)max_val;
363 : // only support cbtnummodes right now
364 12 : tor_assert(strcmp(param_name, "cbtnummodes")==0);
365 12 : return cbtnummodes;
366 : }
367 :
368 : static void
369 1 : test_circuit_timeout_xm_alpha(void *arg)
370 : {
371 1 : circuit_build_times_t cbt;
372 1 : build_time_t Xm;
373 1 : int alpha_ret;
374 1 : circuit_build_times_init(&cbt);
375 1 : (void)arg;
376 :
377 : /* Plan:
378 : * 1. Create array of build times with 10 modes.
379 : * 2. Make sure Xm calc is sane for 1,3,5,10,15,20 modes.
380 : * 3. Make sure alpha calc is sane for 1,3,5,10,15,20 modes.
381 : */
382 :
383 : /* 110 build times, 9 modes, 8 mode ties, 10 abandoned */
384 1 : build_time_t circuit_build_times[] = {
385 : 100, 20, 1000, 500, 200, 5000, 30, 600, 200, 300, CBT_BUILD_ABANDONED,
386 : 101, 21, 1001, 501, 201, 5001, 31, 601, 201, 301, CBT_BUILD_ABANDONED,
387 : 102, 22, 1002, 502, 202, 5002, 32, 602, 202, 302, CBT_BUILD_ABANDONED,
388 : 103, 23, 1003, 503, 203, 5003, 33, 603, 203, 303, CBT_BUILD_ABANDONED,
389 : 104, 24, 1004, 504, 204, 5004, 34, 604, 204, 304, CBT_BUILD_ABANDONED,
390 : 105, 25, 1005, 505, 205, 5005, 35, 605, 205, 305, CBT_BUILD_ABANDONED,
391 : 106, 26, 1006, 506, 206, 5006, 36, 606, 206, 306, CBT_BUILD_ABANDONED,
392 : 107, 27, 1007, 507, 207, 5007, 37, 607, 207, 307, CBT_BUILD_ABANDONED,
393 : 108, 28, 1008, 508, 208, 5008, 38, 608, 208, 308, CBT_BUILD_ABANDONED,
394 : 109, 29, 1009, 509, 209, 5009, 39, 609, 209, 309, CBT_BUILD_ABANDONED
395 : };
396 :
397 1 : memcpy(cbt.circuit_build_times, circuit_build_times,
398 : sizeof(circuit_build_times));
399 1 : cbt.total_build_times = 110;
400 :
401 1 : MOCK(networkstatus_get_param, mock_xm_networkstatus_get_param);
402 :
403 : #define CBT_ALPHA_PRECISION 0.00001
404 1 : cbtnummodes = 1;
405 1 : Xm = circuit_build_times_get_xm(&cbt);
406 1 : alpha_ret = circuit_build_times_update_alpha(&cbt);
407 1 : tt_int_op(alpha_ret, OP_EQ, 1);
408 1 : tt_int_op(Xm, OP_EQ, 205);
409 1 : tt_assert(fabs(cbt.alpha - 1.394401) < CBT_ALPHA_PRECISION);
410 :
411 1 : cbtnummodes = 3;
412 1 : Xm = circuit_build_times_get_xm(&cbt);
413 1 : alpha_ret = circuit_build_times_update_alpha(&cbt);
414 1 : tt_int_op(alpha_ret, OP_EQ, 1);
415 1 : tt_int_op(Xm, OP_EQ, 117);
416 1 : tt_assert(fabs(cbt.alpha - 0.902313) < CBT_ALPHA_PRECISION);
417 :
418 1 : cbtnummodes = 5;
419 1 : Xm = circuit_build_times_get_xm(&cbt);
420 1 : alpha_ret = circuit_build_times_update_alpha(&cbt);
421 1 : tt_int_op(alpha_ret, OP_EQ, 1);
422 1 : tt_int_op(Xm, OP_EQ, 146);
423 1 : tt_assert(fabs(cbt.alpha - 1.049032) < CBT_ALPHA_PRECISION);
424 :
425 1 : cbtnummodes = 10;
426 1 : Xm = circuit_build_times_get_xm(&cbt);
427 1 : alpha_ret = circuit_build_times_update_alpha(&cbt);
428 1 : tt_int_op(alpha_ret, OP_EQ, 1);
429 1 : tt_int_op(Xm, OP_EQ, 800);
430 1 : tt_assert(fabs(cbt.alpha - 4.851754) < CBT_ALPHA_PRECISION);
431 :
432 1 : cbtnummodes = 15;
433 1 : Xm = circuit_build_times_get_xm(&cbt);
434 1 : alpha_ret = circuit_build_times_update_alpha(&cbt);
435 1 : tt_int_op(alpha_ret, OP_EQ, 1);
436 1 : tt_int_op(Xm, OP_EQ, 800);
437 1 : tt_assert(fabs(cbt.alpha - 4.851754) < CBT_ALPHA_PRECISION);
438 :
439 1 : cbtnummodes = 20;
440 1 : Xm = circuit_build_times_get_xm(&cbt);
441 1 : alpha_ret = circuit_build_times_update_alpha(&cbt);
442 1 : tt_int_op(alpha_ret, OP_EQ, 1);
443 1 : tt_int_op(Xm, OP_EQ, 800);
444 1 : tt_assert(fabs(cbt.alpha - 4.851754) < CBT_ALPHA_PRECISION);
445 :
446 1 : done:
447 : #undef CBT_ALPHA_PRECISION
448 1 : UNMOCK(networkstatus_get_param);
449 1 : circuit_build_times_free_timeouts(&cbt);
450 1 : }
451 :
452 : static void
453 1 : test_circuit_timeout(void *arg)
454 : {
455 : /* Plan:
456 : * 1. Generate 1000 samples
457 : * 2. Estimate parameters
458 : * 3. If difference, repeat
459 : * 4. Save state
460 : * 5. load state
461 : * 6. Estimate parameters
462 : * 7. compare differences
463 : */
464 1 : circuit_build_times_t initial;
465 1 : circuit_build_times_t estimate;
466 1 : circuit_build_times_t final;
467 1 : double timeout1, timeout2;
468 1 : or_state_t *state=NULL;
469 1 : int i, runs;
470 1 : (void)arg;
471 :
472 1 : initialize_periodic_events();
473 :
474 1 : circuit_build_times_init(&initial);
475 1 : circuit_build_times_init(&estimate);
476 1 : circuit_build_times_init(&final);
477 :
478 1 : state = or_state_new();
479 :
480 : // Use a deterministic RNG here, or else we'll get nondeterministic
481 : // coverage in some of the circuitstats functions.
482 1 : testing_enable_deterministic_rng();
483 :
484 1 : circuitbuild_running_unit_tests();
485 : #define timeout0 (build_time_t)(30*1000.0)
486 1 : initial.Xm = 3000;
487 1 : circuit_build_times_initial_alpha(&initial,
488 : CBT_DEFAULT_QUANTILE_CUTOFF/100.0,
489 : timeout0);
490 1 : do {
491 101 : for (i=0; i < CBT_DEFAULT_MIN_CIRCUITS_TO_OBSERVE; i++) {
492 100 : build_time_t sample = circuit_build_times_generate_sample(&initial,0,1);
493 :
494 100 : circuit_build_times_add_time(&estimate, sample);
495 : }
496 1 : circuit_build_times_update_alpha(&estimate);
497 1 : timeout1 = circuit_build_times_calculate_timeout(&estimate,
498 : CBT_DEFAULT_QUANTILE_CUTOFF/100.0);
499 1 : circuit_build_times_set_timeout(&estimate);
500 1 : log_notice(LD_CIRC, "Timeout1 is %f, Xm is %d", timeout1, estimate.Xm);
501 : /* 2% error */
502 2 : } while (fabs(circuit_build_times_cdf(&initial, timeout0) -
503 1 : circuit_build_times_cdf(&initial, timeout1)) > 0.02);
504 :
505 1 : tt_int_op(estimate.total_build_times, OP_LE, CBT_NCIRCUITS_TO_OBSERVE);
506 :
507 1 : circuit_build_times_update_state(&estimate, state);
508 1 : circuit_build_times_free_timeouts(&final);
509 1 : tt_int_op(circuit_build_times_parse_state(&final, state), OP_EQ, 0);
510 :
511 1 : circuit_build_times_update_alpha(&final);
512 1 : timeout2 = circuit_build_times_calculate_timeout(&final,
513 : CBT_DEFAULT_QUANTILE_CUTOFF/100.0);
514 :
515 1 : circuit_build_times_set_timeout(&final);
516 1 : log_notice(LD_CIRC, "Timeout2 is %f, Xm is %d", timeout2, final.Xm);
517 :
518 : /* 5% here because some accuracy is lost due to histogram conversion */
519 1 : tt_assert(fabs(circuit_build_times_cdf(&initial, timeout0) -
520 : circuit_build_times_cdf(&initial, timeout2)) < 0.05);
521 :
522 51 : for (runs = 0; runs < 50; runs++) {
523 50 : int build_times_idx = 0;
524 50 : int total_build_times = 0;
525 :
526 50 : final.close_ms = final.timeout_ms = CBT_DEFAULT_TIMEOUT_INITIAL_VALUE;
527 50 : estimate.close_ms = estimate.timeout_ms
528 50 : = CBT_DEFAULT_TIMEOUT_INITIAL_VALUE;
529 :
530 2050 : for (i = 0; i < CBT_DEFAULT_RECENT_CIRCUITS*2; i++) {
531 2000 : circuit_build_times_network_circ_success(&estimate);
532 2000 : circuit_build_times_add_time(&estimate,
533 : circuit_build_times_generate_sample(&estimate, 0,
534 : CBT_DEFAULT_QUANTILE_CUTOFF/100.0));
535 :
536 2000 : circuit_build_times_network_circ_success(&estimate);
537 2000 : circuit_build_times_add_time(&final,
538 : circuit_build_times_generate_sample(&final, 0,
539 : CBT_DEFAULT_QUANTILE_CUTOFF/100.0));
540 : }
541 :
542 50 : tt_assert(!circuit_build_times_network_check_changed(&estimate));
543 50 : tt_assert(!circuit_build_times_network_check_changed(&final));
544 :
545 : /* Reset liveness to be non-live */
546 50 : final.liveness.network_last_live = 0;
547 50 : estimate.liveness.network_last_live = 0;
548 :
549 50 : build_times_idx = estimate.build_times_idx;
550 50 : total_build_times = estimate.total_build_times;
551 :
552 50 : tt_assert(circuit_build_times_network_check_live(&estimate));
553 50 : tt_assert(circuit_build_times_network_check_live(&final));
554 :
555 100 : circuit_build_times_count_close(&estimate, 0,
556 50 : (time_t)(approx_time()-estimate.close_ms/1000.0-1));
557 100 : circuit_build_times_count_close(&final, 0,
558 50 : (time_t)(approx_time()-final.close_ms/1000.0-1));
559 :
560 50 : tt_assert(!circuit_build_times_network_check_live(&estimate));
561 50 : tt_assert(!circuit_build_times_network_check_live(&final));
562 :
563 50 : log_info(LD_CIRC, "idx: %d %d, tot: %d %d",
564 : build_times_idx, estimate.build_times_idx,
565 : total_build_times, estimate.total_build_times);
566 :
567 : /* Check rollback index. Should match top of loop. */
568 50 : tt_assert(build_times_idx == estimate.build_times_idx);
569 : // This can fail if estimate.total_build_times == 1000, because
570 : // in that case, rewind actually causes us to lose timeouts
571 50 : if (total_build_times != CBT_NCIRCUITS_TO_OBSERVE)
572 50 : tt_assert(total_build_times == estimate.total_build_times);
573 :
574 : /* Now simulate that the network has become live and we need
575 : * a change */
576 50 : circuit_build_times_network_is_live(&estimate);
577 50 : circuit_build_times_network_is_live(&final);
578 :
579 1000 : for (i = 0; i < CBT_DEFAULT_MAX_RECENT_TIMEOUT_COUNT; i++) {
580 900 : circuit_build_times_count_timeout(&estimate, 1);
581 :
582 900 : if (i < CBT_DEFAULT_MAX_RECENT_TIMEOUT_COUNT-1) {
583 850 : circuit_build_times_count_timeout(&final, 1);
584 : }
585 : }
586 :
587 50 : tt_int_op(estimate.liveness.after_firsthop_idx, OP_EQ, 0);
588 50 : tt_assert(final.liveness.after_firsthop_idx ==
589 : CBT_DEFAULT_MAX_RECENT_TIMEOUT_COUNT-1);
590 :
591 50 : tt_assert(circuit_build_times_network_check_live(&estimate));
592 50 : tt_assert(circuit_build_times_network_check_live(&final));
593 :
594 50 : circuit_build_times_count_timeout(&final, 1);
595 :
596 : /* Ensure return value for degenerate cases are clamped correctly */
597 50 : initial.alpha = INT32_MAX;
598 50 : tt_assert(circuit_build_times_calculate_timeout(&initial, .99999999) <=
599 : INT32_MAX);
600 50 : initial.alpha = 0;
601 50 : tt_assert(circuit_build_times_calculate_timeout(&initial, .5) <=
602 : INT32_MAX);
603 : }
604 :
605 1 : done:
606 1 : circuit_build_times_free_timeouts(&initial);
607 1 : circuit_build_times_free_timeouts(&estimate);
608 1 : circuit_build_times_free_timeouts(&final);
609 1 : or_state_free(state);
610 1 : teardown_periodic_events();
611 :
612 1 : testing_disable_deterministic_rng();
613 1 : }
614 :
615 : #define ENT(name) \
616 : { #name, test_ ## name , 0, NULL, NULL }
617 : #define FORK(name) \
618 : { #name, test_ ## name , TT_FORK, NULL, NULL }
619 :
620 : static struct testcase_t test_array[] = {
621 : ENT(onion_handshake),
622 : { "bad_onion_handshake", test_bad_onion_handshake, 0, NULL, NULL },
623 : ENT(onion_queues),
624 : { "ntor_handshake", test_ntor_handshake, 0, NULL, NULL },
625 : { "fast_handshake", test_fast_handshake, 0, NULL, NULL },
626 : FORK(circuit_timeout),
627 : FORK(circuit_timeout_xm_alpha),
628 :
629 : END_OF_TESTCASES
630 : };
631 :
632 : struct testgroup_t testgroups[] = {
633 : { "", test_array },
634 : { "accounting/", accounting_tests },
635 : { "addr/", addr_tests },
636 : { "address/", address_tests },
637 : { "address_set/", address_set_tests },
638 : { "bridges/", bridges_tests },
639 : { "buffer/", buffer_tests },
640 : { "bwmgt/", bwmgt_tests },
641 : { "cellfmt/", cell_format_tests },
642 : { "cellqueue/", cell_queue_tests },
643 : { "channel/", channel_tests },
644 : { "channelpadding/", channelpadding_tests },
645 : { "channeltls/", channeltls_tests },
646 : { "checkdir/", checkdir_tests },
647 : { "circuitbuild/", circuitbuild_tests },
648 : { "circuitpadding/", circuitpadding_tests },
649 : { "circuitlist/", circuitlist_tests },
650 : { "circuitmux/", circuitmux_tests },
651 : { "circuitmux_ewma/", circuitmux_ewma_tests },
652 : { "circuitstats/", circuitstats_tests },
653 : { "circuituse/", circuituse_tests },
654 : { "compat/libevent/", compat_libevent_tests },
655 : { "config/", config_tests },
656 : { "config/mgr/", confmgr_tests },
657 : { "config/parse/", confparse_tests },
658 : { "connection/", connection_tests },
659 : { "conscache/", conscache_tests },
660 : { "consdiff/", consdiff_tests },
661 : { "consdiffmgr/", consdiffmgr_tests },
662 : { "container/", container_tests },
663 : { "container/namemap/", namemap_tests },
664 : { "control/", controller_tests },
665 : { "control/btrack/", btrack_tests },
666 : { "control/event/", controller_event_tests },
667 : { "crypto/", crypto_tests },
668 : { "crypto/ope/", crypto_ope_tests },
669 : #ifdef ENABLE_OPENSSL
670 : { "crypto/openssl/", crypto_openssl_tests },
671 : #endif
672 : { "crypto/pem/", pem_tests },
673 : { "crypto/rng/", crypto_rng_tests },
674 : { "dir/", dir_tests },
675 : { "dir/auth/ports/", dirauth_port_tests },
676 : { "dir/auth/process_descs/", process_descs_tests },
677 : { "dir/md/", microdesc_tests },
678 : { "dirauth/dirvote/", dirvote_tests},
679 : { "dir/voting/flags/", voting_flags_tests },
680 : { "dir/voting/schedule/", voting_schedule_tests },
681 : { "dir_handle_get/", dir_handle_get_tests },
682 : { "dispatch/", dispatch_tests, },
683 : { "dns/", dns_tests },
684 : { "dos/", dos_tests },
685 : { "entryconn/", entryconn_tests },
686 : { "entrynodes/", entrynodes_tests },
687 : { "extorport/", extorport_tests },
688 : { "geoip/", geoip_tests },
689 : { "guardfraction/", guardfraction_tests },
690 : { "hs_cache/", hs_cache },
691 : { "hs_cell/", hs_cell_tests },
692 : { "hs_client/", hs_client_tests },
693 : { "hs_common/", hs_common_tests },
694 : { "hs_config/", hs_config_tests },
695 : { "hs_control/", hs_control_tests },
696 : { "hs_descriptor/", hs_descriptor },
697 : { "hs_dos/", hs_dos_tests },
698 : { "hs_intropoint/", hs_intropoint_tests },
699 : { "hs_metrics/", hs_metrics_tests },
700 : { "hs_ntor/", hs_ntor_tests },
701 : { "hs_ob/", hs_ob_tests },
702 : { "hs_service/", hs_service_tests },
703 : { "keypin/", keypin_tests },
704 : { "link-handshake/", link_handshake_tests },
705 : { "mainloop/", mainloop_tests },
706 : { "metrics/", metrics_tests },
707 : { "netinfo/", netinfo_tests },
708 : { "nodelist/", nodelist_tests },
709 : { "oom/", oom_tests },
710 : { "oos/", oos_tests },
711 : { "options/", options_tests },
712 : { "options/act/", options_act_tests },
713 : { "parsecommon/", parsecommon_tests },
714 : { "periodic-event/" , periodic_event_tests },
715 : { "policy/" , policy_tests },
716 : { "prob_distr/", prob_distr_tests },
717 : { "procmon/", procmon_tests },
718 : { "process/", process_tests },
719 : { "proto/haproxy/", proto_haproxy_tests },
720 : { "proto/http/", proto_http_tests },
721 : { "proto/misc/", proto_misc_tests },
722 : { "protover/", protover_tests },
723 : { "pt/", pt_tests },
724 : { "pubsub/build/", pubsub_build_tests },
725 : { "pubsub/msg/", pubsub_msg_tests },
726 : { "relay/" , relay_tests },
727 : { "relaycell/", relaycell_tests },
728 : { "relaycrypt/", relaycrypt_tests },
729 : { "replaycache/", replaycache_tests },
730 : { "router/", router_tests },
731 : { "routerkeys/", routerkeys_tests },
732 : { "routerlist/", routerlist_tests },
733 : { "routerset/" , routerset_tests },
734 : { "scheduler/", scheduler_tests },
735 : { "sendme/", sendme_tests },
736 : { "shared-random/", sr_tests },
737 : { "socks/", socks_tests },
738 : { "statefile/", statefile_tests },
739 : { "stats/", stats_tests },
740 : { "status/" , status_tests },
741 : { "storagedir/", storagedir_tests },
742 : { "token_bucket/", token_bucket_tests },
743 : { "tortls/", tortls_tests },
744 : #ifndef ENABLE_NSS
745 : { "tortls/openssl/", tortls_openssl_tests },
746 : #endif
747 : { "tortls/x509/", x509_tests },
748 : { "util/", util_tests },
749 : { "util/format/", util_format_tests },
750 : { "util/handle/", handle_tests },
751 : { "util/logging/", logging_tests },
752 : { "util/process/", util_process_tests },
753 : { "util/thread/", thread_tests },
754 : END_OF_GROUPS
755 : };
|