Line data Source code
1 : /* Copyright (c) 2017-2021, The Tor Project, Inc. */
2 : /* See LICENSE for licensing information */
3 :
4 : #include "core/or/or.h"
5 : #include "lib/crypt_ops/crypto_rand.h"
6 : #include "core/or/address_set.h"
7 : #include "feature/nodelist/dirlist.h"
8 : #include "feature/nodelist/microdesc.h"
9 : #include "feature/nodelist/networkstatus.h"
10 : #include "feature/nodelist/nodelist.h"
11 : #include "feature/nodelist/routerlist.h"
12 : #include "feature/nodelist/torcert.h"
13 :
14 : #include "feature/nodelist/microdesc_st.h"
15 : #include "feature/nodelist/networkstatus_st.h"
16 : #include "feature/nodelist/routerinfo_st.h"
17 : #include "feature/nodelist/routerstatus_st.h"
18 :
19 : #include "test/test.h"
20 :
21 : static networkstatus_t *dummy_ns = NULL;
22 : static networkstatus_t *
23 4 : mock_networkstatus_get_latest_consensus(void)
24 : {
25 4 : return dummy_ns;
26 : }
27 :
28 : static networkstatus_t *
29 2 : mock_networkstatus_get_latest_consensus_by_flavor(consensus_flavor_t f)
30 : {
31 2 : tor_assert(f == FLAV_MICRODESC);
32 2 : return dummy_ns;
33 : }
34 :
35 : static void
36 4 : mock_dirlist_add_trusted_dir_addresses(void)
37 : {
38 4 : return;
39 : }
40 :
41 : /* Number of address a single node_t can have. Default to the production
42 : * value. This is to control the size of the bloom filter. */
43 : static int addr_per_node = 2;
44 : static int
45 8 : mock_get_estimated_address_per_node(void)
46 : {
47 8 : return addr_per_node;
48 : }
49 :
50 : static void
51 1 : test_contains(void *arg)
52 : {
53 1 : int ret;
54 1 : address_set_t *set = NULL;
55 :
56 1 : (void) arg;
57 :
58 : /* Setup an IPv4 and IPv6 addresses. */
59 1 : tor_addr_t addr_v6;
60 1 : tor_addr_parse(&addr_v6, "1:2:3:4::");
61 1 : tor_addr_t addr_v4;
62 1 : tor_addr_parse(&addr_v4, "42.42.42.42");
63 1 : uint32_t ipv4h = tor_addr_to_ipv4h(&addr_v4);
64 :
65 : /* Make it very big so the chance of failing the contain test will be
66 : * extremely rare. */
67 1 : set = address_set_new(1024);
68 1 : tt_assert(set);
69 :
70 : /* Add and lookup IPv6. */
71 1 : address_set_add(set, &addr_v6);
72 1 : ret = address_set_probably_contains(set, &addr_v6);
73 1 : tt_int_op(ret, OP_EQ, 1);
74 :
75 : /* Add and lookup IPv4. */
76 1 : address_set_add_ipv4h(set, ipv4h);
77 1 : ret = address_set_probably_contains(set, &addr_v4);
78 1 : tt_int_op(ret, OP_EQ, 1);
79 :
80 : /* Try a lookup of rubbish. */
81 1 : tor_addr_t dummy_addr;
82 1 : memset(&dummy_addr, 'A', sizeof(dummy_addr));
83 1 : dummy_addr.family = AF_INET;
84 1 : ret = address_set_probably_contains(set, &dummy_addr);
85 1 : tt_int_op(ret, OP_EQ, 0);
86 1 : dummy_addr.family = AF_INET6;
87 1 : ret = address_set_probably_contains(set, &dummy_addr);
88 1 : tt_int_op(ret, OP_EQ, 0);
89 :
90 1 : done:
91 1 : address_set_free(set);
92 1 : }
93 :
94 : static void
95 1 : test_nodelist(void *arg)
96 : {
97 1 : int ret;
98 1 : routerstatus_t *rs = NULL; microdesc_t *md = NULL; routerinfo_t *ri = NULL;
99 :
100 1 : (void) arg;
101 :
102 1 : MOCK(networkstatus_get_latest_consensus,
103 : mock_networkstatus_get_latest_consensus);
104 1 : MOCK(networkstatus_get_latest_consensus_by_flavor,
105 : mock_networkstatus_get_latest_consensus_by_flavor);
106 1 : MOCK(get_estimated_address_per_node,
107 : mock_get_estimated_address_per_node);
108 1 : MOCK(dirlist_add_trusted_dir_addresses,
109 : mock_dirlist_add_trusted_dir_addresses);
110 :
111 1 : dummy_ns = tor_malloc_zero(sizeof(*dummy_ns));
112 1 : dummy_ns->flavor = FLAV_MICRODESC;
113 1 : dummy_ns->routerstatus_list = smartlist_new();
114 :
115 1 : tor_addr_t addr_v4, addr_v6, dummy_addr;
116 1 : tor_addr_parse(&addr_v4, "42.42.42.42");
117 1 : tor_addr_parse(&addr_v6, "1:2:3:4::");
118 1 : memset(&dummy_addr, 'A', sizeof(dummy_addr));
119 :
120 : /* This will make the nodelist bloom filter very large
121 : * (the_nodelist->node_addrs) so we will fail the contain test rarely. */
122 1 : addr_per_node = 1024;
123 :
124 : /* No node no nothing. The lookups should be empty. We've mocked the
125 : * dirlist_add_trusted_dir_addresses in order for _no_ authorities to be
126 : * added to the filter else it makes this test to trigger many false
127 : * positive. */
128 1 : nodelist_set_consensus(dummy_ns);
129 :
130 : /* The address set should be empty. */
131 1 : ret = nodelist_probably_contains_address(&addr_v4);
132 1 : tt_int_op(ret, OP_EQ, 0);
133 1 : ret = nodelist_probably_contains_address(&addr_v6);
134 1 : tt_int_op(ret, OP_EQ, 0);
135 1 : dummy_addr.family = AF_INET;
136 1 : ret = nodelist_probably_contains_address(&dummy_addr);
137 1 : tt_int_op(ret, OP_EQ, 0);
138 1 : dummy_addr.family = AF_INET6;
139 1 : ret = nodelist_probably_contains_address(&dummy_addr);
140 1 : tt_int_op(ret, OP_EQ, 0);
141 :
142 1 : md = tor_malloc_zero(sizeof(*md));
143 1 : ri = tor_malloc_zero(sizeof(*ri));
144 1 : rs = tor_malloc_zero(sizeof(*rs));
145 1 : crypto_rand(rs->identity_digest, sizeof(rs->identity_digest));
146 1 : crypto_rand(md->digest, sizeof(md->digest));
147 1 : memcpy(rs->descriptor_digest, md->digest, DIGEST256_LEN);
148 :
149 : /* Setup the rs, ri and md addresses. */
150 1 : tor_addr_copy(&rs->ipv4_addr, &addr_v4);
151 1 : tor_addr_parse(&rs->ipv6_addr, "1:2:3:4::");
152 1 : tor_addr_copy(&ri->ipv4_addr, &addr_v4);
153 1 : tor_addr_parse(&ri->ipv6_addr, "1:2:3:4::");
154 1 : tor_addr_parse(&md->ipv6_addr, "1:2:3:4::");
155 :
156 : /* Add the rs to the consensus becoming a node_t. */
157 1 : smartlist_add(dummy_ns->routerstatus_list, rs);
158 1 : nodelist_set_consensus(dummy_ns);
159 :
160 : /* At this point, the address set should be initialized in the nodelist and
161 : * we should be able to lookup. */
162 1 : ret = nodelist_probably_contains_address(&addr_v4);
163 1 : tt_int_op(ret, OP_EQ, 1);
164 1 : ret = nodelist_probably_contains_address(&addr_v6);
165 1 : tt_int_op(ret, OP_EQ, 1);
166 : /* Lookup unknown address. */
167 1 : dummy_addr.family = AF_INET;
168 1 : ret = nodelist_probably_contains_address(&dummy_addr);
169 1 : tt_int_op(ret, OP_EQ, 0);
170 1 : dummy_addr.family = AF_INET6;
171 1 : ret = nodelist_probably_contains_address(&dummy_addr);
172 1 : tt_int_op(ret, OP_EQ, 0);
173 :
174 1 : done:
175 1 : routerstatus_free(rs); routerinfo_free(ri); microdesc_free(md);
176 1 : smartlist_clear(dummy_ns->routerstatus_list);
177 1 : networkstatus_vote_free(dummy_ns);
178 1 : UNMOCK(networkstatus_get_latest_consensus);
179 1 : UNMOCK(networkstatus_get_latest_consensus_by_flavor);
180 1 : UNMOCK(get_estimated_address_per_node);
181 1 : UNMOCK(dirlist_add_trusted_dir_addresses);
182 1 : }
183 :
184 : /** Test that the no-reentry exit filter works as intended */
185 : static void
186 1 : test_exit_no_reentry(void *arg)
187 : {
188 1 : routerstatus_t *rs = NULL; microdesc_t *md = NULL; routerinfo_t *ri = NULL;
189 1 : (void) arg;
190 :
191 1 : MOCK(networkstatus_get_latest_consensus,
192 : mock_networkstatus_get_latest_consensus);
193 1 : MOCK(networkstatus_get_latest_consensus_by_flavor,
194 : mock_networkstatus_get_latest_consensus_by_flavor);
195 1 : MOCK(get_estimated_address_per_node,
196 : mock_get_estimated_address_per_node);
197 1 : MOCK(dirlist_add_trusted_dir_addresses,
198 : mock_dirlist_add_trusted_dir_addresses);
199 :
200 1 : dummy_ns = tor_malloc_zero(sizeof(*dummy_ns));
201 1 : dummy_ns->flavor = FLAV_MICRODESC;
202 1 : dummy_ns->routerstatus_list = smartlist_new();
203 :
204 1 : tor_addr_t addr_v4, addr_v6, dummy_addr;
205 1 : tor_addr_parse(&addr_v4, "42.42.42.42");
206 1 : tor_addr_parse(&addr_v6, "1:2:3:4::");
207 1 : memset(&dummy_addr, 'A', sizeof(dummy_addr));
208 :
209 : /* This will make the nodelist bloom filter very large
210 : * (the_nodelist->node_addrs) so we will fail the contain test rarely. */
211 1 : addr_per_node = 1024;
212 :
213 : /* After this point the nodelist is populated with the directory authorities
214 : * address and ports */
215 1 : nodelist_set_consensus(dummy_ns);
216 :
217 : /* The address set is empty. Try it anyway */
218 1 : tt_assert(!nodelist_reentry_contains(&addr_v4, 244));
219 1 : tt_assert(!nodelist_reentry_contains(&addr_v6, 244));
220 :
221 : /* Now let's populate the network */
222 1 : md = tor_malloc_zero(sizeof(*md));
223 1 : ri = tor_malloc_zero(sizeof(*ri));
224 1 : rs = tor_malloc_zero(sizeof(*rs));
225 1 : crypto_rand(rs->identity_digest, sizeof(rs->identity_digest));
226 1 : crypto_rand(md->digest, sizeof(md->digest));
227 1 : memcpy(rs->descriptor_digest, md->digest, DIGEST256_LEN);
228 :
229 : /* Setup the rs, ri and md addresses. */
230 1 : tor_addr_copy(&rs->ipv4_addr, &addr_v4);
231 1 : rs->ipv4_orport = 444;
232 1 : tor_addr_parse(&rs->ipv6_addr, "1:2:3:4::");
233 1 : rs->ipv6_orport = 666;
234 1 : tor_addr_copy(&ri->ipv4_addr, &addr_v4);
235 1 : tor_addr_parse(&ri->ipv6_addr, "1:2:3:4::");
236 1 : tor_addr_parse(&md->ipv6_addr, "1:2:3:4::");
237 :
238 : /* Add the rs to the consensus becoming a node_t. */
239 1 : smartlist_add(dummy_ns->routerstatus_list, rs);
240 1 : nodelist_set_consensus(dummy_ns);
241 :
242 : /* Now that the nodelist is populated let's do some retry attempts */
243 :
244 : /* First let's try an address that is on the no-reentry list, but with a
245 : different port */
246 1 : tt_assert(!nodelist_reentry_contains(&addr_v4, 666));
247 1 : tt_assert(!nodelist_reentry_contains(&addr_v6, 444));
248 :
249 : /* OK now let's try with the right address and right port */
250 1 : tt_assert(nodelist_reentry_contains(&addr_v4, 444));
251 1 : tt_assert(nodelist_reentry_contains(&addr_v6, 666));
252 :
253 1 : done:
254 1 : routerstatus_free(rs); routerinfo_free(ri); microdesc_free(md);
255 1 : smartlist_clear(dummy_ns->routerstatus_list);
256 1 : networkstatus_vote_free(dummy_ns);
257 1 : UNMOCK(networkstatus_get_latest_consensus);
258 1 : UNMOCK(networkstatus_get_latest_consensus_by_flavor);
259 1 : UNMOCK(get_estimated_address_per_node);
260 1 : UNMOCK(dirlist_add_trusted_dir_addresses);
261 1 : }
262 :
263 : struct testcase_t address_set_tests[] = {
264 : { "contains", test_contains, TT_FORK,
265 : NULL, NULL },
266 : { "nodelist", test_nodelist, TT_FORK,
267 : NULL, NULL },
268 : { "exit_no_reentry", test_exit_no_reentry, TT_FORK, NULL, NULL },
269 :
270 : END_OF_TESTCASES
271 : };
272 :
|