Line data Source code
1 : /* Copyright (c) 2020-2021, The Tor Project, Inc. */
2 : /* See LICENSE for licensing information */
3 :
4 : /**
5 : * \file test_dirvote.c
6 : * \brief Unit tests for dirvote related functions
7 : */
8 : #define DIRVOTE_PRIVATE
9 :
10 : #include "core/or/or.h"
11 : #include "feature/dirauth/dirvote.h"
12 : #include "feature/nodelist/dirlist.h"
13 : #include "feature/nodelist/node_st.h"
14 : #include "feature/nodelist/nodelist.h"
15 : #include "feature/nodelist/routerinfo_st.h"
16 : #include "feature/nodelist/signed_descriptor_st.h"
17 :
18 : #include "test/test.h"
19 :
20 : /**
21 : * This struct holds the various information that are needed for router
22 : * comparison. Each router in the test function has one, and they are all
23 : * put in a global digestmap, router_properties
24 : */
25 : typedef struct router_values_t {
26 : int is_running;
27 : int is_auth;
28 : int bw_kb;
29 : char digest[DIGEST_LEN];
30 : } router_values_t;
31 : /**
32 : * This typedef makes declaring digests easier and less verbose
33 : */
34 : typedef char sha1_digest_t[DIGEST_LEN];
35 :
36 : // Use of global variable is justified because the functions that have to be
37 : // mocked take as arguments objects we have no control over
38 : static digestmap_t *router_properties = NULL;
39 : // Use of global variable is justified by its use in nodelist.c
40 : // and is necessary to avoid memory leaks when mocking the
41 : // function node_get_by_id
42 : static node_t *running_node;
43 : static node_t *non_running_node;
44 :
45 : /* Allocate memory to the global variables that represent a running
46 : * and non-running node
47 : */
48 : #define ALLOCATE_MOCK_NODES() \
49 : running_node = tor_malloc(sizeof(node_t)); \
50 : running_node->is_running = 1; \
51 : non_running_node = tor_malloc(sizeof(node_t)); \
52 : non_running_node->is_running = 0;
53 :
54 : /* Free the memory allocated to the mock nodes */
55 : #define FREE_MOCK_NODES() \
56 : tor_free(running_node); \
57 : tor_free(non_running_node);
58 :
59 : static int
60 378 : mock_router_digest_is_trusted(const char *digest, dirinfo_type_t type)
61 : {
62 378 : (void)type;
63 378 : router_values_t *mock_status;
64 378 : mock_status = digestmap_get(router_properties, digest);
65 378 : if (!mock_status) {
66 : return -1;
67 : }
68 378 : return mock_status->is_auth;
69 : }
70 :
71 : static const node_t *
72 374 : mock_node_get_by_id(const char *identity_digest)
73 : {
74 374 : router_values_t *status;
75 374 : status = digestmap_get(router_properties, identity_digest);
76 374 : if (!status) {
77 : return NULL;
78 : }
79 374 : if (status->is_running)
80 369 : return running_node;
81 : else
82 5 : return non_running_node;
83 : }
84 :
85 : static uint32_t
86 372 : mock_dirserv_get_bw(const routerinfo_t *ri)
87 : {
88 372 : const char *digest = ri->cache_info.identity_digest;
89 372 : router_values_t *status;
90 372 : status = digestmap_get(router_properties, digest);
91 372 : if (!status) {
92 : return -1;
93 : }
94 372 : return status->bw_kb;
95 : }
96 :
97 : /** Generate a pointer to a router_values_t struct with the arguments as
98 : * field values, and return it
99 : * The returned pointer has to be freed by the caller.
100 : */
101 : static router_values_t *
102 41 : router_values_new(int running, int auth, int bw, char *digest)
103 : {
104 41 : router_values_t *status = tor_malloc(sizeof(router_values_t));
105 41 : memcpy(status->digest, digest, sizeof(status->digest));
106 41 : status->is_running = running;
107 41 : status->bw_kb = bw;
108 41 : status->is_auth = auth;
109 41 : return status;
110 : }
111 :
112 : /** Given a router_values_t struct, generate a pointer to a routerinfo struct.
113 : * In the cache_info member, put the identity digest, and depending on
114 : * the family argument, fill the IPv4 or IPv6 address. Return the pointer.
115 : * The returned pointer has to be freed by the caller.
116 : */
117 : static routerinfo_t *
118 41 : routerinfo_new(router_values_t *status, int family, int addr)
119 : {
120 41 : routerinfo_t *ri = tor_malloc(sizeof(routerinfo_t));
121 41 : signed_descriptor_t cache_info;
122 41 : memcpy(cache_info.identity_digest, status->digest,
123 : sizeof(cache_info.identity_digest));
124 41 : ri->cache_info = cache_info;
125 41 : tor_addr_t ipv6, ipv4;
126 41 : ipv6.family = family;
127 41 : ipv4.family = family;
128 : // Set the address of the other IP version to 0
129 41 : if (family == AF_INET) {
130 23 : ipv4.addr.in_addr.s_addr = addr;
131 391 : for (size_t i = 0; i < 16; i++) {
132 368 : ipv6.addr.in6_addr.s6_addr[i] = 0;
133 : }
134 : } else {
135 306 : for (size_t i = 0; i < 16; i++) {
136 288 : ipv6.addr.in6_addr.s6_addr[i] = addr;
137 : }
138 : ipv4.addr.in_addr.s_addr = 0;
139 : }
140 41 : ri->ipv6_addr = ipv6;
141 41 : ri->ipv4_addr = ipv4;
142 41 : return ri;
143 : }
144 :
145 : static void
146 1 : test_dirvote_compare_routerinfo_usefulness(void *arg)
147 : {
148 1 : (void)arg;
149 1 : MOCK(router_digest_is_trusted_dir_type, mock_router_digest_is_trusted);
150 1 : MOCK(node_get_by_id, mock_node_get_by_id);
151 1 : MOCK(dirserv_get_bandwidth_for_router_kb, mock_dirserv_get_bw);
152 1 : ALLOCATE_MOCK_NODES();
153 1 : router_properties = digestmap_new();
154 :
155 : // The router one is the "least useful" router, every router is compared to
156 : // it
157 1 : sha1_digest_t digest_one = "aaaa";
158 1 : router_values_t *status_one = router_values_new(0, 0, 0, digest_one);
159 1 : digestmap_set(router_properties, status_one->digest, status_one);
160 1 : sha1_digest_t digest_two = "bbbb";
161 1 : router_values_t *status_two = router_values_new(0, 1, 0, digest_two);
162 1 : digestmap_set(router_properties, status_two->digest, status_two);
163 1 : sha1_digest_t digest_three = "cccc";
164 1 : router_values_t *status_three = router_values_new(1, 0, 0, digest_three);
165 1 : digestmap_set(router_properties, status_three->digest, status_three);
166 1 : sha1_digest_t digest_four = "dddd";
167 1 : router_values_t *status_four = router_values_new(0, 0, 128, digest_four);
168 1 : digestmap_set(router_properties, status_four->digest, status_four);
169 1 : sha1_digest_t digest_five = "9999";
170 1 : router_values_t *status_five = router_values_new(0, 0, 0, digest_five);
171 1 : digestmap_set(router_properties, status_five->digest, status_five);
172 :
173 : // A router that has auth status is more useful than a non-auth one
174 1 : routerinfo_t *first = routerinfo_new(status_one, AF_INET, 0xf);
175 1 : routerinfo_t *second = routerinfo_new(status_two, AF_INET, 0xf);
176 1 : int a = compare_routerinfo_usefulness(first, second);
177 1 : tt_assert(a == 1);
178 1 : tor_free(second);
179 :
180 : // A running router is more useful than a non running one
181 1 : routerinfo_t *third = routerinfo_new(status_three, AF_INET, 0xf);
182 1 : a = compare_routerinfo_usefulness(first, third);
183 1 : tt_assert(a == 1);
184 1 : tor_free(third);
185 :
186 : // A higher bandwidth is more useful
187 1 : routerinfo_t *fourth = routerinfo_new(status_four, AF_INET, 0xf);
188 1 : a = compare_routerinfo_usefulness(first, fourth);
189 1 : tt_assert(a == 1);
190 1 : tor_free(fourth);
191 :
192 : // In case of tie, the digests are compared
193 1 : routerinfo_t *fifth = routerinfo_new(status_five, AF_INET, 0xf);
194 1 : a = compare_routerinfo_usefulness(first, fifth);
195 1 : tt_assert(a > 0);
196 1 : tor_free(fifth);
197 :
198 1 : done:
199 1 : UNMOCK(router_digest_is_trusted_dir_type);
200 1 : UNMOCK(node_get_by_id);
201 1 : UNMOCK(dirserv_get_bandwidth_for_router_kb);
202 1 : FREE_MOCK_NODES();
203 1 : digestmap_free(router_properties, NULL);
204 1 : tor_free(status_one);
205 1 : tor_free(status_two);
206 1 : tor_free(status_three);
207 1 : tor_free(status_four);
208 1 : tor_free(status_five);
209 1 : tor_free(first);
210 1 : }
211 :
212 : static void
213 1 : test_dirvote_compare_routerinfo_by_ipv4(void *arg)
214 : {
215 1 : (void)arg;
216 1 : MOCK(router_digest_is_trusted_dir_type, mock_router_digest_is_trusted);
217 1 : MOCK(node_get_by_id, mock_node_get_by_id);
218 1 : MOCK(dirserv_get_bandwidth_for_router_kb, mock_dirserv_get_bw);
219 :
220 1 : ALLOCATE_MOCK_NODES();
221 1 : router_properties = digestmap_new();
222 1 : sha1_digest_t digest_one = "aaaa";
223 1 : router_values_t *status_one = router_values_new(0, 0, 0, digest_one);
224 1 : digestmap_set(router_properties, status_one->digest, status_one);
225 1 : sha1_digest_t digest_two = "bbbb";
226 1 : router_values_t *status_two = router_values_new(0, 1, 0, digest_two);
227 1 : digestmap_set(router_properties, status_two->digest, status_two);
228 :
229 : // Both routers have an IPv4 address
230 1 : routerinfo_t *first = routerinfo_new(status_one, AF_INET, 1);
231 1 : routerinfo_t *second = routerinfo_new(status_two, AF_INET, 0xf);
232 :
233 : // The first argument's address precedes the seconds' one
234 1 : int a = compare_routerinfo_by_ipv4((const void **)&first,
235 : (const void **)&second);
236 1 : tt_assert(a < 0);
237 : // The second argument's address precedes the first' one
238 1 : a = compare_routerinfo_by_ipv4((const void **)&second,
239 : (const void **)&first);
240 1 : tt_assert(a > 0);
241 1 : tor_addr_copy(&(second->ipv4_addr), &(first->ipv6_addr));
242 : // The addresses are equal, they are compared by usefulness,
243 : // and first is less useful than second
244 1 : a = compare_routerinfo_by_ipv4((const void **)&first,
245 : (const void **)&second);
246 1 : tt_assert(a == 1);
247 1 : done:
248 1 : UNMOCK(router_digest_is_trusted_dir_type);
249 1 : UNMOCK(node_get_by_id);
250 1 : UNMOCK(dirserv_get_bandwidth_for_router_kb);
251 1 : FREE_MOCK_NODES();
252 1 : digestmap_free(router_properties, NULL);
253 1 : tor_free(status_one);
254 1 : tor_free(status_two);
255 1 : tor_free(first);
256 1 : tor_free(second);
257 1 : }
258 :
259 : static void
260 1 : test_dirvote_compare_routerinfo_by_ipv6(void *arg)
261 : {
262 1 : (void)arg;
263 1 : MOCK(router_digest_is_trusted_dir_type, mock_router_digest_is_trusted);
264 1 : MOCK(node_get_by_id, mock_node_get_by_id);
265 1 : MOCK(dirserv_get_bandwidth_for_router_kb, mock_dirserv_get_bw);
266 :
267 1 : ALLOCATE_MOCK_NODES();
268 1 : router_properties = digestmap_new();
269 1 : char digest_one[DIGEST_LEN] = "aaaa";
270 1 : router_values_t *status_one = router_values_new(0, 0, 0, digest_one);
271 1 : digestmap_set(router_properties, status_one->digest, status_one);
272 1 : char digest_two[DIGEST_LEN] = "bbbb";
273 1 : router_values_t *status_two = router_values_new(0, 1, 0, digest_two);
274 1 : digestmap_set(router_properties, status_two->digest, status_two);
275 :
276 : // Both routers have an IPv6 address
277 1 : routerinfo_t *first = routerinfo_new(status_one, AF_INET6, 1);
278 1 : routerinfo_t *second = routerinfo_new(status_two, AF_INET6, 0xf);
279 :
280 : // The first argument's address precedes the seconds' one
281 1 : int a = compare_routerinfo_by_ipv6((const void **)&first,
282 : (const void **)&second);
283 1 : tt_assert(a < 0);
284 : // The second argument's address precedes the first' one
285 1 : a = compare_routerinfo_by_ipv6((const void **)&second,
286 : (const void **)&first);
287 1 : tt_assert(a > 0);
288 1 : tor_addr_copy(&(first->ipv6_addr), &(second->ipv6_addr));
289 : // The addresses are equal, they are compared by usefulness,
290 : // and first is less useful than second
291 1 : a = compare_routerinfo_by_ipv6((const void **)&first,
292 : (const void **)&second);
293 1 : tt_assert(a == 1);
294 1 : done:
295 1 : UNMOCK(router_digest_is_trusted_dir_type);
296 1 : UNMOCK(node_get_by_id);
297 1 : UNMOCK(dirserv_get_bandwidth_for_router_kb);
298 1 : FREE_MOCK_NODES();
299 1 : digestmap_free(router_properties, NULL);
300 1 : tor_free(status_one);
301 1 : tor_free(status_two);
302 1 : tor_free(first);
303 1 : tor_free(second);
304 1 : }
305 :
306 : /** Create routers values and routerinfos that always have the same
307 : * characteristics, and add them to the global digestmap. This macro is here to
308 : * avoid duplicated code fragments.
309 : * The created name##_val pointer should be freed by the caller (and cannot
310 : * be freed in the macro as it causes a heap-after-free error)
311 : */
312 : #define CREATE_ROUTER(digest, name, addr, ip_version) \
313 : sha1_digest_t name##_digest = digest; \
314 : name##_val = router_values_new(1, 1, 1, name##_digest); \
315 : digestmap_set(router_properties, name##_digest, name##_val); \
316 : name##_ri = routerinfo_new(name##_val, ip_version, addr);
317 :
318 : #define ROUTER_FREE(name) \
319 : tor_free(name##_val); \
320 : tor_free(name##_ri);
321 :
322 : /** Test to see if the returned routers are exactly the ones that should be
323 : * flagged as sybils : we test for inclusion then for number of elements
324 : */
325 : #define TEST_SYBIL(true_sybil, possible_sybil) \
326 : DIGESTMAP_FOREACH (true_sybil, sybil_id, void *, ignore) { \
327 : (void)ignore; \
328 : tt_assert(digestmap_get(possible_sybil, sybil_id)); \
329 : } \
330 : DIGESTMAP_FOREACH_END; \
331 : tt_assert(digestmap_size(true_sybil) == digestmap_size(possible_sybil));
332 :
333 : static void
334 1 : test_dirvote_get_sybil_by_ip_version_ipv4(void *arg)
335 : {
336 : // It is assumed that global_dirauth_options.AuthDirMaxServersPerAddr == 2
337 1 : (void)arg;
338 1 : router_values_t *aaaa_val=NULL, *bbbb_val=NULL, *cccc_val=NULL,
339 1 : *dddd_val=NULL, *eeee_val=NULL, *ffff_val=NULL, *gggg_val=NULL,
340 1 : *hhhh_val=NULL;
341 1 : routerinfo_t *aaaa_ri=NULL, *bbbb_ri=NULL, *cccc_ri=NULL,
342 1 : *dddd_ri=NULL, *eeee_ri=NULL, *ffff_ri=NULL, *gggg_ri=NULL,
343 1 : *hhhh_ri=NULL;
344 :
345 1 : MOCK(router_digest_is_trusted_dir_type, mock_router_digest_is_trusted);
346 1 : MOCK(node_get_by_id, mock_node_get_by_id);
347 1 : MOCK(dirserv_get_bandwidth_for_router_kb, mock_dirserv_get_bw);
348 1 : ALLOCATE_MOCK_NODES();
349 1 : router_properties = digestmap_new();
350 1 : smartlist_t *routers_ipv4;
351 1 : routers_ipv4 = smartlist_new();
352 1 : digestmap_t *true_sybil_routers = NULL;
353 1 : true_sybil_routers = digestmap_new();
354 1 : digestmap_t *omit_as_sybil;
355 :
356 1 : CREATE_ROUTER("aaaa", aaaa, 123, AF_INET);
357 1 : smartlist_add(routers_ipv4, aaaa_ri);
358 1 : CREATE_ROUTER("bbbb", bbbb, 123, AF_INET);
359 1 : smartlist_add(routers_ipv4, bbbb_ri);
360 1 : omit_as_sybil = get_sybil_list_by_ip_version(routers_ipv4, AF_INET);
361 1 : tt_assert(digestmap_isempty(omit_as_sybil) == 1);
362 1 : digestmap_free(omit_as_sybil, NULL);
363 :
364 1 : CREATE_ROUTER("cccc", cccc, 123, AF_INET);
365 1 : smartlist_add(routers_ipv4, cccc_ri);
366 1 : digestmap_set(true_sybil_routers, cccc_digest, cccc_digest);
367 1 : omit_as_sybil = get_sybil_list_by_ip_version(routers_ipv4, AF_INET);
368 2 : TEST_SYBIL(true_sybil_routers, omit_as_sybil);
369 1 : digestmap_free(omit_as_sybil, NULL);
370 :
371 1 : CREATE_ROUTER("dddd", dddd, 123, AF_INET);
372 1 : smartlist_add(routers_ipv4, dddd_ri);
373 1 : digestmap_set(true_sybil_routers, dddd_digest, dddd_digest);
374 1 : omit_as_sybil = get_sybil_list_by_ip_version(routers_ipv4, AF_INET);
375 3 : TEST_SYBIL(true_sybil_routers, omit_as_sybil);
376 1 : digestmap_free(omit_as_sybil, NULL);
377 :
378 1 : CREATE_ROUTER("eeee", eeee, 456, AF_INET);
379 1 : smartlist_add(routers_ipv4, eeee_ri);
380 1 : omit_as_sybil = get_sybil_list_by_ip_version(routers_ipv4, AF_INET);
381 3 : TEST_SYBIL(true_sybil_routers, omit_as_sybil);
382 1 : digestmap_free(omit_as_sybil, NULL);
383 :
384 1 : CREATE_ROUTER("ffff", ffff, 456, AF_INET);
385 1 : smartlist_add(routers_ipv4, ffff_ri);
386 1 : omit_as_sybil = get_sybil_list_by_ip_version(routers_ipv4, AF_INET);
387 3 : TEST_SYBIL(true_sybil_routers, omit_as_sybil);
388 1 : digestmap_free(omit_as_sybil, NULL);
389 :
390 1 : CREATE_ROUTER("gggg", gggg, 456, AF_INET);
391 1 : smartlist_add(routers_ipv4, gggg_ri);
392 1 : digestmap_set(true_sybil_routers, gggg_digest, gggg_digest);
393 1 : omit_as_sybil = get_sybil_list_by_ip_version(routers_ipv4, AF_INET);
394 4 : TEST_SYBIL(true_sybil_routers, omit_as_sybil);
395 1 : digestmap_free(omit_as_sybil, NULL);
396 :
397 1 : CREATE_ROUTER("hhhh", hhhh, 456, AF_INET);
398 1 : smartlist_add(routers_ipv4, hhhh_ri);
399 1 : digestmap_set(true_sybil_routers, hhhh_digest, hhhh_digest);
400 1 : omit_as_sybil = get_sybil_list_by_ip_version(routers_ipv4, AF_INET);
401 5 : TEST_SYBIL(true_sybil_routers, omit_as_sybil);
402 :
403 1 : done:
404 1 : UNMOCK(router_digest_is_trusted_dir_type);
405 1 : UNMOCK(node_get_by_id);
406 1 : UNMOCK(dirserv_get_bandwidth_for_router_kb);
407 1 : FREE_MOCK_NODES();
408 1 : digestmap_free(router_properties, NULL);
409 1 : smartlist_free(routers_ipv4);
410 1 : digestmap_free(omit_as_sybil, NULL);
411 1 : digestmap_free(true_sybil_routers, NULL);
412 1 : ROUTER_FREE(aaaa);
413 1 : ROUTER_FREE(bbbb);
414 1 : ROUTER_FREE(cccc);
415 1 : ROUTER_FREE(dddd);
416 1 : ROUTER_FREE(eeee);
417 1 : ROUTER_FREE(ffff);
418 1 : ROUTER_FREE(gggg);
419 1 : ROUTER_FREE(hhhh);
420 1 : }
421 :
422 : static void
423 1 : test_dirvote_get_sybil_by_ip_version_ipv6(void *arg)
424 : {
425 1 : router_values_t *aaaa_val=NULL, *bbbb_val=NULL, *cccc_val=NULL,
426 1 : *dddd_val=NULL, *eeee_val=NULL, *ffff_val=NULL, *gggg_val=NULL,
427 1 : *hhhh_val=NULL;
428 1 : routerinfo_t *aaaa_ri=NULL, *bbbb_ri=NULL, *cccc_ri=NULL,
429 1 : *dddd_ri=NULL, *eeee_ri=NULL, *ffff_ri=NULL, *gggg_ri=NULL,
430 1 : *hhhh_ri=NULL;
431 :
432 : // It is assumed that global_dirauth_options.AuthDirMaxServersPerAddr == 2
433 1 : (void)arg;
434 1 : MOCK(router_digest_is_trusted_dir_type, mock_router_digest_is_trusted);
435 1 : MOCK(node_get_by_id, mock_node_get_by_id);
436 1 : MOCK(dirserv_get_bandwidth_for_router_kb, mock_dirserv_get_bw);
437 1 : ALLOCATE_MOCK_NODES();
438 1 : router_properties = digestmap_new();
439 1 : smartlist_t *routers_ipv6;
440 1 : routers_ipv6 = smartlist_new();
441 1 : digestmap_t *true_sybil_routers = NULL;
442 1 : true_sybil_routers = digestmap_new();
443 1 : digestmap_t *omit_as_sybil;
444 :
445 1 : CREATE_ROUTER("aaaa", aaaa, 123, AF_INET6);
446 1 : smartlist_add(routers_ipv6, aaaa_ri);
447 1 : CREATE_ROUTER("bbbb", bbbb, 123, AF_INET6);
448 1 : smartlist_add(routers_ipv6, bbbb_ri);
449 1 : omit_as_sybil = get_sybil_list_by_ip_version(routers_ipv6, AF_INET6);
450 1 : TEST_SYBIL(true_sybil_routers, omit_as_sybil);
451 1 : digestmap_free(omit_as_sybil, NULL);
452 :
453 1 : CREATE_ROUTER("cccc", cccc, 123, AF_INET6);
454 1 : smartlist_add(routers_ipv6, cccc_ri);
455 1 : digestmap_set(true_sybil_routers, cccc_digest, cccc_digest);
456 1 : omit_as_sybil = get_sybil_list_by_ip_version(routers_ipv6, AF_INET6);
457 2 : TEST_SYBIL(true_sybil_routers, omit_as_sybil);
458 1 : digestmap_free(omit_as_sybil, NULL);
459 :
460 1 : CREATE_ROUTER("dddd", dddd, 123, AF_INET6);
461 1 : smartlist_add(routers_ipv6, dddd_ri);
462 1 : digestmap_set(true_sybil_routers, dddd_digest, dddd_digest);
463 1 : omit_as_sybil = get_sybil_list_by_ip_version(routers_ipv6, AF_INET6);
464 3 : TEST_SYBIL(true_sybil_routers, omit_as_sybil);
465 1 : digestmap_free(omit_as_sybil, NULL);
466 :
467 1 : CREATE_ROUTER("eeee", eeee, 456, AF_INET6);
468 1 : smartlist_add(routers_ipv6, eeee_ri);
469 1 : omit_as_sybil = get_sybil_list_by_ip_version(routers_ipv6, AF_INET6);
470 3 : TEST_SYBIL(true_sybil_routers, omit_as_sybil);
471 1 : digestmap_free(omit_as_sybil, NULL);
472 :
473 1 : CREATE_ROUTER("ffff", ffff, 456, AF_INET6);
474 1 : smartlist_add(routers_ipv6, ffff_ri);
475 1 : omit_as_sybil = get_sybil_list_by_ip_version(routers_ipv6, AF_INET6);
476 3 : TEST_SYBIL(true_sybil_routers, omit_as_sybil);
477 1 : digestmap_free(omit_as_sybil, NULL);
478 :
479 1 : CREATE_ROUTER("gggg", gggg, 456, AF_INET6);
480 1 : smartlist_add(routers_ipv6, gggg_ri);
481 1 : digestmap_set(true_sybil_routers, gggg_digest, gggg_digest);
482 1 : omit_as_sybil = get_sybil_list_by_ip_version(routers_ipv6, AF_INET6);
483 4 : TEST_SYBIL(true_sybil_routers, omit_as_sybil);
484 1 : digestmap_free(omit_as_sybil, NULL);
485 :
486 1 : CREATE_ROUTER("hhhh", hhhh, 456, AF_INET6);
487 1 : smartlist_add(routers_ipv6, hhhh_ri);
488 1 : digestmap_set(true_sybil_routers, hhhh_digest, hhhh_digest);
489 1 : omit_as_sybil = get_sybil_list_by_ip_version(routers_ipv6, AF_INET6);
490 5 : TEST_SYBIL(true_sybil_routers, omit_as_sybil);
491 1 : done:
492 1 : UNMOCK(router_digest_is_trusted_dir_type);
493 1 : UNMOCK(node_get_by_id);
494 1 : UNMOCK(dirserv_get_bandwidth_for_router_kb);
495 1 : FREE_MOCK_NODES();
496 1 : digestmap_free(router_properties, NULL);
497 1 : digestmap_free(true_sybil_routers, NULL);
498 1 : smartlist_free(routers_ipv6);
499 1 : digestmap_free(omit_as_sybil, NULL);
500 1 : ROUTER_FREE(aaaa);
501 1 : ROUTER_FREE(bbbb);
502 1 : ROUTER_FREE(cccc);
503 1 : ROUTER_FREE(dddd);
504 1 : ROUTER_FREE(eeee);
505 1 : ROUTER_FREE(ffff);
506 1 : ROUTER_FREE(gggg);
507 1 : ROUTER_FREE(hhhh);
508 1 : }
509 :
510 : static void
511 1 : test_dirvote_get_all_possible_sybil(void *arg)
512 : {
513 1 : router_values_t *aaaa_val=NULL, *bbbb_val=NULL, *cccc_val=NULL,
514 1 : *dddd_val=NULL, *eeee_val=NULL, *ffff_val=NULL, *gggg_val=NULL,
515 1 : *hhhh_val=NULL, *iiii_val=NULL, *jjjj_val=NULL, *kkkk_val=NULL,
516 1 : *llll_val=NULL, *mmmm_val=NULL, *nnnn_val=NULL, *oooo_val=NULL,
517 1 : *pppp_val=NULL;
518 1 : routerinfo_t *aaaa_ri=NULL, *bbbb_ri=NULL, *cccc_ri=NULL,
519 1 : *dddd_ri=NULL, *eeee_ri=NULL, *ffff_ri=NULL, *gggg_ri=NULL,
520 1 : *hhhh_ri=NULL, *iiii_ri=NULL, *jjjj_ri=NULL, *kkkk_ri=NULL,
521 1 : *llll_ri=NULL, *mmmm_ri=NULL, *nnnn_ri=NULL, *oooo_ri=NULL,
522 1 : *pppp_ri=NULL;
523 :
524 : // It is assumed that global_dirauth_options.AuthDirMaxServersPerAddr == 2
525 1 : (void)arg;
526 1 : MOCK(router_digest_is_trusted_dir_type, mock_router_digest_is_trusted);
527 1 : MOCK(node_get_by_id, mock_node_get_by_id);
528 1 : MOCK(dirserv_get_bandwidth_for_router_kb, mock_dirserv_get_bw);
529 1 : ALLOCATE_MOCK_NODES();
530 1 : router_properties = digestmap_new();
531 1 : smartlist_t *routers;
532 1 : routers = smartlist_new();
533 1 : digestmap_t *true_sybil_routers = NULL;
534 1 : true_sybil_routers = digestmap_new();
535 1 : digestmap_t *omit_as_sybil;
536 :
537 1 : CREATE_ROUTER("aaaa", aaaa, 123, AF_INET);
538 1 : smartlist_add(routers, aaaa_ri);
539 1 : CREATE_ROUTER("bbbb", bbbb, 123, AF_INET);
540 1 : smartlist_add(routers, bbbb_ri);
541 1 : omit_as_sybil = get_all_possible_sybil(routers);
542 1 : TEST_SYBIL(true_sybil_routers, omit_as_sybil);
543 1 : digestmap_free(omit_as_sybil, NULL);
544 :
545 1 : CREATE_ROUTER("cccc", cccc, 123, AF_INET);
546 1 : smartlist_add(routers, cccc_ri);
547 1 : digestmap_set(true_sybil_routers, cccc_digest, cccc_digest);
548 1 : omit_as_sybil = get_all_possible_sybil(routers);
549 2 : TEST_SYBIL(true_sybil_routers, omit_as_sybil);
550 1 : digestmap_free(omit_as_sybil, NULL);
551 :
552 1 : CREATE_ROUTER("dddd", dddd, 123, AF_INET);
553 1 : smartlist_add(routers, dddd_ri);
554 1 : digestmap_set(true_sybil_routers, dddd_digest, dddd_digest);
555 1 : omit_as_sybil = get_all_possible_sybil(routers);
556 3 : TEST_SYBIL(true_sybil_routers, omit_as_sybil);
557 1 : digestmap_free(omit_as_sybil, NULL);
558 :
559 1 : CREATE_ROUTER("eeee", eeee, 456, AF_INET);
560 1 : smartlist_add(routers, eeee_ri);
561 1 : omit_as_sybil = get_all_possible_sybil(routers);
562 3 : TEST_SYBIL(true_sybil_routers, omit_as_sybil);
563 1 : digestmap_free(omit_as_sybil, NULL);
564 :
565 1 : CREATE_ROUTER("ffff", ffff, 456, AF_INET);
566 1 : smartlist_add(routers, ffff_ri);
567 1 : omit_as_sybil = get_all_possible_sybil(routers);
568 3 : TEST_SYBIL(true_sybil_routers, omit_as_sybil);
569 1 : digestmap_free(omit_as_sybil, NULL);
570 :
571 1 : CREATE_ROUTER("gggg", gggg, 456, AF_INET);
572 1 : smartlist_add(routers, gggg_ri);
573 1 : digestmap_set(true_sybil_routers, gggg_digest, gggg_digest);
574 1 : omit_as_sybil = get_all_possible_sybil(routers);
575 4 : TEST_SYBIL(true_sybil_routers, omit_as_sybil);
576 1 : digestmap_free(omit_as_sybil, NULL);
577 :
578 1 : CREATE_ROUTER("hhhh", hhhh, 456, AF_INET);
579 1 : smartlist_add(routers, hhhh_ri);
580 1 : digestmap_set(true_sybil_routers, hhhh_digest, hhhh_digest);
581 1 : omit_as_sybil = get_all_possible_sybil(routers);
582 5 : TEST_SYBIL(true_sybil_routers, omit_as_sybil);
583 1 : digestmap_free(omit_as_sybil, NULL);
584 :
585 1 : CREATE_ROUTER("iiii", iiii, 123, AF_INET6);
586 1 : smartlist_add(routers, iiii_ri);
587 1 : CREATE_ROUTER("jjjj", jjjj, 123, AF_INET6);
588 1 : smartlist_add(routers, jjjj_ri);
589 1 : omit_as_sybil = get_all_possible_sybil(routers);
590 5 : TEST_SYBIL(true_sybil_routers, omit_as_sybil);
591 1 : digestmap_free(omit_as_sybil, NULL);
592 :
593 1 : CREATE_ROUTER("kkkk", kkkk, 123, AF_INET6);
594 1 : smartlist_add(routers, kkkk_ri);
595 1 : digestmap_set(true_sybil_routers, kkkk_digest, kkkk_digest);
596 1 : omit_as_sybil = get_all_possible_sybil(routers);
597 6 : TEST_SYBIL(true_sybil_routers, omit_as_sybil);
598 1 : digestmap_free(omit_as_sybil,NULL);
599 :
600 1 : CREATE_ROUTER("llll", llll, 123, AF_INET6);
601 1 : smartlist_add(routers, llll_ri);
602 1 : digestmap_set(true_sybil_routers, llll_digest, llll_digest);
603 1 : omit_as_sybil = get_all_possible_sybil(routers);
604 7 : TEST_SYBIL(true_sybil_routers, omit_as_sybil);
605 1 : digestmap_free(omit_as_sybil,NULL);
606 :
607 1 : CREATE_ROUTER("mmmm", mmmm, 456, AF_INET6);
608 1 : smartlist_add(routers, mmmm_ri);
609 1 : omit_as_sybil = get_all_possible_sybil(routers);
610 7 : TEST_SYBIL(true_sybil_routers, omit_as_sybil);
611 1 : digestmap_free(omit_as_sybil, NULL);
612 :
613 1 : CREATE_ROUTER("nnnn", nnnn, 456, AF_INET6);
614 1 : smartlist_add(routers, nnnn_ri);
615 1 : omit_as_sybil = get_all_possible_sybil(routers);
616 7 : TEST_SYBIL(true_sybil_routers, omit_as_sybil);
617 1 : digestmap_free(omit_as_sybil, NULL);
618 :
619 1 : CREATE_ROUTER("oooo", oooo, 456, AF_INET6);
620 1 : smartlist_add(routers, oooo_ri);
621 1 : digestmap_set(true_sybil_routers, oooo_digest, oooo_digest);
622 1 : omit_as_sybil = get_all_possible_sybil(routers);
623 8 : TEST_SYBIL(true_sybil_routers, omit_as_sybil);
624 1 : digestmap_free(omit_as_sybil, NULL);
625 :
626 1 : CREATE_ROUTER("pppp", pppp, 456, AF_INET6);
627 1 : smartlist_add(routers, pppp_ri);
628 1 : digestmap_set(true_sybil_routers, pppp_digest, pppp_digest);
629 1 : omit_as_sybil = get_all_possible_sybil(routers);
630 9 : TEST_SYBIL(true_sybil_routers, omit_as_sybil);
631 :
632 1 : done:
633 1 : UNMOCK(router_digest_is_trusted_dir_type);
634 1 : UNMOCK(node_get_by_id);
635 1 : UNMOCK(dirserv_get_bandwidth_for_router_kb);
636 1 : FREE_MOCK_NODES();
637 1 : digestmap_free(router_properties, NULL);
638 1 : smartlist_free(routers);
639 1 : digestmap_free(omit_as_sybil, NULL);
640 1 : digestmap_free(true_sybil_routers, NULL);
641 1 : ROUTER_FREE(aaaa);
642 1 : ROUTER_FREE(bbbb);
643 1 : ROUTER_FREE(cccc);
644 1 : ROUTER_FREE(dddd);
645 1 : ROUTER_FREE(eeee);
646 1 : ROUTER_FREE(ffff);
647 1 : ROUTER_FREE(gggg);
648 1 : ROUTER_FREE(hhhh);
649 1 : ROUTER_FREE(iiii);
650 1 : ROUTER_FREE(jjjj);
651 1 : ROUTER_FREE(kkkk);
652 1 : ROUTER_FREE(llll);
653 1 : ROUTER_FREE(mmmm);
654 1 : ROUTER_FREE(nnnn);
655 1 : ROUTER_FREE(oooo);
656 1 : ROUTER_FREE(pppp);
657 1 : }
658 :
659 : static void
660 1 : test_dirvote_parse_param_buggy(void *arg)
661 : {
662 1 : (void)arg;
663 :
664 : /* Tests for behavior with bug emulation to migrate away from bug 19011. */
665 1 : tt_i64_op(extract_param_buggy("blah blah", "bwweightscale", 10000),
666 : OP_EQ, 10000);
667 1 : tt_i64_op(extract_param_buggy("bwweightscale=7", "bwweightscale", 10000),
668 : OP_EQ, 7);
669 1 : tt_i64_op(extract_param_buggy("bwweightscale=7 foo=9",
670 : "bwweightscale", 10000),
671 : OP_EQ, 10000);
672 1 : tt_i64_op(extract_param_buggy("foo=7 bwweightscale=777 bar=9",
673 : "bwweightscale", 10000),
674 : OP_EQ, 10000);
675 1 : tt_i64_op(extract_param_buggy("foo=7 bwweightscale=1234",
676 : "bwweightscale", 10000),
677 : OP_EQ, 1234);
678 :
679 1 : done:
680 1 : ;
681 1 : }
682 :
683 : #define NODE(name, flags) \
684 : { \
685 : #name, test_dirvote_##name, (flags), NULL, NULL \
686 : }
687 :
688 : struct testcase_t dirvote_tests[] = {
689 : NODE(compare_routerinfo_usefulness, TT_FORK),
690 : NODE(compare_routerinfo_by_ipv6, TT_FORK),
691 : NODE(compare_routerinfo_by_ipv4, TT_FORK),
692 : NODE(get_sybil_by_ip_version_ipv4, TT_FORK),
693 : NODE(get_sybil_by_ip_version_ipv6, TT_FORK),
694 : NODE(get_all_possible_sybil, TT_FORK),
695 : NODE(parse_param_buggy, 0),
696 : END_OF_TESTCASES};
|