LCOV - code coverage report
Current view: top level - feature/relay - circuitbuild_relay.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 150 173 86.7 %
Date: 2021-11-24 03:28:48 Functions: 10 10 100.0 %

          Line data    Source code
       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 circuitbuild_relay.c
       9             :  * @brief Implements the details of exteding circuits (by relaying extend
      10             :  * cells as create cells, and answering create cells).
      11             :  *
      12             :  * On the server side, this module handles the logic of responding to
      13             :  * RELAY_EXTEND requests, using circuit_extend() and onionskin_answer().
      14             :  *
      15             :  * The shared client and server code is in core/or/circuitbuild.c.
      16             :  **/
      17             : 
      18             : #include "orconfig.h"
      19             : #include "feature/relay/circuitbuild_relay.h"
      20             : 
      21             : #include "lib/crypt_ops/crypto_rand.h"
      22             : 
      23             : #include "core/or/or.h"
      24             : #include "app/config/config.h"
      25             : 
      26             : #include "core/crypto/relay_crypto.h"
      27             : 
      28             : #include "core/or/cell_st.h"
      29             : #include "core/or/circuit_st.h"
      30             : #include "core/or/extend_info_st.h"
      31             : #include "core/or/or_circuit_st.h"
      32             : 
      33             : #include "core/or/channel.h"
      34             : #include "core/or/circuitbuild.h"
      35             : #include "core/or/circuitlist.h"
      36             : #include "core/or/extendinfo.h"
      37             : #include "core/or/onion.h"
      38             : #include "core/or/relay.h"
      39             : 
      40             : #include "feature/nodelist/nodelist.h"
      41             : 
      42             : #include "feature/relay/router.h"
      43             : #include "feature/relay/routermode.h"
      44             : #include "feature/relay/selftest.h"
      45             : 
      46             : /* Before replying to an extend cell, check the state of the circuit
      47             :  * <b>circ</b>, and the configured tor mode.
      48             :  *
      49             :  * <b>circ</b> must not be NULL.
      50             :  *
      51             :  * If the state and mode are valid, return 0.
      52             :  * Otherwise, if they are invalid, log a protocol warning, and return -1.
      53             :  */
      54             : STATIC int
      55          15 : circuit_extend_state_valid_helper(const struct circuit_t *circ)
      56             : {
      57          15 :   if (!server_mode(get_options())) {
      58           3 :     circuitbuild_warn_client_extend();
      59           3 :     return -1;
      60             :   }
      61             : 
      62          12 :   IF_BUG_ONCE(!circ) {
      63             :     return -1;
      64             :   }
      65             : 
      66          11 :   if (circ->n_chan) {
      67           1 :     log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
      68             :            "n_chan already set. Bug/attack. Closing.");
      69           1 :     return -1;
      70             :   }
      71             : 
      72          10 :   if (circ->n_hop) {
      73           1 :     log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
      74             :            "conn to next hop already launched. Bug/attack. Closing.");
      75           1 :     return -1;
      76             :   }
      77             : 
      78             :   return 0;
      79             : }
      80             : 
      81             : /* Make sure the extend cell <b>ec</b> has an ed25519 link specifier.
      82             :  *
      83             :  * First, check that the RSA node id is valid.
      84             :  * If the node id is valid, add the ed25519 link specifier (if required),
      85             :  * and return 0.
      86             :  *
      87             :  * Otherwise, if the node id is invalid, log a protocol warning,
      88             :  * and return -1.(And do not modify the extend cell.)
      89             :  *
      90             :  * Must be called before circuit_extend_lspec_valid_helper().
      91             :  */
      92             : STATIC int
      93          15 : circuit_extend_add_ed25519_helper(struct extend_cell_t *ec)
      94             : {
      95          15 :   IF_BUG_ONCE(!ec) {
      96             :     return -1;
      97             :   }
      98             : 
      99             :   /* Check if they asked us for 0000..0000. We support using
     100             :    * an empty fingerprint for the first hop (e.g. for a bridge relay),
     101             :    * but we don't want to let clients send us extend cells for empty
     102             :    * fingerprints -- a) because it opens the user up to a mitm attack,
     103             :    * and b) because it lets an attacker force the relay to hold open a
     104             :    * new TLS connection for each extend request. */
     105          14 :   if (tor_digest_is_zero((const char*)ec->node_id)) {
     106           2 :     log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
     107             :            "Client asked me to extend without specifying an id_digest.");
     108           2 :     return -1;
     109             :   }
     110             : 
     111             :   /* Fill in ed_pubkey if it was not provided and we can infer it from
     112             :    * our networkstatus */
     113          12 :   if (ed25519_public_key_is_zero(&ec->ed_pubkey)) {
     114          12 :     const node_t *node = node_get_by_id((const char*)ec->node_id);
     115          12 :     const ed25519_public_key_t *node_ed_id = NULL;
     116          16 :     if (node &&
     117           4 :         node_supports_ed25519_link_authentication(node, 1) &&
     118           3 :         (node_ed_id = node_get_ed25519_id(node))) {
     119           2 :       ed25519_pubkey_copy(&ec->ed_pubkey, node_ed_id);
     120             :     }
     121             :   }
     122             : 
     123             :   return 0;
     124             : }
     125             : 
     126             : /* Make sure the extend cell <b>ec</b> has an IPv4 address if the relay
     127             :  * supports in, and if not, fill it in. */
     128             : STATIC int
     129           5 : circuit_extend_add_ipv4_helper(struct extend_cell_t *ec)
     130             : {
     131           5 :   IF_BUG_ONCE(!ec) {
     132             :     return -1;
     133             :   }
     134             : 
     135           5 :   const node_t *node = node_get_by_id((const char *) ec->node_id);
     136           5 :   if (node) {
     137           1 :     tor_addr_port_t node_ipv4;
     138           1 :     node_get_prim_orport(node, &node_ipv4);
     139           2 :     if (tor_addr_is_null(&ec->orport_ipv4.addr) &&
     140           1 :         !tor_addr_is_null(&node_ipv4.addr)) {
     141           1 :       tor_addr_copy(&ec->orport_ipv4.addr, &node_ipv4.addr);
     142           1 :       ec->orport_ipv4.port = node_ipv4.port;
     143             :     }
     144             :   }
     145             : 
     146             :   return 0;
     147             : }
     148             : 
     149             : /* Make sure the extend cell <b>ec</b> has an IPv6 address if the relay
     150             :  * supports in, and if not, fill it in. */
     151             : STATIC int
     152           5 : circuit_extend_add_ipv6_helper(struct extend_cell_t *ec)
     153             : {
     154           5 :   IF_BUG_ONCE(!ec) {
     155             :     return -1;
     156             :   }
     157             : 
     158           5 :   const node_t *node = node_get_by_id((const char *) ec->node_id);
     159           5 :   if (node) {
     160           1 :     tor_addr_port_t node_ipv6;
     161           1 :     node_get_pref_ipv6_orport(node, &node_ipv6);
     162           2 :     if (tor_addr_is_null(&ec->orport_ipv6.addr) &&
     163           1 :         !tor_addr_is_null(&node_ipv6.addr)) {
     164           1 :       tor_addr_copy(&ec->orport_ipv6.addr, &node_ipv6.addr);
     165           1 :       ec->orport_ipv6.port = node_ipv6.port;
     166             :     }
     167             :   }
     168             : 
     169             :   return 0;
     170             : }
     171             : 
     172             : /* Check if the address and port in the tor_addr_port_t <b>ap</b> are valid,
     173             :  * and are allowed by the current ExtendAllowPrivateAddresses config.
     174             :  *
     175             :  * If they are valid, return true.
     176             :  * Otherwise, if they are invalid, return false.
     177             :  *
     178             :  * If <b>log_zero_addrs</b> is true, log warnings about zero addresses at
     179             :  * <b>log_level</b>. If <b>log_internal_addrs</b> is true, log warnings about
     180             :  * internal addresses at <b>log_level</b>.
     181             :  */
     182             : static bool
     183         121 : circuit_extend_addr_port_is_valid(const struct tor_addr_port_t *ap,
     184             :                                   bool log_zero_addrs, bool log_internal_addrs,
     185             :                                   int log_level)
     186             : {
     187             :   /* It's safe to print the family. But we don't want to print the address,
     188             :    * unless specifically configured to do so. (Zero addresses aren't sensitive,
     189             :    * But some internal addresses might be.)*/
     190             : 
     191         121 :   if (!tor_addr_port_is_valid_ap(ap, 0)) {
     192          68 :     if (log_zero_addrs) {
     193          14 :       log_fn(log_level, LD_PROTOCOL,
     194             :              "Client asked me to extend to a zero destination port or "
     195             :              "%s address '%s'.",
     196             :              fmt_addr_family(&ap->addr), safe_str(fmt_addrport_ap(ap)));
     197             :     }
     198          68 :     return false;
     199             :   }
     200             : 
     201          53 :   if (tor_addr_is_internal(&ap->addr, 0) &&
     202          16 :       !get_options()->ExtendAllowPrivateAddresses) {
     203          12 :     if (log_internal_addrs) {
     204           6 :       log_fn(log_level, LD_PROTOCOL,
     205             :              "Client asked me to extend to a private %s address '%s'.",
     206             :              fmt_addr_family(&ap->addr),
     207             :              safe_str(fmt_and_decorate_addr(&ap->addr)));
     208             :     }
     209          12 :     return false;
     210             :   }
     211             : 
     212             :   return true;
     213             : }
     214             : 
     215             : /* Before replying to an extend cell, check the link specifiers in the extend
     216             :  * cell <b>ec</b>, which was received on the circuit <b>circ</b>.
     217             :  *
     218             :  * If they are valid, return 0.
     219             :  * Otherwise, if they are invalid, log a protocol warning, and return -1.
     220             :  *
     221             :  * Must be called after circuit_extend_add_ed25519_helper().
     222             :  */
     223             : STATIC int
     224          30 : circuit_extend_lspec_valid_helper(const struct extend_cell_t *ec,
     225             :                                   const struct circuit_t *circ)
     226             : {
     227          30 :   IF_BUG_ONCE(!ec) {
     228             :     return -1;
     229             :   }
     230             : 
     231          28 :   IF_BUG_ONCE(!circ) {
     232             :     return -1;
     233             :   }
     234             : 
     235             :   /* Check the addresses, without logging */
     236          27 :   const int ipv4_valid = circuit_extend_addr_port_is_valid(&ec->orport_ipv4,
     237             :                                                            false, false, 0);
     238          27 :   const int ipv6_valid = circuit_extend_addr_port_is_valid(&ec->orport_ipv6,
     239             :                                                            false, false, 0);
     240             :   /* We need at least one valid address */
     241          27 :   if (!ipv4_valid && !ipv6_valid) {
     242             :     /* Now, log the invalid addresses at protocol warning level */
     243           9 :     circuit_extend_addr_port_is_valid(&ec->orport_ipv4,
     244             :                                       true, true, LOG_PROTOCOL_WARN);
     245           9 :     circuit_extend_addr_port_is_valid(&ec->orport_ipv6,
     246             :                                       true, true, LOG_PROTOCOL_WARN);
     247             :     /* And fail */
     248           9 :     return -1;
     249          18 :   } else if (!ipv4_valid) {
     250             :     /* Always log unexpected internal addresses, but go on to use the other
     251             :      * valid address */
     252           1 :     circuit_extend_addr_port_is_valid(&ec->orport_ipv4,
     253             :                                       false, true, LOG_PROTOCOL_WARN);
     254          17 :   } else if (!ipv6_valid) {
     255          12 :     circuit_extend_addr_port_is_valid(&ec->orport_ipv6,
     256             :                                       false, true, LOG_PROTOCOL_WARN);
     257             :   }
     258             : 
     259          18 :   IF_BUG_ONCE(circ->magic != OR_CIRCUIT_MAGIC) {
     260             :     return -1;
     261             :   }
     262             : 
     263          15 :   const channel_t *p_chan = CONST_TO_OR_CIRCUIT(circ)->p_chan;
     264             : 
     265          15 :   IF_BUG_ONCE(!p_chan) {
     266             :     return -1;
     267             :   }
     268             : 
     269             :   /* Next, check if we're being asked to connect to the hop that the
     270             :    * extend cell came from. There isn't any reason for that, and it can
     271             :    * assist circular-path attacks. */
     272          13 :   if (tor_memeq(ec->node_id, p_chan->identity_digest, DIGEST_LEN)) {
     273           2 :     log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
     274             :            "Client asked me to extend back to the previous hop.");
     275           2 :     return -1;
     276             :   }
     277             : 
     278             :   /* Check the previous hop Ed25519 ID too */
     279          14 :   if (! ed25519_public_key_is_zero(&ec->ed_pubkey) &&
     280           3 :       ed25519_pubkey_eq(&ec->ed_pubkey, &p_chan->ed25519_identity)) {
     281           1 :     log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
     282             :            "Client asked me to extend back to the previous hop "
     283             :            "(by Ed25519 ID).");
     284           1 :     return -1;
     285             :   }
     286             : 
     287             :   return 0;
     288             : }
     289             : 
     290             : /* If possible, return a supported, non-NULL IP address.
     291             :  *
     292             :  * If both addresses are supported and non-NULL, choose one uniformly at
     293             :  * random.
     294             :  *
     295             :  * If we have an IPv6-only extend, but IPv6 is not supported, returns NULL.
     296             :  * If both addresses are NULL, also returns NULL. */
     297             : STATIC const tor_addr_port_t *
     298          19 : circuit_choose_ip_ap_for_extend(const tor_addr_port_t *ipv4_ap,
     299             :                                 const tor_addr_port_t *ipv6_ap)
     300             : {
     301          19 :   const bool ipv6_supported = router_can_extend_over_ipv6(get_options());
     302             : 
     303             :   /* If IPv6 is not supported, we can't use the IPv6 address. */
     304          19 :   if (!ipv6_supported) {
     305             :     ipv6_ap = NULL;
     306             :   }
     307             : 
     308             :   /* If there is no IPv6 address, IPv4 is always supported.
     309             :    * Until clients include IPv6 ORPorts, and most relays support IPv6,
     310             :    * this is the most common case. */
     311          13 :   if (!ipv6_ap) {
     312             :     return ipv4_ap;
     313             :   }
     314             : 
     315             :   /* If there is no IPv4 address, return the (possibly NULL) IPv6 address. */
     316           8 :   if (!ipv4_ap) {
     317             :     return ipv6_ap;
     318             :   }
     319             : 
     320             :   /* Now we have an IPv4 and an IPv6 address, and IPv6 is supported.
     321             :    * So make an IPv6 connection at random, with probability 1 in N.
     322             :    *   1 means "always IPv6 (and no IPv4)"
     323             :    *   2 means "equal probability of IPv4 or IPv6"
     324             :    *   ... (and so on) ...
     325             :    *   (UINT_MAX - 1) means "almost always IPv4 (and almost never IPv6)"
     326             :    * To disable IPv6, set ipv6_supported to 0.
     327             :    */
     328             : #define IPV6_CONNECTION_ONE_IN_N 2
     329             : 
     330           4 :   bool choose_ipv6 = crypto_fast_rng_one_in_n(get_thread_fast_rng(),
     331             :                                               IPV6_CONNECTION_ONE_IN_N);
     332           4 :   if (choose_ipv6) {
     333             :     return ipv6_ap;
     334             :   } else {
     335           3 :     return ipv4_ap;
     336             :   }
     337             : }
     338             : 
     339             : /* When there is no open channel for an extend cell <b>ec</b>, set up the
     340             :  * circuit <b>circ</b> to wait for a new connection.
     341             :  *
     342             :  * If <b>should_launch</b> is true, open a new connection. (Otherwise, we are
     343             :  * already waiting for a new connection to the same relay.)
     344             :  *
     345             :  * Check if IPv6 extends are supported by our current configuration. If they
     346             :  * are, new connections may be made over IPv4 or IPv6. (IPv4 connections are
     347             :  * always supported.)
     348             :  */
     349             : STATIC void
     350          23 : circuit_open_connection_for_extend(const struct extend_cell_t *ec,
     351             :                                    struct circuit_t *circ,
     352             :                                    int should_launch)
     353             : {
     354             :   /* We have to check circ first, so we can close it on all other failures */
     355          23 :   IF_BUG_ONCE(!circ) {
     356             :     /* We can't mark a NULL circuit for close. */
     357             :     return;
     358             :   }
     359             : 
     360             :   /* Now we know that circ is not NULL */
     361          17 :   IF_BUG_ONCE(!ec) {
     362           3 :     circuit_mark_for_close(circ, END_CIRC_REASON_CONNECTFAILED);
     363           3 :     return;
     364             :   }
     365             : 
     366             :   /* Check the addresses, without logging */
     367          14 :   const int ipv4_valid = circuit_extend_addr_port_is_valid(&ec->orport_ipv4,
     368             :                                                            false, false, 0);
     369          14 :   const int ipv6_valid = circuit_extend_addr_port_is_valid(&ec->orport_ipv6,
     370             :                                                            false, false, 0);
     371             : 
     372          14 :   IF_BUG_ONCE(!ipv4_valid && !ipv6_valid) {
     373             :     /* circuit_extend_lspec_valid_helper() should have caught this */
     374           3 :     circuit_mark_for_close(circ, END_CIRC_REASON_CONNECTFAILED);
     375           3 :     return;
     376             :   }
     377             : 
     378          25 :   const tor_addr_port_t *chosen_ap = circuit_choose_ip_ap_for_extend(
     379             :                                         ipv4_valid ? &ec->orport_ipv4 : NULL,
     380             :                                         ipv6_valid ? &ec->orport_ipv6 : NULL);
     381          11 :   if (!chosen_ap) {
     382             :     /* An IPv6-only extend, but IPv6 is not supported */
     383           0 :     log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
     384             :            "Received IPv6-only extend, but we don't have an IPv6 ORPort.");
     385           0 :     circuit_mark_for_close(circ, END_CIRC_REASON_CONNECTFAILED);
     386           0 :     return;
     387             :   }
     388             : 
     389          22 :   circ->n_hop = extend_info_new(NULL /*nickname*/,
     390          11 :                                 (const char*)ec->node_id,
     391             :                                 &ec->ed_pubkey,
     392             :                                 NULL, /*onion_key*/
     393             :                                 NULL, /*curve25519_key*/
     394             :                                 &chosen_ap->addr,
     395          11 :                                 chosen_ap->port);
     396             : 
     397          11 :   circ->n_chan_create_cell = tor_memdup(&ec->create_cell,
     398             :                                         sizeof(ec->create_cell));
     399             : 
     400          11 :   circuit_set_state(circ, CIRCUIT_STATE_CHAN_WAIT);
     401             : 
     402          11 :   if (should_launch) {
     403             :     /* we should try to open a connection */
     404           7 :     channel_t *n_chan = channel_connect_for_circuit(circ->n_hop);
     405           7 :     if (!n_chan) {
     406           3 :       log_info(LD_CIRC,"Launching n_chan failed. Closing circuit.");
     407           3 :       circuit_mark_for_close(circ, END_CIRC_REASON_CONNECTFAILED);
     408           3 :       return;
     409             :     }
     410           4 :     log_debug(LD_CIRC,"connecting in progress (or finished). Good.");
     411             :   }
     412             : }
     413             : 
     414             : /** Take the 'extend' <b>cell</b>, pull out addr/port plus the onion
     415             :  * skin and identity digest for the next hop. If we're already connected,
     416             :  * pass the onion skin to the next hop using a create cell; otherwise
     417             :  * launch a new OR connection, and <b>circ</b> will notice when the
     418             :  * connection succeeds or fails.
     419             :  *
     420             :  * Return -1 if we want to warn and tear down the circuit, else return 0.
     421             :  */
     422             : int
     423          12 : circuit_extend(struct cell_t *cell, struct circuit_t *circ)
     424             : {
     425          12 :   channel_t *n_chan;
     426          12 :   relay_header_t rh;
     427          12 :   extend_cell_t ec;
     428          12 :   const char *msg = NULL;
     429          12 :   int should_launch = 0;
     430             : 
     431          12 :   IF_BUG_ONCE(!cell) {
     432             :     return -1;
     433             :   }
     434             : 
     435          10 :   IF_BUG_ONCE(!circ) {
     436             :     return -1;
     437             :   }
     438             : 
     439           9 :   if (circuit_extend_state_valid_helper(circ) < 0)
     440             :     return -1;
     441             : 
     442           8 :   relay_header_unpack(&rh, cell->payload);
     443             : 
     444           8 :   if (extend_cell_parse(&ec, rh.command,
     445             :                         cell->payload+RELAY_HEADER_SIZE,
     446           8 :                         rh.length) < 0) {
     447           1 :     log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
     448             :            "Can't parse extend cell. Closing circuit.");
     449           1 :     return -1;
     450             :   }
     451             : 
     452           7 :   if (circuit_extend_add_ed25519_helper(&ec) < 0)
     453             :     return -1;
     454             : 
     455           6 :   if (circuit_extend_lspec_valid_helper(&ec, circ) < 0)
     456             :     return -1;
     457             : 
     458           4 :   if (circuit_extend_add_ipv4_helper(&ec) < 0)
     459             :     return -1;
     460             : 
     461           4 :   if (circuit_extend_add_ipv6_helper(&ec) < 0)
     462             :     return -1;
     463             : 
     464             :   /* Check the addresses, without logging */
     465           4 :   const int ipv4_valid = circuit_extend_addr_port_is_valid(&ec.orport_ipv4,
     466             :                                                            false, false, 0);
     467           4 :   const int ipv6_valid = circuit_extend_addr_port_is_valid(&ec.orport_ipv6,
     468             :                                                            false, false, 0);
     469           4 :   IF_BUG_ONCE(!ipv4_valid && !ipv6_valid) {
     470             :     /* circuit_extend_lspec_valid_helper() should have caught this */
     471             :     return -1;
     472             :   }
     473             : 
     474           8 :   n_chan = channel_get_for_extend((const char*)ec.node_id,
     475             :                                   &ec.ed_pubkey,
     476             :                                   ipv4_valid ? &ec.orport_ipv4.addr : NULL,
     477             :                                   ipv6_valid ? &ec.orport_ipv6.addr : NULL,
     478             :                                   false,
     479             :                                   &msg,
     480             :                                   &should_launch);
     481             : 
     482           4 :   if (!n_chan) {
     483             :     /* We can't use fmt_addr*() twice in the same function call,
     484             :      * because it uses a static buffer. */
     485           2 :     log_debug(LD_CIRC|LD_OR, "Next router IPv4 (%s): %s.",
     486             :               fmt_addrport_ap(&ec.orport_ipv4),
     487             :               msg ? msg : "????");
     488           2 :     log_debug(LD_CIRC|LD_OR, "Next router IPv6 (%s).",
     489             :               fmt_addrport_ap(&ec.orport_ipv6));
     490             : 
     491           2 :     circuit_open_connection_for_extend(&ec, circ, should_launch);
     492             : 
     493             :     /* return success. The onion/circuit/etc will be taken care of
     494             :      * automatically (may already have been) whenever n_chan reaches
     495             :      * OR_CONN_STATE_OPEN.
     496             :      */
     497           2 :     return 0;
     498             :   } else {
     499             :     /* Connection is already established.
     500             :      * So we need to extend the circuit to the next hop. */
     501           2 :     tor_assert(!circ->n_hop);
     502           2 :     circ->n_chan = n_chan;
     503           2 :     log_debug(LD_CIRC,
     504             :               "n_chan is %s.",
     505             :               channel_describe_peer(n_chan));
     506             : 
     507           2 :     if (circuit_deliver_create_cell(circ, &ec.create_cell, 1) < 0)
     508             :       return -1;
     509             : 
     510           1 :     return 0;
     511             :   }
     512             : }
     513             : 
     514             : /** On a relay, accept a create cell, initialise a circuit, and send a
     515             :  * created cell back.
     516             :  *
     517             :  * Given:
     518             :  *   - a response payload consisting of:
     519             :  *     - the <b>created_cell</b> and
     520             :  *     - an optional <b>rend_circ_nonce</b>, and
     521             :  *   - <b>keys</b> of length <b>keys_len</b>, which must be
     522             :  *     CPATH_KEY_MATERIAL_LEN;
     523             :  * then:
     524             :  *   - initialize the circuit <b>circ</b>'s cryptographic material,
     525             :  *   - set the circuit's state to open, and
     526             :  *   - send a created cell back on that circuit.
     527             :  *
     528             :  * If we haven't found our ORPorts reachable yet, and the channel meets the
     529             :  * necessary conditions, mark the relevant ORPorts as reachable.
     530             :  *
     531             :  * Returns -1 if cell or circuit initialisation fails.
     532             :  */
     533             : int
     534           5 : onionskin_answer(struct or_circuit_t *circ,
     535             :                  const created_cell_t *created_cell,
     536             :                  const char *keys, size_t keys_len,
     537             :                  const uint8_t *rend_circ_nonce)
     538             : {
     539           5 :   cell_t cell;
     540             : 
     541           5 :   IF_BUG_ONCE(!circ) {
     542             :     return -1;
     543             :   }
     544             : 
     545           4 :   IF_BUG_ONCE(!created_cell) {
     546             :     return -1;
     547             :   }
     548             : 
     549           3 :   IF_BUG_ONCE(!keys) {
     550             :     return -1;
     551             :   }
     552             : 
     553           2 :   IF_BUG_ONCE(!rend_circ_nonce) {
     554             :     return -1;
     555             :   }
     556             : 
     557           1 :   tor_assert(keys_len == CPATH_KEY_MATERIAL_LEN);
     558             : 
     559           1 :   if (created_cell_format(&cell, created_cell) < 0) {
     560           1 :     log_warn(LD_BUG,"couldn't format created cell (type=%d, len=%d).",
     561             :              (int)created_cell->cell_type, (int)created_cell->handshake_len);
     562           1 :     return -1;
     563             :   }
     564           0 :   cell.circ_id = circ->p_circ_id;
     565             : 
     566           0 :   circuit_set_state(TO_CIRCUIT(circ), CIRCUIT_STATE_OPEN);
     567             : 
     568           0 :   log_debug(LD_CIRC,"init digest forward 0x%.8x, backward 0x%.8x.",
     569             :             (unsigned int)get_uint32(keys),
     570             :             (unsigned int)get_uint32(keys+20));
     571           0 :   if (relay_crypto_init(&circ->crypto, keys, keys_len, 0, 0)<0) {
     572           0 :     log_warn(LD_BUG,"Circuit initialization failed.");
     573           0 :     return -1;
     574             :   }
     575             : 
     576           0 :   memcpy(circ->rend_circ_nonce, rend_circ_nonce, DIGEST_LEN);
     577             : 
     578           0 :   int used_create_fast = (created_cell->cell_type == CELL_CREATED_FAST);
     579             : 
     580           0 :   append_cell_to_circuit_queue(TO_CIRCUIT(circ),
     581             :                                circ->p_chan, &cell, CELL_DIRECTION_IN, 0);
     582           0 :   log_debug(LD_CIRC,"Finished sending '%s' cell.",
     583             :             used_create_fast ? "created_fast" : "created");
     584             : 
     585             :   /* Ignore the local bit when ExtendAllowPrivateAddresses is set:
     586             :    * it violates the assumption that private addresses are local.
     587             :    * Also, many test networks run on local addresses, and
     588             :    * TestingTorNetwork sets ExtendAllowPrivateAddresses. */
     589           0 :   if ((!channel_is_local(circ->p_chan)
     590           0 :        || get_options()->ExtendAllowPrivateAddresses)
     591           0 :       && !channel_is_outgoing(circ->p_chan)) {
     592             :     /* Okay, it's a create cell from a non-local connection
     593             :      * that we didn't initiate. Presumably this means that create cells
     594             :      * can reach us too. But what address can they reach us on? */
     595           0 :     const tor_addr_t *my_supposed_addr = &circ->p_chan->addr_according_to_peer;
     596           0 :     if (router_addr_is_my_published_addr(my_supposed_addr)) {
     597             :       /* Great, this create cell came on connection where the peer says
     598             :        * that the our address is an address we're actually advertising!
     599             :        * That should mean that we're reachable.  But before we finally
     600             :        * declare ourselves reachable, make sure that the address listed
     601             :        * by the peer is the same family as the peer is actually using.
     602             :        */
     603           0 :       tor_addr_t remote_addr;
     604           0 :       int family = tor_addr_family(my_supposed_addr);
     605           0 :       if (channel_get_addr_if_possible(circ->p_chan, &remote_addr) &&
     606           0 :           tor_addr_family(&remote_addr) == family) {
     607           0 :         router_orport_found_reachable(family);
     608             :       }
     609             :     }
     610             :   }
     611             : 
     612             :   return 0;
     613             : }

Generated by: LCOV version 1.14