Tor 0.4.9.8
Loading...
Searching...
No Matches
onion.c
Go to the documentation of this file.
1/* Copyright (c) 2001 Matej Pfajfar.
2 * Copyright (c) 2001-2004, Roger Dingledine.
3 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4 * Copyright (c) 2007-2021, The Tor Project, Inc. */
5/* See LICENSE for licensing information */
6
7/**
8 * \file onion.c
9 * \brief Functions to queue create cells,
10 * and parse and create the CREATE cell and its allies.
11 *
12 * This module has a few functions, all related to the CREATE/CREATED
13 * handshake that we use on links in order to create a circuit, and the
14 * related EXTEND/EXTENDED handshake that we use over circuits in order to
15 * extend them an additional hop.
16 *
17 * Clients invoke these functions when creating or extending a circuit,
18 * from circuitbuild.c.
19 *
20 * Relays invoke these functions when they receive a CREATE or EXTEND
21 * cell in command.c or relay.c, in order to queue the pending request.
22 * They also invoke them from cpuworker.c, which handles dispatching
23 * onionskin requests to different worker threads.
24 *
25 * <br>
26 *
27 * This module also handles:
28 * <ul>
29 * <li> Queueing incoming onionskins on the relay side before passing
30 * them to worker threads.
31 * <li>Expiring onionskins on the relay side if they have waited for
32 * too long.
33 * <li>Packaging private keys on the server side in order to pass
34 * them to worker threads.
35 * <li>Encoding and decoding CREATE, CREATED, CREATE2, and CREATED2 cells.
36 * <li>Encoding and decodign EXTEND, EXTENDED, EXTEND2, and EXTENDED2
37 * relay cells.
38 * </ul>
39 **/
40
41#include "core/or/or.h"
42
43#include "app/config/config.h"
47#include "core/or/onion.h"
49
50#include "core/or/cell_st.h"
51
52// trunnel
53#include "trunnel/ed25519_cert.h"
54
55/** Helper: return 0 if <b>cell</b> appears valid, -1 otherwise. If
56 * <b>unknown_ok</b> is true, allow cells with handshake types we don't
57 * recognize. */
58static int
59check_create_cell(const create_cell_t *cell, int unknown_ok)
60{
61 switch (cell->cell_type) {
62 case CELL_CREATE:
63 return -1;
64 case CELL_CREATE_FAST:
65 if (cell->handshake_type != ONION_HANDSHAKE_TYPE_FAST)
66 return -1;
67 break;
68 case CELL_CREATE2:
69 break;
70 default:
71 return -1;
72 }
73
74 switch (cell->handshake_type) {
75 case ONION_HANDSHAKE_TYPE_TAP:
76 return -1;
77 case ONION_HANDSHAKE_TYPE_FAST:
78 if (cell->handshake_len != CREATE_FAST_LEN)
79 return -1;
80 break;
81 case ONION_HANDSHAKE_TYPE_NTOR:
83 return -1;
84 break;
85 case ONION_HANDSHAKE_TYPE_NTOR_V3:
86 /* ntor v3 has variable length fields that are checked
87 * elsewhere. Fall through to always valid here. */
88 break;
89 default:
90 if (! unknown_ok)
91 return -1;
92 }
93
94 return 0;
95}
96
97/** Write the various parameters into the create cell. Separate from
98 * create_cell_parse() to make unit testing easier.
99 */
100void
101create_cell_init(create_cell_t *cell_out, uint8_t cell_type,
102 uint16_t handshake_type, uint16_t handshake_len,
103 const uint8_t *onionskin)
104{
105 memset(cell_out, 0, sizeof(*cell_out));
106
107 cell_out->cell_type = cell_type;
108 cell_out->handshake_type = handshake_type;
109 cell_out->handshake_len = handshake_len;
110 memcpy(cell_out->onionskin, onionskin, handshake_len);
111}
112
113/** Helper: parse the CREATE2 payload at <b>p</b>, which could be up to
114 * <b>p_len</b> bytes long, and use it to fill the fields of
115 * <b>cell_out</b>. Return 0 on success and -1 on failure.
116 *
117 * Note that part of the body of an EXTEND2 cell is a CREATE2 payload, so
118 * this function is also used for parsing those.
119 */
120static int
121parse_create2_payload(create_cell_t *cell_out, const uint8_t *p, size_t p_len)
122{
123 uint16_t handshake_type, handshake_len;
124
125 if (p_len < 4)
126 return -1;
127
128 handshake_type = ntohs(get_uint16(p));
129 handshake_len = ntohs(get_uint16(p+2));
130
131 if (handshake_len > MAX_CREATE_LEN || handshake_len > p_len - 4)
132 return -1;
133 if (handshake_type == ONION_HANDSHAKE_TYPE_FAST)
134 return -1;
135
136 create_cell_init(cell_out, CELL_CREATE2, handshake_type, handshake_len,
137 p+4);
138 return 0;
139}
140
141/** Magic string which, in a CREATE or EXTEND cell, indicates that a seeming
142 * TAP payload is really an ntor payload. We'd do away with this if every
143 * relay supported EXTEND2, but we want to be able to extend from A to B with
144 * ntor even when A doesn't understand EXTEND2 and so can't generate a
145 * CREATE2 cell.
146 **/
147#define NTOR_CREATE_MAGIC "ntorNTORntorNTOR"
148
149/** Parse a CREATE, CREATE_FAST, or CREATE2 cell from <b>cell_in</b> into
150 * <b>cell_out</b>. Return 0 on success, -1 on failure. (We reject some
151 * syntactically valid CREATE2 cells that we can't generate or react to.) */
152int
153create_cell_parse(create_cell_t *cell_out, const cell_t *cell_in)
154{
155 switch (cell_in->command) {
156 case CELL_CREATE:
157 return -1;
158 case CELL_CREATE_FAST:
159 create_cell_init(cell_out, CELL_CREATE_FAST, ONION_HANDSHAKE_TYPE_FAST,
160 CREATE_FAST_LEN, cell_in->payload);
161 break;
162 case CELL_CREATE2:
163 if (parse_create2_payload(cell_out, cell_in->payload,
165 return -1;
166 break;
167 default:
168 return -1;
169 }
170
171 return check_create_cell(cell_out, 0);
172}
173
174/** Helper: return 0 if <b>cell</b> appears valid, -1 otherwise. */
175static int
177{
178 switch (cell->cell_type) {
179 case CELL_CREATED:
180 return -1;
181 case CELL_CREATED_FAST:
182 if (cell->handshake_len != CREATED_FAST_LEN)
183 return -1;
184 break;
185 case CELL_CREATED2:
186 /* Need to remove 2 bytes because first 2 bytes of the payload is the
187 * handshake_len value and then the payload. */
188 if (cell->handshake_len > (RELAY_PAYLOAD_SIZE_MAX - 2))
189 return -1;
190 break;
191 }
192
193 return 0;
194}
195
196/** Parse a CREATED, CREATED_FAST, or CREATED2 cell from <b>cell_in</b> into
197 * <b>cell_out</b>. Return 0 on success, -1 on failure. */
198int
199created_cell_parse(created_cell_t *cell_out, const cell_t *cell_in)
200{
201 memset(cell_out, 0, sizeof(*cell_out));
202
203 switch (cell_in->command) {
204 case CELL_CREATED:
205 return -1;
206 case CELL_CREATED_FAST:
207 cell_out->cell_type = CELL_CREATED_FAST;
208 cell_out->handshake_len = CREATED_FAST_LEN;
209 memcpy(cell_out->reply, cell_in->payload, CREATED_FAST_LEN);
210 break;
211 case CELL_CREATED2:
212 {
213 const uint8_t *p = cell_in->payload;
214 cell_out->cell_type = CELL_CREATED2;
215 cell_out->handshake_len = ntohs(get_uint16(p));
216 if (cell_out->handshake_len > MAX_CREATED_LEN)
217 return -1;
218 memcpy(cell_out->reply, p+2, cell_out->handshake_len);
219 break;
220 }
221 }
222
223 return check_created_cell(cell_out);
224}
225
226/** Helper: return 0 if <b>cell</b> appears valid, -1 otherwise. */
227static int
229{
230 const bool is_extend2 = (cell->cell_type == RELAY_COMMAND_EXTEND2);
231
232 if (tor_digest_is_zero((const char*)cell->node_id))
233 return -1;
234 if (!tor_addr_port_is_valid_ap(&cell->orport_ipv4, 0)) {
235 /* EXTEND cells must have an IPv4 address. */
236 if (!is_extend2) {
237 return -1;
238 }
239 /* EXTEND2 cells must have at least one IP address.
240 * It can be IPv4 or IPv6. */
241 if (!tor_addr_port_is_valid_ap(&cell->orport_ipv6, 0)) {
242 return -1;
243 }
244 }
245 if (cell->create_cell.cell_type == CELL_CREATE) {
246 return -1;
247 } else if (cell->create_cell.cell_type == CELL_CREATE2) {
248 if (cell->cell_type != RELAY_COMMAND_EXTEND2)
249 return -1;
250 } else {
251 /* In particular, no CREATE_FAST cells are allowed */
252 return -1;
253 }
254 if (cell->create_cell.handshake_type == ONION_HANDSHAKE_TYPE_FAST ||
255 cell->create_cell.handshake_type == ONION_HANDSHAKE_TYPE_TAP)
256 return -1;
257
258 return check_create_cell(&cell->create_cell, 1);
259}
260
261static int
262create_cell_from_create2_cell_body(create_cell_t *cell_out,
263 const create2_cell_body_t *cell)
264{
265 tor_assert(cell_out);
266 tor_assert(cell);
267 memset(cell_out, 0, sizeof(create_cell_t));
268 if (BUG(cell->handshake_len > sizeof(cell_out->onionskin))) {
269 /* This should be impossible because there just isn't enough room in the
270 * input cell to make the handshake_len this large and provide a
271 * handshake_data to match. */
272 return -1;
273 }
274
275 cell_out->cell_type = CELL_CREATE2;
276 cell_out->handshake_type = cell->handshake_type;
277 cell_out->handshake_len = cell->handshake_len;
278 memcpy(cell_out->onionskin,
279 create2_cell_body_getconstarray_handshake_data(cell),
280 cell->handshake_len);
281 return 0;
282}
283
284static int
285extend_cell_from_extend2_cell_body(extend_cell_t *cell_out,
286 const extend2_cell_body_t *cell)
287{
288 tor_assert(cell_out);
289 tor_assert(cell);
290 int found_ipv4 = 0, found_ipv6 = 0, found_rsa_id = 0, found_ed_id = 0;
291 memset(cell_out, 0, sizeof(*cell_out));
292 tor_addr_make_unspec(&cell_out->orport_ipv4.addr);
293 tor_addr_make_unspec(&cell_out->orport_ipv6.addr);
294 cell_out->cell_type = RELAY_COMMAND_EXTEND2;
295
296 unsigned i;
297 for (i = 0; i < cell->n_spec; ++i) {
298 const link_specifier_t *ls = extend2_cell_body_getconst_ls(cell, i);
299 switch (ls->ls_type) {
300 case LS_IPV4:
301 if (found_ipv4)
302 continue;
303 found_ipv4 = 1;
304 tor_addr_from_ipv4h(&cell_out->orport_ipv4.addr, ls->un_ipv4_addr);
305 cell_out->orport_ipv4.port = ls->un_ipv4_port;
306 break;
307 case LS_IPV6:
308 if (found_ipv6)
309 continue;
310 found_ipv6 = 1;
312 ls->un_ipv6_addr);
313 cell_out->orport_ipv6.port = ls->un_ipv6_port;
314 break;
315 case LS_LEGACY_ID:
316 if (found_rsa_id)
317 return -1;
318 found_rsa_id = 1;
319 memcpy(cell_out->node_id, ls->un_legacy_id, 20);
320 break;
321 case LS_ED25519_ID:
322 if (found_ed_id)
323 return -1;
324 found_ed_id = 1;
325 memcpy(cell_out->ed_pubkey.pubkey, ls->un_ed25519_id, 32);
326 break;
327 default:
328 /* Ignore this, whatever it is. */
329 break;
330 }
331 }
332
333 /* EXTEND2 cells must have an RSA ID */
334 if (!found_rsa_id)
335 return -1;
336
337 /* EXTEND2 cells must have at least one IP address */
338 if (!found_ipv4 && !found_ipv6)
339 return -1;
340
341 return create_cell_from_create2_cell_body(&cell_out->create_cell,
342 cell->create2);
343}
344
345/** Parse an EXTEND or EXTEND2 cell (according to <b>command</b>) from the
346 * <b>payload_length</b> bytes of <b>payload</b> into <b>cell_out</b>. Return
347 * 0 on success, -1 on failure. */
348MOCK_IMPL(int,
350 const uint8_t command,
351 const uint8_t *payload,
352 size_t payload_length))
353{
354
355 tor_assert(cell_out);
356 tor_assert(payload);
357
358 if (payload_length > RELAY_PAYLOAD_SIZE_MAX)
359 return -1;
360
361 switch (command) {
362 case RELAY_COMMAND_EXTEND:
363 return -1;
364 break;
365 case RELAY_COMMAND_EXTEND2:
366 {
367 extend2_cell_body_t *cell = NULL;
368 if (extend2_cell_body_parse(&cell, payload, payload_length) < 0 ||
369 cell == NULL) {
370 if (cell)
371 extend2_cell_body_free(cell);
372 return -1;
373 }
374 int r = extend_cell_from_extend2_cell_body(cell_out, cell);
375 extend2_cell_body_free(cell);
376 if (r < 0)
377 return r;
378 }
379 break;
380 default:
381 return -1;
382 }
383
384 return check_extend_cell(cell_out);
385}
386
387/** Helper: return 0 if <b>cell</b> appears valid, -1 otherwise. */
388static int
390{
391 tor_assert(cell);
392 if (cell->created_cell.cell_type == CELL_CREATED) {
393 if (cell->cell_type != RELAY_COMMAND_EXTENDED)
394 return -1;
395 } else if (cell->created_cell.cell_type == CELL_CREATED2) {
396 if (cell->cell_type != RELAY_COMMAND_EXTENDED2)
397 return -1;
398 } else {
399 return -1;
400 }
401
402 return check_created_cell(&cell->created_cell);
403}
404
405/** Parse an EXTENDED or EXTENDED2 cell (according to <b>command</b>) from the
406 * <b>payload_len</b> bytes of <b>payload</b> into <b>cell_out</b>. Return
407 * 0 on success, -1 on failure. */
408int
410 const uint8_t command, const uint8_t *payload,
411 size_t payload_len)
412{
413 tor_assert(cell_out);
414 tor_assert(payload);
415
416 memset(cell_out, 0, sizeof(*cell_out));
417 if (payload_len > RELAY_PAYLOAD_SIZE_MAX)
418 return -1;
419
420 switch (command) {
421 case RELAY_COMMAND_EXTENDED:
422 return -1;
423 case RELAY_COMMAND_EXTENDED2:
424 {
425 if (payload_len < 2) {
426 // Prevent underflow below.
427 return -1;
428 }
429 cell_out->cell_type = RELAY_COMMAND_EXTENDED2;
430 cell_out->created_cell.cell_type = CELL_CREATED2;
431 cell_out->created_cell.handshake_len = ntohs(get_uint16(payload));
433 cell_out->created_cell.handshake_len > payload_len - 2)
434 return -1;
435 memcpy(cell_out->created_cell.reply, payload+2,
436 cell_out->created_cell.handshake_len);
437 }
438 break;
439 default:
440 return -1;
441 }
442
443 return check_extended_cell(cell_out);
444}
445
446/** Fill <b>cell_out</b> with a correctly formatted version of the
447 * CREATE{,_FAST,2} cell in <b>cell_in</b>. Return 0 on success, -1 on
448 * failure. This is a cell we didn't originate if <b>relayed</b> is true. */
449static int
451 int relayed)
452{
453 uint8_t *p;
454 size_t space;
455 if (check_create_cell(cell_in, relayed) < 0)
456 return -1;
457
458 memset(cell_out->payload, 0, sizeof(cell_out->payload));
459 cell_out->command = cell_in->cell_type;
460
461 p = cell_out->payload;
462 space = sizeof(cell_out->payload);
463
464 switch (cell_in->cell_type) {
465 case CELL_CREATE:
466 if (BUG(cell_in->handshake_type == ONION_HANDSHAKE_TYPE_NTOR_V3)) {
467 log_warn(LD_BUG, "Create cells cannot contain ntorv3.");
468 return -1;
469 }
470
471 if (cell_in->handshake_type == ONION_HANDSHAKE_TYPE_NTOR) {
472 memcpy(p, NTOR_CREATE_MAGIC, 16);
473 p += 16;
474 space -= 16;
475 }
476 FALLTHROUGH;
477 case CELL_CREATE_FAST:
478 tor_assert(cell_in->handshake_len <= space);
479 memcpy(p, cell_in->onionskin, cell_in->handshake_len);
480 break;
481 case CELL_CREATE2:
482 tor_assert(cell_in->handshake_len <= sizeof(cell_out->payload)-4);
483 set_uint16(cell_out->payload, htons(cell_in->handshake_type));
484 set_uint16(cell_out->payload+2, htons(cell_in->handshake_len));
485 memcpy(cell_out->payload + 4, cell_in->onionskin, cell_in->handshake_len);
486 break;
487 default:
488 return -1;
489 }
490
491 return 0;
492}
493
494int
495create_cell_format(cell_t *cell_out, const create_cell_t *cell_in)
496{
497 return create_cell_format_impl(cell_out, cell_in, 0);
498}
499
500int
501create_cell_format_relayed(cell_t *cell_out, const create_cell_t *cell_in)
502{
503 return create_cell_format_impl(cell_out, cell_in, 1);
504}
505
506/** Fill <b>cell_out</b> with a correctly formatted version of the
507 * CREATED{,_FAST,2} cell in <b>cell_in</b>. Return 0 on success, -1 on
508 * failure. */
509int
510created_cell_format(cell_t *cell_out, const created_cell_t *cell_in)
511{
512 if (check_created_cell(cell_in) < 0)
513 return -1;
514
515 memset(cell_out->payload, 0, sizeof(cell_out->payload));
516 cell_out->command = cell_in->cell_type;
517
518 switch (cell_in->cell_type) {
519 case CELL_CREATED:
520 case CELL_CREATED_FAST:
521 tor_assert(cell_in->handshake_len <= sizeof(cell_out->payload));
522 memcpy(cell_out->payload, cell_in->reply, cell_in->handshake_len);
523 break;
524 case CELL_CREATED2:
525 tor_assert(cell_in->handshake_len <= sizeof(cell_out->payload)-2);
526 set_uint16(cell_out->payload, htons(cell_in->handshake_len));
527 memcpy(cell_out->payload + 2, cell_in->reply, cell_in->handshake_len);
528 break;
529 default:
530 return -1;
531 }
532 return 0;
533}
534
535/** Return true iff we are configured (by torrc or by the networkstatus
536 * parameters) to use Ed25519 identities in our Extend2 cells. */
537static int
539 const or_options_t *options)
540{
541 if (options->ExtendByEd25519ID != -1)
542 return options->ExtendByEd25519ID; /* The user has an opinion. */
543
544 return (int) networkstatus_get_param(ns, "ExtendByEd25519ID",
545 0 /* default */,
546 0 /* min */,
547 1 /*max*/);
548}
549
550/** Format the EXTEND{,2} cell in <b>cell_in</b>, storing its relay payload in
551 * <b>payload_out</b>, the number of bytes used in *<b>len_out</b>, and the
552 * relay command in *<b>command_out</b>. The <b>payload_out</b> must have
553 * RELAY_PAYLOAD_SIZE_MAX bytes available.
554 *
555 * Return 0 on success, -1 on failure. */
556int
557extend_cell_format(uint8_t *command_out, uint16_t *len_out,
558 uint8_t *payload_out, const extend_cell_t *cell_in)
559{
560 uint8_t *p;
561 if (check_extend_cell(cell_in) < 0)
562 return -1;
563
564 p = payload_out;
565
566 memset(p, 0, RELAY_PAYLOAD_SIZE_MAX);
567
568 switch (cell_in->cell_type) {
569 case RELAY_COMMAND_EXTEND:
570 return -1;
571 case RELAY_COMMAND_EXTEND2:
572 {
573 uint8_t n_specifiers = 1;
574 *command_out = RELAY_COMMAND_EXTEND2;
575 extend2_cell_body_t *cell = extend2_cell_body_new();
576 link_specifier_t *ls;
577 if (tor_addr_port_is_valid_ap(&cell_in->orport_ipv4, 0)) {
578 /* Maybe IPv4 specifier first. */
579 ++n_specifiers;
580 ls = link_specifier_new();
581 extend2_cell_body_add_ls(cell, ls);
582 ls->ls_type = LS_IPV4;
583 ls->ls_len = 6;
584 ls->un_ipv4_addr = tor_addr_to_ipv4h(&cell_in->orport_ipv4.addr);
585 ls->un_ipv4_port = cell_in->orport_ipv4.port;
586 }
587 {
588 /* Then RSA id */
589 ls = link_specifier_new();
590 extend2_cell_body_add_ls(cell, ls);
591 ls->ls_type = LS_LEGACY_ID;
592 ls->ls_len = DIGEST_LEN;
593 memcpy(ls->un_legacy_id, cell_in->node_id, DIGEST_LEN);
594 }
597 /* Then, maybe, the ed25519 id! */
598 ++n_specifiers;
599 ls = link_specifier_new();
600 extend2_cell_body_add_ls(cell, ls);
601 ls->ls_type = LS_ED25519_ID;
602 ls->ls_len = 32;
603 memcpy(ls->un_ed25519_id, cell_in->ed_pubkey.pubkey, 32);
604 }
605 if (tor_addr_port_is_valid_ap(&cell_in->orport_ipv6, 0)) {
606 /* Then maybe IPv6 specifier. */
607 ++n_specifiers;
608 ls = link_specifier_new();
609 extend2_cell_body_add_ls(cell, ls);
610 ls->ls_type = LS_IPV6;
611 ls->ls_len = 18;
612 tor_addr_copy_ipv6_bytes(ls->un_ipv6_addr,
613 &cell_in->orport_ipv6.addr);
614 ls->un_ipv6_port = cell_in->orport_ipv6.port;
615 }
616 cell->n_spec = n_specifiers;
617
618 /* Now, the handshake */
619 cell->create2 = create2_cell_body_new();
620 cell->create2->handshake_type = cell_in->create_cell.handshake_type;
621 cell->create2->handshake_len = cell_in->create_cell.handshake_len;
622 create2_cell_body_setlen_handshake_data(cell->create2,
623 cell_in->create_cell.handshake_len);
624 memcpy(create2_cell_body_getarray_handshake_data(cell->create2),
625 cell_in->create_cell.onionskin,
626 cell_in->create_cell.handshake_len);
627
628 ssize_t len_encoded = extend2_cell_body_encode(
629 payload_out, RELAY_PAYLOAD_SIZE_MAX,
630 cell);
631 extend2_cell_body_free(cell);
632 if (len_encoded < 0 || len_encoded > UINT16_MAX)
633 return -1;
634 *len_out = (uint16_t) len_encoded;
635 }
636 break;
637 default:
638 return -1;
639 }
640
641 return 0;
642}
643
644/** Format the EXTENDED{,2} cell in <b>cell_in</b>, storing its relay payload
645 * in <b>payload_out</b>, the number of bytes used in *<b>len_out</b>, and the
646 * relay command in *<b>command_out</b>. The <b>payload_out</b> must have
647 * RELAY_PAYLOAD_SIZE_MAX bytes available.
648 *
649 * Return 0 on success, -1 on failure. */
650int
651extended_cell_format(uint8_t *command_out, uint16_t *len_out,
652 uint8_t *payload_out, const extended_cell_t *cell_in)
653{
654 uint8_t *p;
655 if (check_extended_cell(cell_in) < 0)
656 return -1;
657
658 p = payload_out;
659 memset(p, 0, RELAY_PAYLOAD_SIZE_MAX);
660
661 switch (cell_in->cell_type) {
662 case RELAY_COMMAND_EXTENDED:
663 return -1;
664 case RELAY_COMMAND_EXTENDED2:
665 {
666 *command_out = RELAY_COMMAND_EXTENDED2;
667 *len_out = 2 + cell_in->created_cell.handshake_len;
668 set_uint16(payload_out, htons(cell_in->created_cell.handshake_len));
669 /* We are about to write the handshake payload into the cell which is
670 * RELAY_PAYLOAD_SIZE_MAX minus the two bytes of the HLEN value. */
672 return -1;
673 }
674 memcpy(payload_out+2, cell_in->created_cell.reply,
675 cell_in->created_cell.handshake_len);
676 }
677 break;
678 default:
679 return -1;
680 }
681
682 return 0;
683}
void tor_addr_make_unspec(tor_addr_t *a)
Definition address.c:225
void tor_addr_copy_ipv6_bytes(uint8_t *dest, const tor_addr_t *src)
Definition address.c:920
void tor_addr_from_ipv6_bytes(tor_addr_t *dest, const uint8_t *ipv6_bytes)
Definition address.c:900
static uint32_t tor_addr_to_ipv4h(const tor_addr_t *a)
Definition address.h:160
#define tor_addr_from_ipv4h(dest, v4addr)
Definition address.h:327
static void set_uint16(void *cp, uint16_t v)
Definition bytes.h:78
static uint16_t get_uint16(const void *cp)
Definition bytes.h:42
Fixed-size cell structure.
const or_options_t * get_options(void)
Definition config.c:948
tor_cmdline_mode_t command
Definition config.c:2478
Header file for config.c.
int ed25519_public_key_is_zero(const ed25519_public_key_t *pubkey)
#define DIGEST_LEN
#define LD_BUG
Definition log.h:86
int32_t networkstatus_get_param(const networkstatus_t *ns, const char *param_name, int32_t default_val, int32_t min_val, int32_t max_val)
Header file for networkstatus.c.
static int check_created_cell(const created_cell_t *cell)
Definition onion.c:176
static int should_include_ed25519_id_extend_cells(const networkstatus_t *ns, const or_options_t *options)
Definition onion.c:538
static int parse_create2_payload(create_cell_t *cell_out, const uint8_t *p, size_t p_len)
Definition onion.c:121
#define NTOR_CREATE_MAGIC
Definition onion.c:147
static int check_create_cell(const create_cell_t *cell, int unknown_ok)
Definition onion.c:59
static int create_cell_format_impl(cell_t *cell_out, const create_cell_t *cell_in, int relayed)
Definition onion.c:450
int created_cell_parse(created_cell_t *cell_out, const cell_t *cell_in)
Definition onion.c:199
void create_cell_init(create_cell_t *cell_out, uint8_t cell_type, uint16_t handshake_type, uint16_t handshake_len, const uint8_t *onionskin)
Definition onion.c:101
static int check_extend_cell(const extend_cell_t *cell)
Definition onion.c:228
int create_cell_parse(create_cell_t *cell_out, const cell_t *cell_in)
Definition onion.c:153
int extend_cell_parse(extend_cell_t *cell_out, const uint8_t command, const uint8_t *payload, size_t payload_length)
Definition onion.c:352
int created_cell_format(cell_t *cell_out, const created_cell_t *cell_in)
Definition onion.c:510
int extended_cell_format(uint8_t *command_out, uint16_t *len_out, uint8_t *payload_out, const extended_cell_t *cell_in)
Definition onion.c:651
int extended_cell_parse(extended_cell_t *cell_out, const uint8_t command, const uint8_t *payload, size_t payload_len)
Definition onion.c:409
int extend_cell_format(uint8_t *command_out, uint16_t *len_out, uint8_t *payload_out, const extend_cell_t *cell_in)
Definition onion.c:557
static int check_extended_cell(const extended_cell_t *cell)
Definition onion.c:389
Header file for onion.c.
Header file for onion_crypto.c.
Header file for onion_fast.c.
Header for onion_ntor.c.
#define NTOR_ONIONSKIN_LEN
Definition onion_ntor.h:23
Master header file for Tor-specific functionality.
#define CELL_PAYLOAD_SIZE
Definition or.h:529
#define RELAY_PAYLOAD_SIZE_MAX
Definition or.h:576
uint8_t payload[CELL_PAYLOAD_SIZE]
Definition cell_st.h:21
uint8_t command
Definition cell_st.h:19
uint16_t handshake_len
Definition onion.h:33
uint16_t handshake_type
Definition onion.h:31
uint8_t onionskin[MAX_CREATE_LEN]
Definition onion.h:35
uint8_t cell_type
Definition onion.h:29
uint16_t handshake_len
Definition onion.h:43
uint8_t reply[MAX_CREATED_LEN]
Definition onion.h:45
uint8_t cell_type
Definition onion.h:41
tor_addr_port_t orport_ipv4
Definition onion.h:53
create_cell_t create_cell
Definition onion.h:63
struct ed25519_public_key_t ed_pubkey
Definition onion.h:59
uint8_t node_id[DIGEST_LEN]
Definition onion.h:57
tor_addr_port_t orport_ipv6
Definition onion.h:55
uint8_t cell_type
Definition onion.h:51
created_cell_t created_cell
Definition onion.h:71
uint8_t cell_type
Definition onion.h:69
#define MOCK_IMPL(rv, funcname, arglist)
#define tor_assert(expr)
Definition util_bug.h:103
int tor_digest_is_zero(const char *digest)
Definition util_string.c:98