Tor 0.4.9.1-alpha-dev
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 > CELL_PAYLOAD_SIZE - 4 || 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 if (cell->handshake_len > RELAY_PAYLOAD_SIZE-2)
187 return -1;
188 break;
189 }
190
191 return 0;
192}
193
194/** Parse a CREATED, CREATED_FAST, or CREATED2 cell from <b>cell_in</b> into
195 * <b>cell_out</b>. Return 0 on success, -1 on failure. */
196int
197created_cell_parse(created_cell_t *cell_out, const cell_t *cell_in)
198{
199 memset(cell_out, 0, sizeof(*cell_out));
200
201 switch (cell_in->command) {
202 case CELL_CREATED:
203 return -1;
204 case CELL_CREATED_FAST:
205 cell_out->cell_type = CELL_CREATED_FAST;
206 cell_out->handshake_len = CREATED_FAST_LEN;
207 memcpy(cell_out->reply, cell_in->payload, CREATED_FAST_LEN);
208 break;
209 case CELL_CREATED2:
210 {
211 const uint8_t *p = cell_in->payload;
212 cell_out->cell_type = CELL_CREATED2;
213 cell_out->handshake_len = ntohs(get_uint16(p));
214 if (cell_out->handshake_len > CELL_PAYLOAD_SIZE - 2)
215 return -1;
216 memcpy(cell_out->reply, p+2, cell_out->handshake_len);
217 break;
218 }
219 }
220
221 return check_created_cell(cell_out);
222}
223
224/** Helper: return 0 if <b>cell</b> appears valid, -1 otherwise. */
225static int
227{
228 const bool is_extend2 = (cell->cell_type == RELAY_COMMAND_EXTEND2);
229
230 if (tor_digest_is_zero((const char*)cell->node_id))
231 return -1;
232 if (!tor_addr_port_is_valid_ap(&cell->orport_ipv4, 0)) {
233 /* EXTEND cells must have an IPv4 address. */
234 if (!is_extend2) {
235 return -1;
236 }
237 /* EXTEND2 cells must have at least one IP address.
238 * It can be IPv4 or IPv6. */
239 if (!tor_addr_port_is_valid_ap(&cell->orport_ipv6, 0)) {
240 return -1;
241 }
242 }
243 if (cell->create_cell.cell_type == CELL_CREATE) {
244 return -1;
245 } else if (cell->create_cell.cell_type == CELL_CREATE2) {
246 if (cell->cell_type != RELAY_COMMAND_EXTEND2)
247 return -1;
248 } else {
249 /* In particular, no CREATE_FAST cells are allowed */
250 return -1;
251 }
252 if (cell->create_cell.handshake_type == ONION_HANDSHAKE_TYPE_FAST ||
253 cell->create_cell.handshake_type == ONION_HANDSHAKE_TYPE_TAP)
254 return -1;
255
256 return check_create_cell(&cell->create_cell, 1);
257}
258
259static int
260create_cell_from_create2_cell_body(create_cell_t *cell_out,
261 const create2_cell_body_t *cell)
262{
263 tor_assert(cell_out);
264 tor_assert(cell);
265 memset(cell_out, 0, sizeof(create_cell_t));
266 if (BUG(cell->handshake_len > sizeof(cell_out->onionskin))) {
267 /* This should be impossible because there just isn't enough room in the
268 * input cell to make the handshake_len this large and provide a
269 * handshake_data to match. */
270 return -1;
271 }
272
273 cell_out->cell_type = CELL_CREATE2;
274 cell_out->handshake_type = cell->handshake_type;
275 cell_out->handshake_len = cell->handshake_len;
276 memcpy(cell_out->onionskin,
277 create2_cell_body_getconstarray_handshake_data(cell),
278 cell->handshake_len);
279 return 0;
280}
281
282static int
283extend_cell_from_extend2_cell_body(extend_cell_t *cell_out,
284 const extend2_cell_body_t *cell)
285{
286 tor_assert(cell_out);
287 tor_assert(cell);
288 int found_ipv4 = 0, found_ipv6 = 0, found_rsa_id = 0, found_ed_id = 0;
289 memset(cell_out, 0, sizeof(*cell_out));
290 tor_addr_make_unspec(&cell_out->orport_ipv4.addr);
291 tor_addr_make_unspec(&cell_out->orport_ipv6.addr);
292 cell_out->cell_type = RELAY_COMMAND_EXTEND2;
293
294 unsigned i;
295 for (i = 0; i < cell->n_spec; ++i) {
296 const link_specifier_t *ls = extend2_cell_body_getconst_ls(cell, i);
297 switch (ls->ls_type) {
298 case LS_IPV4:
299 if (found_ipv4)
300 continue;
301 found_ipv4 = 1;
302 tor_addr_from_ipv4h(&cell_out->orport_ipv4.addr, ls->un_ipv4_addr);
303 cell_out->orport_ipv4.port = ls->un_ipv4_port;
304 break;
305 case LS_IPV6:
306 if (found_ipv6)
307 continue;
308 found_ipv6 = 1;
310 ls->un_ipv6_addr);
311 cell_out->orport_ipv6.port = ls->un_ipv6_port;
312 break;
313 case LS_LEGACY_ID:
314 if (found_rsa_id)
315 return -1;
316 found_rsa_id = 1;
317 memcpy(cell_out->node_id, ls->un_legacy_id, 20);
318 break;
319 case LS_ED25519_ID:
320 if (found_ed_id)
321 return -1;
322 found_ed_id = 1;
323 memcpy(cell_out->ed_pubkey.pubkey, ls->un_ed25519_id, 32);
324 break;
325 default:
326 /* Ignore this, whatever it is. */
327 break;
328 }
329 }
330
331 /* EXTEND2 cells must have an RSA ID */
332 if (!found_rsa_id)
333 return -1;
334
335 /* EXTEND2 cells must have at least one IP address */
336 if (!found_ipv4 && !found_ipv6)
337 return -1;
338
339 return create_cell_from_create2_cell_body(&cell_out->create_cell,
340 cell->create2);
341}
342
343/** Parse an EXTEND or EXTEND2 cell (according to <b>command</b>) from the
344 * <b>payload_length</b> bytes of <b>payload</b> into <b>cell_out</b>. Return
345 * 0 on success, -1 on failure. */
346MOCK_IMPL(int,
348 const uint8_t command,
349 const uint8_t *payload,
350 size_t payload_length))
351{
352
353 tor_assert(cell_out);
354 tor_assert(payload);
355
356 if (payload_length > RELAY_PAYLOAD_SIZE)
357 return -1;
358
359 switch (command) {
360 case RELAY_COMMAND_EXTEND:
361 return -1;
362 break;
363 case RELAY_COMMAND_EXTEND2:
364 {
365 extend2_cell_body_t *cell = NULL;
366 if (extend2_cell_body_parse(&cell, payload, payload_length) < 0 ||
367 cell == NULL) {
368 if (cell)
369 extend2_cell_body_free(cell);
370 return -1;
371 }
372 int r = extend_cell_from_extend2_cell_body(cell_out, cell);
373 extend2_cell_body_free(cell);
374 if (r < 0)
375 return r;
376 }
377 break;
378 default:
379 return -1;
380 }
381
382 return check_extend_cell(cell_out);
383}
384
385/** Helper: return 0 if <b>cell</b> appears valid, -1 otherwise. */
386static int
388{
389 tor_assert(cell);
390 if (cell->created_cell.cell_type == CELL_CREATED) {
391 if (cell->cell_type != RELAY_COMMAND_EXTENDED)
392 return -1;
393 } else if (cell->created_cell.cell_type == CELL_CREATED2) {
394 if (cell->cell_type != RELAY_COMMAND_EXTENDED2)
395 return -1;
396 } else {
397 return -1;
398 }
399
400 return check_created_cell(&cell->created_cell);
401}
402
403/** Parse an EXTENDED or EXTENDED2 cell (according to <b>command</b>) from the
404 * <b>payload_length</b> bytes of <b>payload</b> into <b>cell_out</b>. Return
405 * 0 on success, -1 on failure. */
406int
408 const uint8_t command, const uint8_t *payload,
409 size_t payload_len)
410{
411 tor_assert(cell_out);
412 tor_assert(payload);
413
414 memset(cell_out, 0, sizeof(*cell_out));
415 if (payload_len > RELAY_PAYLOAD_SIZE)
416 return -1;
417
418 switch (command) {
419 case RELAY_COMMAND_EXTENDED:
420 return -1;
421 case RELAY_COMMAND_EXTENDED2:
422 {
423 cell_out->cell_type = RELAY_COMMAND_EXTENDED2;
424 cell_out->created_cell.cell_type = CELL_CREATED2;
425 cell_out->created_cell.handshake_len = ntohs(get_uint16(payload));
426 if (cell_out->created_cell.handshake_len > RELAY_PAYLOAD_SIZE - 2 ||
427 cell_out->created_cell.handshake_len > payload_len - 2)
428 return -1;
429 memcpy(cell_out->created_cell.reply, payload+2,
430 cell_out->created_cell.handshake_len);
431 }
432 break;
433 default:
434 return -1;
435 }
436
437 return check_extended_cell(cell_out);
438}
439
440/** Fill <b>cell_out</b> with a correctly formatted version of the
441 * CREATE{,_FAST,2} cell in <b>cell_in</b>. Return 0 on success, -1 on
442 * failure. This is a cell we didn't originate if <b>relayed</b> is true. */
443static int
445 int relayed)
446{
447 uint8_t *p;
448 size_t space;
449 if (check_create_cell(cell_in, relayed) < 0)
450 return -1;
451
452 memset(cell_out->payload, 0, sizeof(cell_out->payload));
453 cell_out->command = cell_in->cell_type;
454
455 p = cell_out->payload;
456 space = sizeof(cell_out->payload);
457
458 switch (cell_in->cell_type) {
459 case CELL_CREATE:
460 if (BUG(cell_in->handshake_type == ONION_HANDSHAKE_TYPE_NTOR_V3)) {
461 log_warn(LD_BUG, "Create cells cannot contain ntorv3.");
462 return -1;
463 }
464
465 if (cell_in->handshake_type == ONION_HANDSHAKE_TYPE_NTOR) {
466 memcpy(p, NTOR_CREATE_MAGIC, 16);
467 p += 16;
468 space -= 16;
469 }
470 FALLTHROUGH;
471 case CELL_CREATE_FAST:
472 tor_assert(cell_in->handshake_len <= space);
473 memcpy(p, cell_in->onionskin, cell_in->handshake_len);
474 break;
475 case CELL_CREATE2:
476 tor_assert(cell_in->handshake_len <= sizeof(cell_out->payload)-4);
477 set_uint16(cell_out->payload, htons(cell_in->handshake_type));
478 set_uint16(cell_out->payload+2, htons(cell_in->handshake_len));
479 memcpy(cell_out->payload + 4, cell_in->onionskin, cell_in->handshake_len);
480 break;
481 default:
482 return -1;
483 }
484
485 return 0;
486}
487
488int
489create_cell_format(cell_t *cell_out, const create_cell_t *cell_in)
490{
491 return create_cell_format_impl(cell_out, cell_in, 0);
492}
493
494int
495create_cell_format_relayed(cell_t *cell_out, const create_cell_t *cell_in)
496{
497 return create_cell_format_impl(cell_out, cell_in, 1);
498}
499
500/** Fill <b>cell_out</b> with a correctly formatted version of the
501 * CREATED{,_FAST,2} cell in <b>cell_in</b>. Return 0 on success, -1 on
502 * failure. */
503int
504created_cell_format(cell_t *cell_out, const created_cell_t *cell_in)
505{
506 if (check_created_cell(cell_in) < 0)
507 return -1;
508
509 memset(cell_out->payload, 0, sizeof(cell_out->payload));
510 cell_out->command = cell_in->cell_type;
511
512 switch (cell_in->cell_type) {
513 case CELL_CREATED:
514 case CELL_CREATED_FAST:
515 tor_assert(cell_in->handshake_len <= sizeof(cell_out->payload));
516 memcpy(cell_out->payload, cell_in->reply, cell_in->handshake_len);
517 break;
518 case CELL_CREATED2:
519 tor_assert(cell_in->handshake_len <= sizeof(cell_out->payload)-2);
520 set_uint16(cell_out->payload, htons(cell_in->handshake_len));
521 memcpy(cell_out->payload + 2, cell_in->reply, cell_in->handshake_len);
522 break;
523 default:
524 return -1;
525 }
526 return 0;
527}
528
529/** Return true iff we are configured (by torrc or by the networkstatus
530 * parameters) to use Ed25519 identities in our Extend2 cells. */
531static int
533 const or_options_t *options)
534{
535 if (options->ExtendByEd25519ID != -1)
536 return options->ExtendByEd25519ID; /* The user has an opinion. */
537
538 return (int) networkstatus_get_param(ns, "ExtendByEd25519ID",
539 0 /* default */,
540 0 /* min */,
541 1 /*max*/);
542}
543
544/** Format the EXTEND{,2} cell in <b>cell_in</b>, storing its relay payload in
545 * <b>payload_out</b>, the number of bytes used in *<b>len_out</b>, and the
546 * relay command in *<b>command_out</b>. The <b>payload_out</b> must have
547 * RELAY_PAYLOAD_SIZE bytes available. Return 0 on success, -1 on failure. */
548int
549extend_cell_format(uint8_t *command_out, uint16_t *len_out,
550 uint8_t *payload_out, const extend_cell_t *cell_in)
551{
552 uint8_t *p;
553 if (check_extend_cell(cell_in) < 0)
554 return -1;
555
556 p = payload_out;
557
558 memset(p, 0, RELAY_PAYLOAD_SIZE);
559
560 switch (cell_in->cell_type) {
561 case RELAY_COMMAND_EXTEND:
562 return -1;
563 case RELAY_COMMAND_EXTEND2:
564 {
565 uint8_t n_specifiers = 1;
566 *command_out = RELAY_COMMAND_EXTEND2;
567 extend2_cell_body_t *cell = extend2_cell_body_new();
568 link_specifier_t *ls;
569 if (tor_addr_port_is_valid_ap(&cell_in->orport_ipv4, 0)) {
570 /* Maybe IPv4 specifier first. */
571 ++n_specifiers;
572 ls = link_specifier_new();
573 extend2_cell_body_add_ls(cell, ls);
574 ls->ls_type = LS_IPV4;
575 ls->ls_len = 6;
576 ls->un_ipv4_addr = tor_addr_to_ipv4h(&cell_in->orport_ipv4.addr);
577 ls->un_ipv4_port = cell_in->orport_ipv4.port;
578 }
579 {
580 /* Then RSA id */
581 ls = link_specifier_new();
582 extend2_cell_body_add_ls(cell, ls);
583 ls->ls_type = LS_LEGACY_ID;
584 ls->ls_len = DIGEST_LEN;
585 memcpy(ls->un_legacy_id, cell_in->node_id, DIGEST_LEN);
586 }
589 /* Then, maybe, the ed25519 id! */
590 ++n_specifiers;
591 ls = link_specifier_new();
592 extend2_cell_body_add_ls(cell, ls);
593 ls->ls_type = LS_ED25519_ID;
594 ls->ls_len = 32;
595 memcpy(ls->un_ed25519_id, cell_in->ed_pubkey.pubkey, 32);
596 }
597 if (tor_addr_port_is_valid_ap(&cell_in->orport_ipv6, 0)) {
598 /* Then maybe IPv6 specifier. */
599 ++n_specifiers;
600 ls = link_specifier_new();
601 extend2_cell_body_add_ls(cell, ls);
602 ls->ls_type = LS_IPV6;
603 ls->ls_len = 18;
604 tor_addr_copy_ipv6_bytes(ls->un_ipv6_addr,
605 &cell_in->orport_ipv6.addr);
606 ls->un_ipv6_port = cell_in->orport_ipv6.port;
607 }
608 cell->n_spec = n_specifiers;
609
610 /* Now, the handshake */
611 cell->create2 = create2_cell_body_new();
612 cell->create2->handshake_type = cell_in->create_cell.handshake_type;
613 cell->create2->handshake_len = cell_in->create_cell.handshake_len;
614 create2_cell_body_setlen_handshake_data(cell->create2,
615 cell_in->create_cell.handshake_len);
616 memcpy(create2_cell_body_getarray_handshake_data(cell->create2),
617 cell_in->create_cell.onionskin,
618 cell_in->create_cell.handshake_len);
619
620 ssize_t len_encoded = extend2_cell_body_encode(
621 payload_out, RELAY_PAYLOAD_SIZE,
622 cell);
623 extend2_cell_body_free(cell);
624 if (len_encoded < 0 || len_encoded > UINT16_MAX)
625 return -1;
626 *len_out = (uint16_t) len_encoded;
627 }
628 break;
629 default:
630 return -1;
631 }
632
633 return 0;
634}
635
636/** Format the EXTENDED{,2} cell in <b>cell_in</b>, storing its relay payload
637 * in <b>payload_out</b>, the number of bytes used in *<b>len_out</b>, and the
638 * relay command in *<b>command_out</b>. The <b>payload_out</b> must have
639 * RELAY_PAYLOAD_SIZE bytes available. Return 0 on success, -1 on failure. */
640int
641extended_cell_format(uint8_t *command_out, uint16_t *len_out,
642 uint8_t *payload_out, const extended_cell_t *cell_in)
643{
644 uint8_t *p;
645 if (check_extended_cell(cell_in) < 0)
646 return -1;
647
648 p = payload_out;
649 memset(p, 0, RELAY_PAYLOAD_SIZE);
650
651 switch (cell_in->cell_type) {
652 case RELAY_COMMAND_EXTENDED:
653 return -1;
654 case RELAY_COMMAND_EXTENDED2:
655 {
656 *command_out = RELAY_COMMAND_EXTENDED2;
657 *len_out = 2 + cell_in->created_cell.handshake_len;
658 set_uint16(payload_out, htons(cell_in->created_cell.handshake_len));
660 return -1;
661 memcpy(payload_out+2, cell_in->created_cell.reply,
662 cell_in->created_cell.handshake_len);
663 }
664 break;
665 default:
666 return -1;
667 }
668
669 return 0;
670}
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:944
tor_cmdline_mode_t command
Definition: config.c:2468
Header file for config.c.
int ed25519_public_key_is_zero(const ed25519_public_key_t *pubkey)
#define DIGEST_LEN
Definition: digest_sizes.h:20
#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:532
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:444
int created_cell_parse(created_cell_t *cell_out, const cell_t *cell_in)
Definition: onion.c:197
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:226
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:350
int created_cell_format(cell_t *cell_out, const created_cell_t *cell_in)
Definition: onion.c:504
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:641
int extended_cell_parse(extended_cell_t *cell_out, const uint8_t command, const uint8_t *payload, size_t payload_len)
Definition: onion.c:407
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:549
static int check_extended_cell(const extended_cell_t *cell)
Definition: onion.c:387
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:465
#define RELAY_PAYLOAD_SIZE
Definition: or.h:494
Definition: cell_st.h:17
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:30
uint16_t handshake_type
Definition: onion.h:28
uint8_t onionskin[CELL_PAYLOAD_SIZE - 4]
Definition: onion.h:32
uint8_t cell_type
Definition: onion.h:26
uint16_t handshake_len
Definition: onion.h:40
uint8_t reply[CELL_PAYLOAD_SIZE - 2]
Definition: onion.h:42
uint8_t cell_type
Definition: onion.h:38
tor_addr_port_t orport_ipv4
Definition: onion.h:50
create_cell_t create_cell
Definition: onion.h:60
struct ed25519_public_key_t ed_pubkey
Definition: onion.h:56
uint8_t node_id[DIGEST_LEN]
Definition: onion.h:54
tor_addr_port_t orport_ipv6
Definition: onion.h:52
uint8_t cell_type
Definition: onion.h:48
created_cell_t created_cell
Definition: onion.h:68
uint8_t cell_type
Definition: onion.h:66
#define MOCK_IMPL(rv, funcname, arglist)
Definition: testsupport.h:133
#define tor_assert(expr)
Definition: util_bug.h:103
int tor_digest_is_zero(const char *digest)
Definition: util_string.c:98