tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

onion.c (20843B)


      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"
     44 #include "core/crypto/onion_crypto.h"
     45 #include "core/crypto/onion_fast.h"
     46 #include "core/crypto/onion_ntor.h"
     47 #include "core/or/onion.h"
     48 #include "feature/nodelist/networkstatus.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. */
     58 static int
     59 check_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:
     82    if (cell->handshake_len != NTOR_ONIONSKIN_LEN)
     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 */
    100 void
    101 create_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 */
    120 static int
    121 parse_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.) */
    152 int
    153 create_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,
    164                              CELL_PAYLOAD_SIZE) < 0)
    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. */
    175 static int
    176 check_created_cell(const created_cell_t *cell)
    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 > MAX_CREATED_LEN)
    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. */
    196 int
    197 created_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 > MAX_CREATED_LEN)
    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. */
    225 static int
    226 check_extend_cell(const extend_cell_t *cell)
    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 
    259 static int
    260 create_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 
    282 static int
    283 extend_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;
    309        tor_addr_from_ipv6_bytes(&cell_out->orport_ipv6.addr,
    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. */
    346 MOCK_IMPL(int,
    347 extend_cell_parse,(extend_cell_t *cell_out,
    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_MAX)
    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. */
    386 static int
    387 check_extended_cell(const extended_cell_t *cell)
    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_len</b> bytes of <b>payload</b> into <b>cell_out</b>. Return
    405 * 0 on success, -1 on failure. */
    406 int
    407 extended_cell_parse(extended_cell_t *cell_out,
    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_MAX)
    416    return -1;
    417 
    418  switch (command) {
    419  case RELAY_COMMAND_EXTENDED:
    420    return -1;
    421  case RELAY_COMMAND_EXTENDED2:
    422    {
    423      if (payload_len < 2) {
    424        // Prevent underflow below.
    425        return -1;
    426      }
    427      cell_out->cell_type = RELAY_COMMAND_EXTENDED2;
    428      cell_out->created_cell.cell_type = CELL_CREATED2;
    429      cell_out->created_cell.handshake_len = ntohs(get_uint16(payload));
    430      if (cell_out->created_cell.handshake_len > RELAY_PAYLOAD_SIZE_MAX - 2 ||
    431          cell_out->created_cell.handshake_len > payload_len - 2)
    432        return -1;
    433      memcpy(cell_out->created_cell.reply, payload+2,
    434             cell_out->created_cell.handshake_len);
    435    }
    436    break;
    437  default:
    438    return -1;
    439  }
    440 
    441  return check_extended_cell(cell_out);
    442 }
    443 
    444 /** Fill <b>cell_out</b> with a correctly formatted version of the
    445 * CREATE{,_FAST,2} cell in <b>cell_in</b>. Return 0 on success, -1 on
    446 * failure.  This is a cell we didn't originate if <b>relayed</b> is true. */
    447 static int
    448 create_cell_format_impl(cell_t *cell_out, const create_cell_t *cell_in,
    449                        int relayed)
    450 {
    451  uint8_t *p;
    452  size_t space;
    453  if (check_create_cell(cell_in, relayed) < 0)
    454    return -1;
    455 
    456  memset(cell_out->payload, 0, sizeof(cell_out->payload));
    457  cell_out->command = cell_in->cell_type;
    458 
    459  p = cell_out->payload;
    460  space = sizeof(cell_out->payload);
    461 
    462  switch (cell_in->cell_type) {
    463  case CELL_CREATE:
    464    if (BUG(cell_in->handshake_type == ONION_HANDSHAKE_TYPE_NTOR_V3)) {
    465      log_warn(LD_BUG, "Create cells cannot contain ntorv3.");
    466      return -1;
    467    }
    468 
    469    if (cell_in->handshake_type == ONION_HANDSHAKE_TYPE_NTOR) {
    470      memcpy(p, NTOR_CREATE_MAGIC, 16);
    471      p += 16;
    472      space -= 16;
    473    }
    474    FALLTHROUGH;
    475  case CELL_CREATE_FAST:
    476    tor_assert(cell_in->handshake_len <= space);
    477    memcpy(p, cell_in->onionskin, cell_in->handshake_len);
    478    break;
    479  case CELL_CREATE2:
    480    tor_assert(cell_in->handshake_len <= sizeof(cell_out->payload)-4);
    481    set_uint16(cell_out->payload, htons(cell_in->handshake_type));
    482    set_uint16(cell_out->payload+2, htons(cell_in->handshake_len));
    483    memcpy(cell_out->payload + 4, cell_in->onionskin, cell_in->handshake_len);
    484    break;
    485  default:
    486    return -1;
    487  }
    488 
    489  return 0;
    490 }
    491 
    492 int
    493 create_cell_format(cell_t *cell_out, const create_cell_t *cell_in)
    494 {
    495  return create_cell_format_impl(cell_out, cell_in, 0);
    496 }
    497 
    498 int
    499 create_cell_format_relayed(cell_t *cell_out, const create_cell_t *cell_in)
    500 {
    501  return create_cell_format_impl(cell_out, cell_in, 1);
    502 }
    503 
    504 /** Fill <b>cell_out</b> with a correctly formatted version of the
    505 * CREATED{,_FAST,2} cell in <b>cell_in</b>. Return 0 on success, -1 on
    506 * failure. */
    507 int
    508 created_cell_format(cell_t *cell_out, const created_cell_t *cell_in)
    509 {
    510  if (check_created_cell(cell_in) < 0)
    511    return -1;
    512 
    513  memset(cell_out->payload, 0, sizeof(cell_out->payload));
    514  cell_out->command = cell_in->cell_type;
    515 
    516  switch (cell_in->cell_type) {
    517  case CELL_CREATED:
    518  case CELL_CREATED_FAST:
    519    tor_assert(cell_in->handshake_len <= sizeof(cell_out->payload));
    520    memcpy(cell_out->payload, cell_in->reply, cell_in->handshake_len);
    521    break;
    522  case CELL_CREATED2:
    523    tor_assert(cell_in->handshake_len <= sizeof(cell_out->payload)-2);
    524    set_uint16(cell_out->payload, htons(cell_in->handshake_len));
    525    memcpy(cell_out->payload + 2, cell_in->reply, cell_in->handshake_len);
    526    break;
    527  default:
    528    return -1;
    529  }
    530  return 0;
    531 }
    532 
    533 /** Return true iff we are configured (by torrc or by the networkstatus
    534 * parameters) to use Ed25519 identities in our Extend2 cells. */
    535 static int
    536 should_include_ed25519_id_extend_cells(const networkstatus_t *ns,
    537                                       const or_options_t *options)
    538 {
    539  if (options->ExtendByEd25519ID != -1)
    540    return options->ExtendByEd25519ID; /* The user has an opinion. */
    541 
    542  return (int) networkstatus_get_param(ns, "ExtendByEd25519ID",
    543                                       0 /* default */,
    544                                       0 /* min */,
    545                                       1 /*max*/);
    546 }
    547 
    548 /** Format the EXTEND{,2} cell in <b>cell_in</b>, storing its relay payload in
    549 * <b>payload_out</b>, the number of bytes used in *<b>len_out</b>, and the
    550 * relay command in *<b>command_out</b>. The <b>payload_out</b> must have
    551 * RELAY_PAYLOAD_SIZE_MAX bytes available.
    552 *
    553 * Return 0 on success, -1 on failure. */
    554 int
    555 extend_cell_format(uint8_t *command_out, uint16_t *len_out,
    556                   uint8_t *payload_out, const extend_cell_t *cell_in)
    557 {
    558  uint8_t *p;
    559  if (check_extend_cell(cell_in) < 0)
    560    return -1;
    561 
    562  p = payload_out;
    563 
    564  memset(p, 0, RELAY_PAYLOAD_SIZE_MAX);
    565 
    566  switch (cell_in->cell_type) {
    567  case RELAY_COMMAND_EXTEND:
    568    return -1;
    569  case RELAY_COMMAND_EXTEND2:
    570    {
    571      uint8_t n_specifiers = 1;
    572      *command_out = RELAY_COMMAND_EXTEND2;
    573      extend2_cell_body_t *cell = extend2_cell_body_new();
    574      link_specifier_t *ls;
    575      if (tor_addr_port_is_valid_ap(&cell_in->orport_ipv4, 0)) {
    576        /* Maybe IPv4 specifier first. */
    577        ++n_specifiers;
    578        ls = link_specifier_new();
    579        extend2_cell_body_add_ls(cell, ls);
    580        ls->ls_type = LS_IPV4;
    581        ls->ls_len = 6;
    582        ls->un_ipv4_addr = tor_addr_to_ipv4h(&cell_in->orport_ipv4.addr);
    583        ls->un_ipv4_port = cell_in->orport_ipv4.port;
    584      }
    585      {
    586        /* Then RSA id */
    587        ls = link_specifier_new();
    588        extend2_cell_body_add_ls(cell, ls);
    589        ls->ls_type = LS_LEGACY_ID;
    590        ls->ls_len = DIGEST_LEN;
    591        memcpy(ls->un_legacy_id, cell_in->node_id, DIGEST_LEN);
    592      }
    593      if (should_include_ed25519_id_extend_cells(NULL, get_options()) &&
    594          !ed25519_public_key_is_zero(&cell_in->ed_pubkey)) {
    595        /* Then, maybe, the ed25519 id! */
    596        ++n_specifiers;
    597        ls = link_specifier_new();
    598        extend2_cell_body_add_ls(cell, ls);
    599        ls->ls_type = LS_ED25519_ID;
    600        ls->ls_len = 32;
    601        memcpy(ls->un_ed25519_id, cell_in->ed_pubkey.pubkey, 32);
    602      }
    603      if (tor_addr_port_is_valid_ap(&cell_in->orport_ipv6, 0)) {
    604        /* Then maybe IPv6 specifier. */
    605        ++n_specifiers;
    606        ls = link_specifier_new();
    607        extend2_cell_body_add_ls(cell, ls);
    608        ls->ls_type = LS_IPV6;
    609        ls->ls_len = 18;
    610        tor_addr_copy_ipv6_bytes(ls->un_ipv6_addr,
    611                                 &cell_in->orport_ipv6.addr);
    612        ls->un_ipv6_port = cell_in->orport_ipv6.port;
    613      }
    614      cell->n_spec = n_specifiers;
    615 
    616      /* Now, the handshake */
    617      cell->create2 = create2_cell_body_new();
    618      cell->create2->handshake_type = cell_in->create_cell.handshake_type;
    619      cell->create2->handshake_len = cell_in->create_cell.handshake_len;
    620      create2_cell_body_setlen_handshake_data(cell->create2,
    621                                         cell_in->create_cell.handshake_len);
    622      memcpy(create2_cell_body_getarray_handshake_data(cell->create2),
    623             cell_in->create_cell.onionskin,
    624             cell_in->create_cell.handshake_len);
    625 
    626      ssize_t len_encoded = extend2_cell_body_encode(
    627                             payload_out, RELAY_PAYLOAD_SIZE_MAX,
    628                             cell);
    629      extend2_cell_body_free(cell);
    630      if (len_encoded < 0 || len_encoded > UINT16_MAX)
    631        return -1;
    632      *len_out = (uint16_t) len_encoded;
    633    }
    634    break;
    635  default:
    636    return -1;
    637  }
    638 
    639  return 0;
    640 }
    641 
    642 /** Format the EXTENDED{,2} cell in <b>cell_in</b>, storing its relay payload
    643 * in <b>payload_out</b>, the number of bytes used in *<b>len_out</b>, and the
    644 * relay command in *<b>command_out</b>. The <b>payload_out</b> must have
    645 * RELAY_PAYLOAD_SIZE_MAX bytes available.
    646 *
    647 * Return 0 on success, -1 on failure. */
    648 int
    649 extended_cell_format(uint8_t *command_out, uint16_t *len_out,
    650                     uint8_t *payload_out, const extended_cell_t *cell_in)
    651 {
    652  uint8_t *p;
    653  if (check_extended_cell(cell_in) < 0)
    654    return -1;
    655 
    656  p = payload_out;
    657  memset(p, 0, RELAY_PAYLOAD_SIZE_MAX);
    658 
    659  switch (cell_in->cell_type) {
    660  case RELAY_COMMAND_EXTENDED:
    661    return -1;
    662  case RELAY_COMMAND_EXTENDED2:
    663    {
    664      *command_out = RELAY_COMMAND_EXTENDED2;
    665      *len_out = 2 + cell_in->created_cell.handshake_len;
    666      set_uint16(payload_out, htons(cell_in->created_cell.handshake_len));
    667      if (cell_in->created_cell.handshake_len > MAX_CREATED_LEN)
    668        return -1;
    669      memcpy(payload_out+2, cell_in->created_cell.reply,
    670             cell_in->created_cell.handshake_len);
    671    }
    672    break;
    673  default:
    674    return -1;
    675  }
    676 
    677  return 0;
    678 }