Line data Source code
1 : /* Copyright (c) 2019 The Tor Project, Inc. */
2 : /* See LICENSE for licensing information */
3 :
4 : /**
5 : * \file circuitpadding_machines.c
6 : * \brief Circuit padding state machines
7 : *
8 : * Introduce circuit padding machines that will be used by Tor circuits, as
9 : * specified by proposal 302 "Hiding onion service clients using padding".
10 : *
11 : * Right now this file introduces two machines that aim to hide the client-side
12 : * of onion service circuits against naive classifiers like the ones from the
13 : * "Circuit Fingerprinting Attacks: Passive Deanonymization of Tor Hidden
14 : * Services" paper from USENIX. By naive classifiers we mean classifiers that
15 : * use basic features like "circuit construction circuits" and "incoming and
16 : * outgoing cell counts" and "duration of activity".
17 : *
18 : * In particular, these machines aim to be lightweight and protect against
19 : * these basic classifiers. They don't aim to protect against more advanced
20 : * attacks that use deep learning or even correlate various circuit
21 : * construction events together. Machines that fool such advanced classifiers
22 : * are also possible, but they can't be so lightweight and might require more
23 : * WTF-PAD features. So for now we opt for the following two machines:
24 : *
25 : * Client-side introduction circuit hiding machine:
26 : *
27 : * This machine hides client-side introduction circuits by making their
28 : * circuit construction sequence look like normal general circuits that
29 : * download directory information. Furthermore, the circuits are kept open
30 : * until all the padding has been sent, since intro circuits are usually
31 : * very short lived and this act as a distinguisher. For more info see
32 : * circpad_machine_client_hide_intro_circuits() and the sec.
33 : *
34 : * Client-side rendezvous circuit hiding machine:
35 : *
36 : * This machine hides client-side rendezvous circuits by making their
37 : * circuit construction sequence look like normal general circuits. For more
38 : * details see circpad_machine_client_hide_rend_circuits() and the spec.
39 : *
40 : * TODO: These are simple machines that carefully manipulate the cells of the
41 : * initial circuit setup procedure to make them look like general
42 : * circuits. In the future, more states can be baked into their state machine
43 : * to do more advanced obfuscation.
44 : **/
45 :
46 : #define CIRCUITPADDING_MACHINES_PRIVATE
47 :
48 : #include "core/or/or.h"
49 : #include "feature/nodelist/networkstatus.h"
50 :
51 : #include "lib/crypt_ops/crypto_rand.h"
52 :
53 : #include "core/or/circuitlist.h"
54 :
55 : #include "core/or/circuitpadding_machines.h"
56 : #include "core/or/circuitpadding.h"
57 :
58 : /** Create a client-side padding machine that aims to hide IP circuits. In
59 : * particular, it keeps intro circuits alive until a bunch of fake traffic has
60 : * been pushed through.
61 : */
62 : void
63 200 : circpad_machine_client_hide_intro_circuits(smartlist_t *machines_sl)
64 : {
65 200 : circpad_machine_spec_t *client_machine
66 200 : = tor_malloc_zero(sizeof(circpad_machine_spec_t));
67 :
68 200 : client_machine->name = "client_ip_circ";
69 :
70 200 : client_machine->conditions.apply_state_mask = CIRCPAD_CIRC_OPENED;
71 200 : client_machine->target_hopnum = 2;
72 :
73 : /* This is a client machine */
74 200 : client_machine->is_origin_side = 1;
75 :
76 : /* We only want to pad introduction circuits, and we want to start padding
77 : * only after the INTRODUCE1 cell has been sent, so set the purposes
78 : * appropriately.
79 : *
80 : * In particular we want introduction circuits to blend as much as possible
81 : * with general circuits. Most general circuits have the following initial
82 : * relay cell sequence (outgoing cells marked in [brackets]):
83 : *
84 : * [EXTEND2] -> EXTENDED2 -> [EXTEND2] -> EXTENDED2 -> [BEGIN] -> CONNECTED
85 : * -> [DATA] -> [DATA] -> DATA -> DATA...(inbound data cells continue)
86 : *
87 : * Whereas normal introduction circuits usually look like:
88 : *
89 : * [EXTEND2] -> EXTENDED2 -> [EXTEND2] -> EXTENDED2 -> [EXTEND2] -> EXTENDED2
90 : * -> [INTRO1] -> INTRODUCE_ACK
91 : *
92 : * This means that up to the sixth cell (first line of each sequence above),
93 : * both general and intro circuits have identical cell sequences. After that
94 : * we want to mimic the second line sequence of
95 : * -> [DATA] -> [DATA] -> DATA -> DATA...(inbound data cells continue)
96 : *
97 : * We achieve this by starting padding INTRODUCE1 has been sent. With padding
98 : * negotiation cells, in the common case of the second line looks like:
99 : * -> [INTRO1] -> [PADDING_NEGOTIATE] -> PADDING_NEGOTIATED -> INTRO_ACK
100 : *
101 : * Then, the middle node will send between INTRO_MACHINE_MINIMUM_PADDING and
102 : * INTRO_MACHINE_MAXIMUM_PADDING cells, to match the "...(inbound data cells
103 : * continue)" portion of the trace (aka the rest of an HTTPS response body).
104 : */
105 :
106 : /* Start the machine on fresh intro circs. */
107 400 : client_machine->conditions.apply_purpose_mask =
108 200 : circpad_circ_purpose_to_mask(CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT);
109 :
110 : /* If the client purpose changes back to CIRCUIT_PURPOSE_C_INTRODUCING,
111 : * or transitions to CIRCUIT_PURPOSE_C_INTRODUCE_ACKED, keep the machine
112 : * alive, but do not launch new machines for these purposes. Also
113 : * keep the machine around if it is in the CIRCUIT_PADDING purpose
114 : * (but do not try to take over other machines in that purpose). */
115 400 : client_machine->conditions.keep_purpose_mask =
116 200 : circpad_circ_purpose_to_mask(CIRCUIT_PURPOSE_C_INTRODUCE_ACKED) |
117 200 : circpad_circ_purpose_to_mask(CIRCUIT_PURPOSE_C_CIRCUIT_PADDING);
118 :
119 : /* Keep the circuit alive even after the introduction has been finished,
120 : * otherwise the short-term lifetime of the circuit will blow our cover */
121 200 : client_machine->manage_circ_lifetime = 1;
122 :
123 : /* Set padding machine limits to help guard against excessive padding */
124 200 : client_machine->allowed_padding_count = INTRO_MACHINE_MAXIMUM_PADDING;
125 200 : client_machine->max_padding_percent = 1;
126 :
127 : /* Two states: START, OBFUSCATE_CIRC_SETUP (and END) */
128 200 : circpad_machine_states_init(client_machine, 2);
129 :
130 : /* For the origin-side machine, we transition to OBFUSCATE_CIRC_SETUP after
131 : * sending PADDING_NEGOTIATE, and we stay there (without sending any padding)
132 : * until we receive a STOP from the other side. */
133 200 : client_machine->states[CIRCPAD_STATE_START].
134 200 : next_state[CIRCPAD_EVENT_NONPADDING_SENT] =
135 : CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP;
136 :
137 : /* origin-side machine has no event reactions while in
138 : * CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP, so no more state transitions here. */
139 :
140 : /* The client side should never send padding, so it does not need
141 : * to specify token removal, or a histogram definition or state lengths.
142 : * That is all controlled by the middle node. */
143 :
144 : /* Register the machine */
145 200 : client_machine->machine_num = smartlist_len(machines_sl);
146 200 : circpad_register_padding_machine(client_machine, machines_sl);
147 :
148 200 : log_info(LD_CIRC,
149 : "Registered client intro point hiding padding machine (%u)",
150 : client_machine->machine_num);
151 200 : }
152 :
153 : /** Create a relay-side padding machine that aims to hide IP circuits. See
154 : * comments on the function above for more details on the workings of the
155 : * machine. */
156 : void
157 200 : circpad_machine_relay_hide_intro_circuits(smartlist_t *machines_sl)
158 : {
159 200 : circpad_machine_spec_t *relay_machine
160 200 : = tor_malloc_zero(sizeof(circpad_machine_spec_t));
161 :
162 200 : relay_machine->name = "relay_ip_circ";
163 :
164 200 : relay_machine->conditions.apply_state_mask = CIRCPAD_CIRC_OPENED;
165 :
166 : /* This is a relay-side machine */
167 200 : relay_machine->is_origin_side = 0;
168 :
169 : /* We want to negotiate END from this side after all our padding is done, so
170 : * that the origin-side machine goes into END state, and eventually closes
171 : * the circuit. */
172 200 : relay_machine->should_negotiate_end = 1;
173 :
174 : /* Set padding machine limits to help guard against excessive padding */
175 200 : relay_machine->allowed_padding_count = INTRO_MACHINE_MAXIMUM_PADDING;
176 200 : relay_machine->max_padding_percent = 1;
177 :
178 : /* Two states: START, OBFUSCATE_CIRC_SETUP (and END) */
179 200 : circpad_machine_states_init(relay_machine, 2);
180 :
181 : /* For the relay-side machine, we want to transition
182 : * START -> OBFUSCATE_CIRC_SETUP upon first non-padding
183 : * cell sent (PADDING_NEGOTIATED in this case). */
184 200 : relay_machine->states[CIRCPAD_STATE_START].
185 200 : next_state[CIRCPAD_EVENT_NONPADDING_SENT] =
186 : CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP;
187 :
188 : /* For the relay-side, we want to transition from OBFUSCATE_CIRC_SETUP to END
189 : * state when the length finishes. */
190 200 : relay_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
191 200 : next_state[CIRCPAD_EVENT_LENGTH_COUNT] = CIRCPAD_STATE_END;
192 :
193 : /* Now let's define the OBF -> OBF transitions that maintain our padding
194 : * flow:
195 : *
196 : * For the relay-side machine, we want to keep on sending padding bytes even
197 : * when nothing else happens on this circuit. */
198 200 : relay_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
199 200 : next_state[CIRCPAD_EVENT_PADDING_SENT] =
200 : CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP;
201 : /* For the relay-side machine, we need this transition so that we re-enter
202 : the state, after PADDING_NEGOTIATED is sent. Otherwise, the remove token
203 : function will disable the timer, and nothing will restart it since there
204 : is no other motion on an intro circuit. */
205 200 : relay_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
206 200 : next_state[CIRCPAD_EVENT_NONPADDING_SENT] =
207 : CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP;
208 :
209 : /* Token removal strategy for OBFUSCATE_CIRC_SETUP state: Don't
210 : * remove any tokens.
211 : *
212 : * We rely on the state length sampling and not token removal, to avoid
213 : * the mallocs required to copy the histograms for token removal,
214 : * and to avoid monotime calls needed to determine histogram
215 : * bins for token removal. */
216 200 : relay_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
217 200 : token_removal = CIRCPAD_TOKEN_REMOVAL_NONE;
218 :
219 : /* Figure out the length of the OBFUSCATE_CIRC_SETUP state so that it's
220 : * randomized. The relay side will send between INTRO_MACHINE_MINIMUM_PADDING
221 : * and INTRO_MACHINE_MAXIMUM_PADDING padding cells towards the client. */
222 200 : relay_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
223 200 : length_dist.type = CIRCPAD_DIST_UNIFORM;
224 200 : relay_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
225 200 : length_dist.param1 = INTRO_MACHINE_MINIMUM_PADDING;
226 200 : relay_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
227 200 : length_dist.param2 = INTRO_MACHINE_MAXIMUM_PADDING;
228 :
229 : /* Configure histogram */
230 200 : relay_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
231 200 : histogram_len = 2;
232 :
233 : /* For the relay-side machine we want to batch padding instantly to pretend
234 : * its an incoming directory download. So set the histogram edges tight:
235 : * (1, 10ms, infinity). */
236 200 : relay_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
237 200 : histogram_edges[0] = 1000;
238 200 : relay_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
239 200 : histogram_edges[1] = 10000;
240 :
241 : /* We put all our tokens in bin 0, which means we want 100% probability
242 : * for choosing a inter-packet delay of between 1000 and 10000 microseconds
243 : * (1 to 10ms). Since we only have 1 bin, it doesn't matter how many tokens
244 : * there are, 1000 out of 1000 is 100% */
245 200 : relay_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
246 200 : histogram[0] = 1000;
247 :
248 : /* just one bin, so setup the total tokens */
249 200 : relay_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
250 200 : histogram_total_tokens =
251 200 : relay_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].histogram[0];
252 :
253 : /* Register the machine */
254 200 : relay_machine->machine_num = smartlist_len(machines_sl);
255 200 : circpad_register_padding_machine(relay_machine, machines_sl);
256 :
257 200 : log_info(LD_CIRC,
258 : "Registered relay intro circuit hiding padding machine (%u)",
259 : relay_machine->machine_num);
260 200 : }
261 :
262 : /************************** Rendezvous-circuit machine ***********************/
263 :
264 : /** Create a client-side padding machine that aims to hide rendezvous
265 : * circuits.*/
266 : void
267 200 : circpad_machine_client_hide_rend_circuits(smartlist_t *machines_sl)
268 : {
269 200 : circpad_machine_spec_t *client_machine
270 200 : = tor_malloc_zero(sizeof(circpad_machine_spec_t));
271 :
272 200 : client_machine->name = "client_rp_circ";
273 :
274 : /* Only pad after the circuit has been built and pad to the middle */
275 200 : client_machine->conditions.apply_state_mask = CIRCPAD_CIRC_OPENED;
276 200 : client_machine->target_hopnum = 2;
277 :
278 : /* This is a client machine */
279 200 : client_machine->is_origin_side = 1;
280 :
281 : /* We only want to pad rendezvous circuits, and we want to start padding only
282 : * after the rendezvous circuit has been established.
283 : *
284 : * Following a similar argument as for intro circuits, we are aiming for
285 : * padded rendezvous circuits to blend in with the initial cell sequence of
286 : * general circuits which usually look like this:
287 : *
288 : * [EXTEND2] -> EXTENDED2 -> [EXTEND2] -> EXTENDED2 -> [BEGIN] -> CONNECTED
289 : * -> [DATA] -> [DATA] -> DATA -> DATA...(incoming cells continue)
290 : *
291 : * Whereas normal rendezvous circuits usually look like:
292 : *
293 : * [EXTEND2] -> EXTENDED2 -> [EXTEND2] -> EXTENDED2 -> [EST_REND] -> REND_EST
294 : * -> REND2 -> [BEGIN]
295 : *
296 : * This means that up to the sixth cell (in the first line), both general and
297 : * rend circuits have identical cell sequences.
298 : *
299 : * After that we want to mimic a [DATA] -> [DATA] -> DATA -> DATA sequence.
300 : *
301 : * With padding negotiation right after the REND_ESTABLISHED, the sequence
302 : * becomes:
303 : *
304 : * [EXTEND2] -> EXTENDED2 -> [EXTEND2] -> EXTENDED2 -> [EST_REND] -> REND_EST
305 : * -> [PADDING_NEGOTIATE] -> [DROP] -> PADDING_NEGOTIATED -> DROP...
306 : *
307 : * After which normal application DATA cells continue on the circuit.
308 : *
309 : * Hence this way we make rendezvous circuits look like general circuits up
310 : * till the end of the circuit setup. */
311 400 : client_machine->conditions.apply_purpose_mask =
312 200 : circpad_circ_purpose_to_mask(CIRCUIT_PURPOSE_C_REND_JOINED)|
313 200 : circpad_circ_purpose_to_mask(CIRCUIT_PURPOSE_C_REND_READY)|
314 200 : circpad_circ_purpose_to_mask(CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED);
315 :
316 : /* Set padding machine limits to help guard against excessive padding */
317 200 : client_machine->allowed_padding_count = 1;
318 200 : client_machine->max_padding_percent = 1;
319 :
320 : /* Two states: START, OBFUSCATE_CIRC_SETUP (and END) */
321 200 : circpad_machine_states_init(client_machine, 2);
322 :
323 : /* START -> OBFUSCATE_CIRC_SETUP transition upon sending the first
324 : * non-padding cell (which is PADDING_NEGOTIATE) */
325 200 : client_machine->states[CIRCPAD_STATE_START].
326 200 : next_state[CIRCPAD_EVENT_NONPADDING_SENT] =
327 : CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP;
328 :
329 : /* OBFUSCATE_CIRC_SETUP -> END transition when we send our first
330 : * padding packet and/or hit the state length (the state length is 1). */
331 200 : client_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
332 200 : next_state[CIRCPAD_EVENT_PADDING_RECV] = CIRCPAD_STATE_END;
333 200 : client_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
334 200 : next_state[CIRCPAD_EVENT_LENGTH_COUNT] = CIRCPAD_STATE_END;
335 :
336 : /* Don't use a token removal strategy since we don't want to use monotime
337 : * functions and we want to avoid mallocing histogram copies. We want
338 : * this machine to be light. */
339 200 : client_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
340 200 : token_removal = CIRCPAD_TOKEN_REMOVAL_NONE;
341 :
342 : /* Instead, to control the volume of padding (we just want to send a single
343 : * padding cell) we will use a static state length. We just want one token,
344 : * since we want to make the following pattern:
345 : * [PADDING_NEGOTIATE] -> [DROP] -> PADDING_NEGOTIATED -> DROP */
346 200 : client_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
347 200 : length_dist.type = CIRCPAD_DIST_UNIFORM;
348 200 : client_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
349 200 : length_dist.param1 = 1;
350 200 : client_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
351 200 : length_dist.param2 = 2; // rand(1,2) is always 1
352 :
353 : /* Histogram is: (0 msecs, 1 msec, infinity). We want this to be fast so
354 : * that we send our outgoing [DROP] before the PADDING_NEGOTIATED comes
355 : * back from the relay side. */
356 200 : client_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
357 200 : histogram_len = 2;
358 200 : client_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
359 200 : histogram_edges[0] = 0;
360 200 : client_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
361 200 : histogram_edges[1] = 1000;
362 :
363 : /* We want a 100% probability of choosing an inter-packet delay of
364 : * between 0 and 1ms. Since we don't use token removal,
365 : * the number of tokens does not matter. (And also, state_length
366 : * governs how many packets we send). */
367 200 : client_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
368 200 : histogram[0] = 1;
369 200 : client_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
370 200 : histogram_total_tokens = 1;
371 :
372 : /* Register the machine */
373 200 : client_machine->machine_num = smartlist_len(machines_sl);
374 200 : circpad_register_padding_machine(client_machine, machines_sl);
375 :
376 200 : log_info(LD_CIRC,
377 : "Registered client rendezvous circuit hiding padding machine (%u)",
378 : client_machine->machine_num);
379 200 : }
380 :
381 : /** Create a relay-side padding machine that aims to hide IP circuits.
382 : *
383 : * This is meant to follow the client-side machine.
384 : */
385 : void
386 200 : circpad_machine_relay_hide_rend_circuits(smartlist_t *machines_sl)
387 : {
388 200 : circpad_machine_spec_t *relay_machine
389 200 : = tor_malloc_zero(sizeof(circpad_machine_spec_t));
390 :
391 200 : relay_machine->name = "relay_rp_circ";
392 :
393 : /* Only pad after the circuit has been built and pad to the middle */
394 200 : relay_machine->conditions.min_hops = 2;
395 200 : relay_machine->conditions.apply_state_mask = CIRCPAD_CIRC_OPENED;
396 :
397 : /* This is a relay-side machine */
398 200 : relay_machine->is_origin_side = 0;
399 :
400 : /* Set padding machine limits to help guard against excessive padding */
401 200 : relay_machine->allowed_padding_count = 1;
402 200 : relay_machine->max_padding_percent = 1;
403 :
404 : /* Two states: START, OBFUSCATE_CIRC_SETUP (and END) */
405 200 : circpad_machine_states_init(relay_machine, 2);
406 :
407 : /* START -> OBFUSCATE_CIRC_SETUP transition upon sending the first
408 : * non-padding cell (which is PADDING_NEGOTIATED) */
409 200 : relay_machine->states[CIRCPAD_STATE_START].
410 200 : next_state[CIRCPAD_EVENT_NONPADDING_SENT] =
411 : CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP;
412 :
413 : /* OBFUSCATE_CIRC_SETUP -> END transition when we send our first
414 : * padding packet and/or hit the state length (the state length is 1). */
415 200 : relay_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
416 200 : next_state[CIRCPAD_EVENT_PADDING_SENT] = CIRCPAD_STATE_END;
417 200 : relay_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
418 200 : next_state[CIRCPAD_EVENT_LENGTH_COUNT] = CIRCPAD_STATE_END;
419 :
420 : /* Don't use a token removal strategy since we don't want to use monotime
421 : * functions and we want to avoid mallocing histogram copies. We want
422 : * this machine to be light. */
423 200 : relay_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
424 200 : token_removal = CIRCPAD_TOKEN_REMOVAL_NONE;
425 :
426 : /* Instead, to control the volume of padding (we just want to send a single
427 : * padding cell) we will use a static state length. We just want one token,
428 : * since we want to make the following pattern:
429 : * [PADDING_NEGOTIATE] -> [DROP] -> PADDING_NEGOTIATED -> DROP */
430 200 : relay_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
431 200 : length_dist.type = CIRCPAD_DIST_UNIFORM;
432 200 : relay_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
433 200 : length_dist.param1 = 1;
434 200 : relay_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
435 200 : length_dist.param2 = 2; // rand(1,2) is always 1
436 :
437 : /* Histogram is: (0 msecs, 1 msec, infinity). We want this to be fast so
438 : * that the outgoing DROP cell is sent immediately after the
439 : * PADDING_NEGOTIATED. */
440 200 : relay_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
441 200 : histogram_len = 2;
442 200 : relay_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
443 200 : histogram_edges[0] = 0;
444 200 : relay_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
445 200 : histogram_edges[1] = 1000;
446 :
447 : /* We want a 100% probability of choosing an inter-packet delay of
448 : * between 0 and 1ms. Since we don't use token removal,
449 : * the number of tokens does not matter. (And also, state_length
450 : * governs how many packets we send). */
451 200 : relay_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
452 200 : histogram[0] = 1;
453 200 : relay_machine->states[CIRCPAD_STATE_OBFUSCATE_CIRC_SETUP].
454 200 : histogram_total_tokens = 1;
455 :
456 : /* Register the machine */
457 200 : relay_machine->machine_num = smartlist_len(machines_sl);
458 200 : circpad_register_padding_machine(relay_machine, machines_sl);
459 :
460 200 : log_info(LD_CIRC,
461 : "Registered relay rendezvous circuit hiding padding machine (%u)",
462 : relay_machine->machine_num);
463 200 : }
|