"Fossies" - the Fresh Open Source Software Archive

Member "tor-0.4.1.6/src/feature/rend/rendclient.c" (10 Jun 2019, 46749 Bytes) of package /linux/misc/tor-0.4.1.6.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "rendclient.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 0.4.0.5_vs_0.4.1.5.

    1 /* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
    2  * Copyright (c) 2007-2019, The Tor Project, Inc. */
    3 /* See LICENSE for licensing information */
    4 
    5 /**
    6  * \file rendclient.c
    7  * \brief Client code to access location-hidden services.
    8  **/
    9 
   10 #include "core/or/or.h"
   11 #include "app/config/config.h"
   12 #include "core/mainloop/connection.h"
   13 #include "core/mainloop/mainloop.h"
   14 #include "core/or/circuitbuild.h"
   15 #include "core/or/circuitlist.h"
   16 #include "core/or/circuituse.h"
   17 #include "core/or/connection_edge.h"
   18 #include "core/or/relay.h"
   19 #include "feature/client/circpathbias.h"
   20 #include "feature/control/control_events.h"
   21 #include "feature/dirclient/dirclient.h"
   22 #include "feature/dircommon/directory.h"
   23 #include "feature/hs/hs_circuit.h"
   24 #include "feature/hs/hs_client.h"
   25 #include "feature/hs/hs_common.h"
   26 #include "feature/nodelist/describe.h"
   27 #include "feature/nodelist/networkstatus.h"
   28 #include "feature/nodelist/nodelist.h"
   29 #include "feature/nodelist/routerlist.h"
   30 #include "feature/nodelist/routerset.h"
   31 #include "feature/rend/rendclient.h"
   32 #include "feature/rend/rendcommon.h"
   33 #include "feature/stats/rephist.h"
   34 #include "lib/crypt_ops/crypto_dh.h"
   35 #include "lib/crypt_ops/crypto_rand.h"
   36 #include "lib/crypt_ops/crypto_util.h"
   37 #include "lib/encoding/confline.h"
   38 
   39 #include "core/or/cpath_build_state_st.h"
   40 #include "core/or/crypt_path_st.h"
   41 #include "feature/dircommon/dir_connection_st.h"
   42 #include "core/or/entry_connection_st.h"
   43 #include "core/or/extend_info_st.h"
   44 #include "core/or/origin_circuit_st.h"
   45 #include "feature/rend/rend_intro_point_st.h"
   46 #include "feature/rend/rend_service_descriptor_st.h"
   47 #include "feature/nodelist/routerstatus_st.h"
   48 
   49 static extend_info_t *rend_client_get_random_intro_impl(
   50                           const rend_cache_entry_t *rend_query,
   51                           const int strict, const int warnings);
   52 
   53 /** Purge all potentially remotely-detectable state held in the hidden
   54  * service client code.  Called on SIGNAL NEWNYM. */
   55 void
   56 rend_client_purge_state(void)
   57 {
   58   rend_cache_purge();
   59   rend_cache_failure_purge();
   60   rend_client_cancel_descriptor_fetches();
   61   hs_purge_last_hid_serv_requests();
   62 }
   63 
   64 /** Called when we've established a circuit to an introduction point:
   65  * send the introduction request. */
   66 void
   67 rend_client_introcirc_has_opened(origin_circuit_t *circ)
   68 {
   69   tor_assert(circ->base_.purpose == CIRCUIT_PURPOSE_C_INTRODUCING);
   70   tor_assert(circ->cpath);
   71 
   72   log_info(LD_REND,"introcirc is open");
   73   connection_ap_attach_pending(1);
   74 }
   75 
   76 /** Send the establish-rendezvous cell along a rendezvous circuit. if
   77  * it fails, mark the circ for close and return -1. else return 0.
   78  */
   79 static int
   80 rend_client_send_establish_rendezvous(origin_circuit_t *circ)
   81 {
   82   tor_assert(circ->base_.purpose == CIRCUIT_PURPOSE_C_ESTABLISH_REND);
   83   tor_assert(circ->rend_data);
   84   log_info(LD_REND, "Sending an ESTABLISH_RENDEZVOUS cell");
   85 
   86   crypto_rand(circ->rend_data->rend_cookie, REND_COOKIE_LEN);
   87 
   88   /* Set timestamp_dirty, because circuit_expire_building expects it,
   89    * and the rend cookie also means we've used the circ. */
   90   circ->base_.timestamp_dirty = time(NULL);
   91 
   92   /* We've attempted to use this circuit. Probe it if we fail */
   93   pathbias_count_use_attempt(circ);
   94 
   95   if (relay_send_command_from_edge(0, TO_CIRCUIT(circ),
   96                                    RELAY_COMMAND_ESTABLISH_RENDEZVOUS,
   97                                    circ->rend_data->rend_cookie,
   98                                    REND_COOKIE_LEN,
   99                                    circ->cpath->prev)<0) {
  100     /* circ is already marked for close */
  101     log_warn(LD_GENERAL, "Couldn't send ESTABLISH_RENDEZVOUS cell");
  102     return -1;
  103   }
  104 
  105   return 0;
  106 }
  107 
  108 /** Called when we're trying to connect an ap conn; sends an INTRODUCE1 cell
  109  * down introcirc if possible.
  110  */
  111 int
  112 rend_client_send_introduction(origin_circuit_t *introcirc,
  113                               origin_circuit_t *rendcirc)
  114 {
  115   const or_options_t *options = get_options();
  116   size_t payload_len;
  117   int r, v3_shift = 0;
  118   char payload[RELAY_PAYLOAD_SIZE];
  119   char tmp[RELAY_PAYLOAD_SIZE];
  120   rend_cache_entry_t *entry = NULL;
  121   crypt_path_t *cpath;
  122   off_t dh_offset;
  123   crypto_pk_t *intro_key = NULL;
  124   int status = 0;
  125   const char *onion_address;
  126 
  127   tor_assert(introcirc->base_.purpose == CIRCUIT_PURPOSE_C_INTRODUCING);
  128   tor_assert(rendcirc->base_.purpose == CIRCUIT_PURPOSE_C_REND_READY);
  129   tor_assert(introcirc->rend_data);
  130   tor_assert(rendcirc->rend_data);
  131   tor_assert(!rend_cmp_service_ids(rend_data_get_address(introcirc->rend_data),
  132                                   rend_data_get_address(rendcirc->rend_data)));
  133   assert_circ_anonymity_ok(introcirc, options);
  134   assert_circ_anonymity_ok(rendcirc, options);
  135   onion_address = rend_data_get_address(introcirc->rend_data);
  136 
  137   r = rend_cache_lookup_entry(onion_address, -1, &entry);
  138   /* An invalid onion address is not possible else we have a big issue. */
  139   tor_assert(r != -EINVAL);
  140   if (r < 0 || !rend_client_any_intro_points_usable(entry)) {
  141     /* If the descriptor is not found or the intro points are not usable
  142      * anymore, trigger a fetch. */
  143     log_info(LD_REND,
  144              "query %s didn't have valid rend desc in cache. "
  145              "Refetching descriptor.",
  146              safe_str_client(onion_address));
  147     rend_client_refetch_v2_renddesc(introcirc->rend_data);
  148     {
  149       connection_t *conn;
  150 
  151       while ((conn = connection_get_by_type_state_rendquery(CONN_TYPE_AP,
  152                        AP_CONN_STATE_CIRCUIT_WAIT, onion_address))) {
  153         connection_ap_mark_as_waiting_for_renddesc(TO_ENTRY_CONN(conn));
  154       }
  155     }
  156 
  157     status = -1;
  158     goto cleanup;
  159   }
  160 
  161   /* first 20 bytes of payload are the hash of the service's pk */
  162   intro_key = NULL;
  163   SMARTLIST_FOREACH(entry->parsed->intro_nodes, rend_intro_point_t *,
  164                     intro, {
  165     if (tor_memeq(introcirc->build_state->chosen_exit->identity_digest,
  166                 intro->extend_info->identity_digest, DIGEST_LEN)) {
  167       intro_key = intro->intro_key;
  168       break;
  169     }
  170   });
  171   if (!intro_key) {
  172     log_info(LD_REND, "Could not find intro key for %s at %s; we "
  173              "have a v2 rend desc with %d intro points. "
  174              "Trying a different intro point...",
  175              safe_str_client(onion_address),
  176              safe_str_client(extend_info_describe(
  177                                    introcirc->build_state->chosen_exit)),
  178              smartlist_len(entry->parsed->intro_nodes));
  179 
  180     if (hs_client_reextend_intro_circuit(introcirc)) {
  181       status = -2;
  182       goto perm_err;
  183     } else {
  184       status = -1;
  185       goto cleanup;
  186     }
  187   }
  188   if (crypto_pk_get_digest(intro_key, payload)<0) {
  189     log_warn(LD_BUG, "Internal error: couldn't hash public key.");
  190     status = -2;
  191     goto perm_err;
  192   }
  193 
  194   /* Initialize the pending_final_cpath and start the DH handshake. */
  195   cpath = rendcirc->build_state->pending_final_cpath;
  196   if (!cpath) {
  197     cpath = rendcirc->build_state->pending_final_cpath =
  198       tor_malloc_zero(sizeof(crypt_path_t));
  199     cpath->magic = CRYPT_PATH_MAGIC;
  200     if (!(cpath->rend_dh_handshake_state = crypto_dh_new(DH_TYPE_REND))) {
  201       log_warn(LD_BUG, "Internal error: couldn't allocate DH.");
  202       status = -2;
  203       goto perm_err;
  204     }
  205     if (crypto_dh_generate_public(cpath->rend_dh_handshake_state)<0) {
  206       log_warn(LD_BUG, "Internal error: couldn't generate g^x.");
  207       status = -2;
  208       goto perm_err;
  209     }
  210   }
  211 
  212   /* If version is 3, write (optional) auth data and timestamp. */
  213   if (entry->parsed->protocols & (1<<3)) {
  214     tmp[0] = 3; /* version 3 of the cell format */
  215     /* auth type, if any */
  216     tmp[1] = (uint8_t) TO_REND_DATA_V2(introcirc->rend_data)->auth_type;
  217     v3_shift = 1;
  218     if (tmp[1] != REND_NO_AUTH) {
  219       set_uint16(tmp+2, htons(REND_DESC_COOKIE_LEN));
  220       memcpy(tmp+4, TO_REND_DATA_V2(introcirc->rend_data)->descriptor_cookie,
  221              REND_DESC_COOKIE_LEN);
  222       v3_shift += 2+REND_DESC_COOKIE_LEN;
  223     }
  224     /* Once this held a timestamp. */
  225     set_uint32(tmp+v3_shift+1, 0);
  226     v3_shift += 4;
  227   } /* if version 2 only write version number */
  228   else if (entry->parsed->protocols & (1<<2)) {
  229     tmp[0] = 2; /* version 2 of the cell format */
  230   }
  231 
  232   /* write the remaining items into tmp */
  233   if (entry->parsed->protocols & (1<<3) || entry->parsed->protocols & (1<<2)) {
  234     /* version 2 format */
  235     extend_info_t *extend_info = rendcirc->build_state->chosen_exit;
  236     int klen;
  237     /* nul pads */
  238     set_uint32(tmp+v3_shift+1, tor_addr_to_ipv4n(&extend_info->addr));
  239     set_uint16(tmp+v3_shift+5, htons(extend_info->port));
  240     memcpy(tmp+v3_shift+7, extend_info->identity_digest, DIGEST_LEN);
  241     klen = crypto_pk_asn1_encode(extend_info->onion_key,
  242                                  tmp+v3_shift+7+DIGEST_LEN+2,
  243                                  sizeof(tmp)-(v3_shift+7+DIGEST_LEN+2));
  244     if (klen < 0) {
  245       log_warn(LD_BUG,"Internal error: can't encode public key.");
  246       status = -2;
  247       goto perm_err;
  248     }
  249     set_uint16(tmp+v3_shift+7+DIGEST_LEN, htons(klen));
  250     memcpy(tmp+v3_shift+7+DIGEST_LEN+2+klen, rendcirc->rend_data->rend_cookie,
  251            REND_COOKIE_LEN);
  252     dh_offset = v3_shift+7+DIGEST_LEN+2+klen+REND_COOKIE_LEN;
  253   } else {
  254     /* Version 0. */
  255 
  256     /* Some compilers are smart enough to work out that nickname can be more
  257      * than 19 characters, when it's a hexdigest. They warn that strncpy()
  258      * will truncate hexdigests without NUL-terminating them. But we only put
  259      * hexdigests in HSDir and general circuit exits. */
  260     if (BUG(strlen(rendcirc->build_state->chosen_exit->nickname)
  261             > MAX_NICKNAME_LEN)) {
  262       goto perm_err;
  263     }
  264     strncpy(tmp, rendcirc->build_state->chosen_exit->nickname,
  265             (MAX_NICKNAME_LEN+1)); /* nul pads */
  266     memcpy(tmp+MAX_NICKNAME_LEN+1, rendcirc->rend_data->rend_cookie,
  267            REND_COOKIE_LEN);
  268     dh_offset = MAX_NICKNAME_LEN+1+REND_COOKIE_LEN;
  269   }
  270 
  271   if (crypto_dh_get_public(cpath->rend_dh_handshake_state, tmp+dh_offset,
  272                            DH1024_KEY_LEN)<0) {
  273     log_warn(LD_BUG, "Internal error: couldn't extract g^x.");
  274     status = -2;
  275     goto perm_err;
  276   }
  277 
  278   /*XXX maybe give crypto_pk_obsolete_public_hybrid_encrypt a max_len arg,
  279    * to avoid buffer overflows? */
  280   r = crypto_pk_obsolete_public_hybrid_encrypt(intro_key, payload+DIGEST_LEN,
  281                                       sizeof(payload)-DIGEST_LEN,
  282                                       tmp,
  283                                       (int)(dh_offset+DH1024_KEY_LEN),
  284                                       PK_PKCS1_OAEP_PADDING, 0);
  285   if (r<0) {
  286     log_warn(LD_BUG,"Internal error: hybrid pk encrypt failed.");
  287     status = -2;
  288     goto perm_err;
  289   }
  290 
  291   payload_len = DIGEST_LEN + r;
  292   tor_assert(payload_len <= RELAY_PAYLOAD_SIZE); /* we overran something */
  293 
  294   /* Copy the rendezvous cookie from rendcirc to introcirc, so that
  295    * when introcirc gets an ack, we can change the state of the right
  296    * rendezvous circuit. */
  297   memcpy(introcirc->rend_data->rend_cookie, rendcirc->rend_data->rend_cookie,
  298          REND_COOKIE_LEN);
  299 
  300   log_info(LD_REND, "Sending an INTRODUCE1 cell");
  301   if (relay_send_command_from_edge(0, TO_CIRCUIT(introcirc),
  302                                    RELAY_COMMAND_INTRODUCE1,
  303                                    payload, payload_len,
  304                                    introcirc->cpath->prev)<0) {
  305     /* introcirc is already marked for close. leave rendcirc alone. */
  306     log_warn(LD_BUG, "Couldn't send INTRODUCE1 cell");
  307     status = -2;
  308     goto cleanup;
  309   }
  310 
  311   /* Now, we wait for an ACK or NAK on this circuit. */
  312   circuit_change_purpose(TO_CIRCUIT(introcirc),
  313                          CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT);
  314   /* Set timestamp_dirty, because circuit_expire_building expects it
  315    * to specify when a circuit entered the _C_INTRODUCE_ACK_WAIT
  316    * state. */
  317   introcirc->base_.timestamp_dirty = time(NULL);
  318 
  319   pathbias_count_use_attempt(introcirc);
  320 
  321   goto cleanup;
  322 
  323  perm_err:
  324   if (!introcirc->base_.marked_for_close)
  325     circuit_mark_for_close(TO_CIRCUIT(introcirc), END_CIRC_REASON_INTERNAL);
  326   circuit_mark_for_close(TO_CIRCUIT(rendcirc), END_CIRC_REASON_INTERNAL);
  327  cleanup:
  328   memwipe(payload, 0, sizeof(payload));
  329   memwipe(tmp, 0, sizeof(tmp));
  330 
  331   return status;
  332 }
  333 
  334 /** Called when a rendezvous circuit is open; sends a establish
  335  * rendezvous circuit as appropriate. */
  336 void
  337 rend_client_rendcirc_has_opened(origin_circuit_t *circ)
  338 {
  339   tor_assert(circ->base_.purpose == CIRCUIT_PURPOSE_C_ESTABLISH_REND);
  340 
  341   log_info(LD_REND,"rendcirc is open");
  342 
  343   /* generate a rendezvous cookie, store it in circ */
  344   if (rend_client_send_establish_rendezvous(circ) < 0) {
  345     return;
  346   }
  347 }
  348 
  349 /**
  350  * Called to close other intro circuits we launched in parallel.
  351  */
  352 static void
  353 rend_client_close_other_intros(const uint8_t *rend_pk_digest)
  354 {
  355   /* abort parallel intro circs, if any */
  356   SMARTLIST_FOREACH_BEGIN(circuit_get_global_list(), circuit_t *, c) {
  357     if ((c->purpose == CIRCUIT_PURPOSE_C_INTRODUCING ||
  358         c->purpose == CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT) &&
  359         !c->marked_for_close && CIRCUIT_IS_ORIGIN(c)) {
  360       origin_circuit_t *oc = TO_ORIGIN_CIRCUIT(c);
  361       if (oc->rend_data &&
  362           rend_circuit_pk_digest_eq(oc, rend_pk_digest)) {
  363         log_info(LD_REND|LD_CIRC, "Closing introduction circuit %d that we "
  364                  "built in parallel (Purpose %d).", oc->global_identifier,
  365                  c->purpose);
  366         circuit_mark_for_close(c, END_CIRC_REASON_IP_NOW_REDUNDANT);
  367       }
  368     }
  369   }
  370   SMARTLIST_FOREACH_END(c);
  371 }
  372 
  373 /** Called when get an ACK or a NAK for a REND_INTRODUCE1 cell.
  374  */
  375 int
  376 rend_client_introduction_acked(origin_circuit_t *circ,
  377                                const uint8_t *request, size_t request_len)
  378 {
  379   const or_options_t *options = get_options();
  380   origin_circuit_t *rendcirc;
  381   (void) request; // XXXX Use this.
  382 
  383   tor_assert(circ->build_state);
  384   tor_assert(circ->build_state->chosen_exit);
  385   assert_circ_anonymity_ok(circ, options);
  386   tor_assert(circ->rend_data);
  387 
  388   if (request_len == 0) {
  389     /* It's an ACK; the introduction point relayed our introduction request. */
  390     /* Locate the rend circ which is waiting to hear about this ack,
  391      * and tell it.
  392      */
  393     log_info(LD_REND,"Received ack. Telling rend circ...");
  394     rendcirc = circuit_get_ready_rend_circ_by_rend_data(circ->rend_data);
  395     if (rendcirc) { /* remember the ack */
  396       assert_circ_anonymity_ok(rendcirc, options);
  397       circuit_change_purpose(TO_CIRCUIT(rendcirc),
  398                              CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED);
  399       /* Set timestamp_dirty, because circuit_expire_building expects
  400        * it to specify when a circuit entered the
  401        * _C_REND_READY_INTRO_ACKED state. */
  402       rendcirc->base_.timestamp_dirty = time(NULL);
  403     } else {
  404       log_info(LD_REND,"...Found no rend circ. Dropping on the floor.");
  405     }
  406     /* Save the rend data digest to a temporary object so that we don't access
  407      * it after we mark the circuit for close. */
  408     const uint8_t *rend_digest_tmp = NULL;
  409     size_t digest_len;
  410     uint8_t *cached_rend_digest = NULL;
  411     rend_digest_tmp = rend_data_get_pk_digest(circ->rend_data, &digest_len);
  412     cached_rend_digest = tor_malloc_zero(digest_len);
  413     memcpy(cached_rend_digest, rend_digest_tmp, digest_len);
  414 
  415     /* close the circuit: we won't need it anymore. */
  416     circuit_change_purpose(TO_CIRCUIT(circ),
  417                            CIRCUIT_PURPOSE_C_INTRODUCE_ACKED);
  418     circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_FINISHED);
  419 
  420     /* close any other intros launched in parallel */
  421     rend_client_close_other_intros(cached_rend_digest);
  422     tor_free(cached_rend_digest); /* free the temporary digest */
  423   } else {
  424     /* It's a NAK; the introduction point didn't relay our request. */
  425     circuit_change_purpose(TO_CIRCUIT(circ), CIRCUIT_PURPOSE_C_INTRODUCING);
  426     /* Remove this intro point from the set of viable introduction
  427      * points. If any remain, extend to a new one and try again.
  428      * If none remain, refetch the service descriptor.
  429      */
  430     log_info(LD_REND, "Got nack for %s from %s...",
  431         safe_str_client(rend_data_get_address(circ->rend_data)),
  432         safe_str_client(extend_info_describe(circ->build_state->chosen_exit)));
  433     if (rend_client_report_intro_point_failure(circ->build_state->chosen_exit,
  434                                              circ->rend_data,
  435                                              INTRO_POINT_FAILURE_GENERIC)>0) {
  436       /* There are introduction points left. Re-extend the circuit to
  437        * another intro point and try again. */
  438       int result = hs_client_reextend_intro_circuit(circ);
  439       /* XXXX If that call failed, should we close the rend circuit,
  440        * too? */
  441       return result;
  442     } else {
  443       /* Close circuit because no more intro points are usable thus not
  444        * useful anymore. Change it's purpose before so we don't report an
  445        * intro point failure again triggering an extra descriptor fetch. */
  446       circuit_change_purpose(TO_CIRCUIT(circ),
  447           CIRCUIT_PURPOSE_C_INTRODUCE_ACKED);
  448       circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_FINISHED);
  449     }
  450   }
  451   return 0;
  452 }
  453 
  454 /** Determine the responsible hidden service directories for <b>desc_id</b>
  455  * and fetch the descriptor with that ID from one of them. Only
  456  * send a request to a hidden service directory that we have not yet tried
  457  * during this attempt to connect to this hidden service; on success, return 1,
  458  * in the case that no hidden service directory is left to ask for the
  459  * descriptor, return 0, and in case of a failure -1.  */
  460 static int
  461 directory_get_from_hs_dir(const char *desc_id,
  462                           const rend_data_t *rend_query,
  463                           routerstatus_t *rs_hsdir)
  464 {
  465   routerstatus_t *hs_dir = rs_hsdir;
  466   char *hsdir_fp;
  467   char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
  468   char descriptor_cookie_base64[3*REND_DESC_COOKIE_LEN_BASE64];
  469   const rend_data_v2_t *rend_data;
  470   const int how_to_fetch = DIRIND_ANONYMOUS;
  471 
  472   tor_assert(desc_id);
  473   tor_assert(rend_query);
  474   rend_data = TO_REND_DATA_V2(rend_query);
  475 
  476   base32_encode(desc_id_base32, sizeof(desc_id_base32),
  477                 desc_id, DIGEST_LEN);
  478 
  479   /* Automatically pick an hs dir if none given. */
  480   if (!rs_hsdir) {
  481     bool rate_limited = false;
  482 
  483     /* Determine responsible dirs. Even if we can't get all we want, work with
  484      * the ones we have. If it's empty, we'll notice in hs_pick_hsdir(). */
  485     smartlist_t *responsible_dirs = smartlist_new();
  486     hid_serv_get_responsible_directories(responsible_dirs, desc_id);
  487 
  488     hs_dir = hs_pick_hsdir(responsible_dirs, desc_id_base32, &rate_limited);
  489     if (!hs_dir) {
  490       /* No suitable hs dir can be found, stop right now. */
  491       const char *query_response = (rate_limited) ? "QUERY_RATE_LIMITED" :
  492                                                     "QUERY_NO_HSDIR";
  493       control_event_hsv2_descriptor_failed(rend_query, NULL, query_response);
  494       control_event_hs_descriptor_content(rend_data_get_address(rend_query),
  495                                           desc_id_base32, NULL, NULL);
  496       return 0;
  497     }
  498   }
  499 
  500   /* Add a copy of the HSDir identity digest to the query so we can track it
  501    * on the control port. */
  502   hsdir_fp = tor_memdup(hs_dir->identity_digest,
  503                         sizeof(hs_dir->identity_digest));
  504   smartlist_add(rend_query->hsdirs_fp, hsdir_fp);
  505 
  506   /* Encode descriptor cookie for logging purposes. Also, if the cookie is
  507    * malformed, no fetch is triggered thus this needs to be done before the
  508    * fetch request. */
  509   if (rend_data->auth_type != REND_NO_AUTH) {
  510     if (base64_encode(descriptor_cookie_base64,
  511                       sizeof(descriptor_cookie_base64),
  512                       rend_data->descriptor_cookie,
  513                       REND_DESC_COOKIE_LEN,
  514                       0)<0) {
  515       log_warn(LD_BUG, "Could not base64-encode descriptor cookie.");
  516       control_event_hsv2_descriptor_failed(rend_query, hsdir_fp, "BAD_DESC");
  517       control_event_hs_descriptor_content(rend_data_get_address(rend_query),
  518                                           desc_id_base32, hsdir_fp, NULL);
  519       return 0;
  520     }
  521     /* Remove == signs. */
  522     descriptor_cookie_base64[strlen(descriptor_cookie_base64)-2] = '\0';
  523   } else {
  524     strlcpy(descriptor_cookie_base64, "(none)",
  525             sizeof(descriptor_cookie_base64));
  526   }
  527 
  528   /* Send fetch request. (Pass query and possibly descriptor cookie so that
  529    * they can be written to the directory connection and be referred to when
  530    * the response arrives. */
  531   directory_request_t *req =
  532     directory_request_new(DIR_PURPOSE_FETCH_RENDDESC_V2);
  533   directory_request_set_routerstatus(req, hs_dir);
  534   directory_request_set_indirection(req, how_to_fetch);
  535   directory_request_set_resource(req, desc_id_base32);
  536   directory_request_set_rend_query(req, rend_query);
  537   directory_initiate_request(req);
  538   directory_request_free(req);
  539 
  540   log_info(LD_REND, "Sending fetch request for v2 descriptor for "
  541                     "service '%s' with descriptor ID '%s', auth type %d, "
  542                     "and descriptor cookie '%s' to hidden service "
  543                     "directory %s",
  544            rend_data->onion_address, desc_id_base32,
  545            rend_data->auth_type,
  546            (rend_data->auth_type == REND_NO_AUTH ? "[none]" :
  547             escaped_safe_str_client(descriptor_cookie_base64)),
  548            routerstatus_describe(hs_dir));
  549   control_event_hs_descriptor_requested(rend_data->onion_address,
  550                                         rend_data->auth_type,
  551                                         hs_dir->identity_digest,
  552                                         desc_id_base32, NULL);
  553   return 1;
  554 }
  555 
  556 /** Remove tracked HSDir requests from our history for this hidden service
  557  *  descriptor <b>desc_id</b> (of size DIGEST_LEN) */
  558 static void
  559 purge_v2_hidserv_req(const char *desc_id)
  560 {
  561   char desc_id_base32[REND_DESC_ID_V2_LEN_BASE32 + 1];
  562 
  563   /* The hsdir request tracker stores v2 keys using the base32 encoded
  564      desc_id. Do it: */
  565   base32_encode(desc_id_base32, sizeof(desc_id_base32), desc_id,
  566                 DIGEST_LEN);
  567   hs_purge_hid_serv_from_last_hid_serv_requests(desc_id_base32);
  568 }
  569 
  570 /** Fetch a v2 descriptor using the given descriptor id. If any hsdir(s) are
  571  * given, they will be used instead.
  572  *
  573  * On success, 1 is returned. If no hidden service is left to ask, return 0.
  574  * On error, -1 is returned. */
  575 static int
  576 fetch_v2_desc_by_descid(const char *desc_id,
  577                         const rend_data_t *rend_query, smartlist_t *hsdirs)
  578 {
  579   int ret;
  580 
  581   tor_assert(rend_query);
  582 
  583   if (!hsdirs) {
  584     ret = directory_get_from_hs_dir(desc_id, rend_query, NULL);
  585     goto end; /* either success or failure, but we're done */
  586   }
  587 
  588   /* Using the given hsdir list, trigger a fetch on each of them. */
  589   SMARTLIST_FOREACH_BEGIN(hsdirs, routerstatus_t *, hs_dir) {
  590     /* This should always be a success. */
  591     ret = directory_get_from_hs_dir(desc_id, rend_query, hs_dir);
  592     tor_assert(ret);
  593   } SMARTLIST_FOREACH_END(hs_dir);
  594 
  595   /* Everything went well. */
  596   ret = 0;
  597 
  598  end:
  599   return ret;
  600 }
  601 
  602 /** Fetch a v2 descriptor using the onion address in the given query object.
  603  * This will compute the descriptor id for each replicas and fetch it on the
  604  * given hsdir(s) if any or the responsible ones that are chosen
  605  * automatically.
  606  *
  607  * On success, 1 is returned. If no hidden service is left to ask, return 0.
  608  * On error, -1 is returned. */
  609 static int
  610 fetch_v2_desc_by_addr(rend_data_t *rend_query, smartlist_t *hsdirs)
  611 {
  612   char descriptor_id[DIGEST_LEN];
  613   int replicas_left_to_try[REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS];
  614   int i, tries_left, ret;
  615   rend_data_v2_t *rend_data = TO_REND_DATA_V2(rend_query);
  616 
  617   /* Randomly iterate over the replicas until a descriptor can be fetched
  618    * from one of the consecutive nodes, or no options are left. */
  619   for (i = 0; i < REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS; i++) {
  620     replicas_left_to_try[i] = i;
  621   }
  622 
  623   tries_left = REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS;
  624   while (tries_left > 0) {
  625     int rand_val = crypto_rand_int(tries_left);
  626     int chosen_replica = replicas_left_to_try[rand_val];
  627     replicas_left_to_try[rand_val] = replicas_left_to_try[--tries_left];
  628 
  629     ret = rend_compute_v2_desc_id(descriptor_id,
  630                                   rend_data->onion_address,
  631                                   rend_data->auth_type == REND_STEALTH_AUTH ?
  632                                     rend_data->descriptor_cookie : NULL,
  633                                   time(NULL), chosen_replica);
  634     if (ret < 0) {
  635       /* Normally, on failure the descriptor_id is untouched but let's be
  636        * safe in general in case the function changes at some point. */
  637       goto end;
  638     }
  639 
  640     if (tor_memcmp(descriptor_id, rend_data->descriptor_id[chosen_replica],
  641                    sizeof(descriptor_id)) != 0) {
  642       /* Not equal from what we currently have so purge the last hid serv
  643        * request cache and update the descriptor ID with the new value. */
  644       purge_v2_hidserv_req(rend_data->descriptor_id[chosen_replica]);
  645       memcpy(rend_data->descriptor_id[chosen_replica], descriptor_id,
  646              sizeof(rend_data->descriptor_id[chosen_replica]));
  647     }
  648 
  649     /* Trigger the fetch with the computed descriptor ID. */
  650     ret = fetch_v2_desc_by_descid(descriptor_id, rend_query, hsdirs);
  651     if (ret != 0) {
  652       /* Either on success or failure, as long as we tried a fetch we are
  653        * done here. */
  654       goto end;
  655     }
  656   }
  657 
  658   /* If we come here, there are no hidden service directories left. */
  659   log_info(LD_REND, "Could not pick one of the responsible hidden "
  660                     "service directories to fetch descriptors, because "
  661                     "we already tried them all unsuccessfully.");
  662   ret = 0;
  663 
  664  end:
  665   memwipe(descriptor_id, 0, sizeof(descriptor_id));
  666   return ret;
  667 }
  668 
  669 /** Fetch a v2 descriptor using the given query. If any hsdir are specified,
  670  * use them for the fetch.
  671  *
  672  * On success, 1 is returned. If no hidden service is left to ask, return 0.
  673  * On error, -1 is returned. */
  674 int
  675 rend_client_fetch_v2_desc(rend_data_t *query, smartlist_t *hsdirs)
  676 {
  677   int ret;
  678   rend_data_v2_t *rend_data;
  679   const char *onion_address;
  680 
  681   tor_assert(query);
  682 
  683   /* Get the version 2 data structure of the query. */
  684   rend_data = TO_REND_DATA_V2(query);
  685   onion_address = rend_data_get_address(query);
  686 
  687   /* Depending on what's available in the rend data query object, we will
  688    * trigger a fetch by HS address or using a descriptor ID. */
  689 
  690   if (onion_address[0] != '\0') {
  691     ret = fetch_v2_desc_by_addr(query, hsdirs);
  692   } else if (!tor_digest_is_zero(rend_data->desc_id_fetch)) {
  693     ret = fetch_v2_desc_by_descid(rend_data->desc_id_fetch, query,
  694                                   hsdirs);
  695   } else {
  696     /* Query data is invalid. */
  697     ret = -1;
  698     goto error;
  699   }
  700 
  701  error:
  702   return ret;
  703 }
  704 
  705 /** Unless we already have a descriptor for <b>rend_query</b> with at least
  706  * one (possibly) working introduction point in it, start a connection to a
  707  * hidden service directory to fetch a v2 rendezvous service descriptor. */
  708 void
  709 rend_client_refetch_v2_renddesc(rend_data_t *rend_query)
  710 {
  711   rend_cache_entry_t *e = NULL;
  712   const char *onion_address = rend_data_get_address(rend_query);
  713 
  714   tor_assert(rend_query);
  715   /* Before fetching, check if we already have a usable descriptor here. */
  716   if (rend_cache_lookup_entry(onion_address, -1, &e) == 0 &&
  717       rend_client_any_intro_points_usable(e)) {
  718     log_info(LD_REND, "We would fetch a v2 rendezvous descriptor, but we "
  719                       "already have a usable descriptor here. Not fetching.");
  720     return;
  721   }
  722   /* Are we configured to fetch descriptors? */
  723   if (!get_options()->FetchHidServDescriptors) {
  724     log_warn(LD_REND, "We received an onion address for a v2 rendezvous "
  725         "service descriptor, but are not fetching service descriptors.");
  726     return;
  727   }
  728   log_debug(LD_REND, "Fetching v2 rendezvous descriptor for service %s",
  729             safe_str_client(onion_address));
  730 
  731   rend_client_fetch_v2_desc(rend_query, NULL);
  732   /* We don't need to look the error code because either on failure or
  733    * success, the necessary steps to continue the HS connection will be
  734    * triggered once the descriptor arrives or if all fetch failed. */
  735   return;
  736 }
  737 
  738 /** Cancel all rendezvous descriptor fetches currently in progress.
  739  */
  740 void
  741 rend_client_cancel_descriptor_fetches(void)
  742 {
  743   smartlist_t *connection_array = get_connection_array();
  744 
  745   SMARTLIST_FOREACH_BEGIN(connection_array, connection_t *, conn) {
  746     if (conn->type == CONN_TYPE_DIR &&
  747         conn->purpose == DIR_PURPOSE_FETCH_RENDDESC_V2) {
  748       /* It's a rendezvous descriptor fetch in progress -- cancel it
  749        * by marking the connection for close.
  750        *
  751        * Even if this connection has already reached EOF, this is
  752        * enough to make sure that if the descriptor hasn't been
  753        * processed yet, it won't be.  See the end of
  754        * connection_handle_read; connection_reached_eof (indirectly)
  755        * processes whatever response the connection received. */
  756 
  757       const rend_data_t *rd = (TO_DIR_CONN(conn))->rend_data;
  758       if (!rd) {
  759         log_warn(LD_BUG | LD_REND,
  760                  "Marking for close dir conn fetching rendezvous "
  761                  "descriptor for unknown service!");
  762       } else {
  763         log_debug(LD_REND, "Marking for close dir conn fetching "
  764                   "rendezvous descriptor for service %s",
  765                   safe_str(rend_data_get_address(rd)));
  766       }
  767       connection_mark_for_close(conn);
  768     }
  769   } SMARTLIST_FOREACH_END(conn);
  770 }
  771 
  772 /** Mark <b>failed_intro</b> as a failed introduction point for the
  773  * hidden service specified by <b>rend_query</b>. If the HS now has no
  774  * usable intro points, or we do not have an HS descriptor for it,
  775  * then launch a new renddesc fetch.
  776  *
  777  * If <b>failure_type</b> is INTRO_POINT_FAILURE_GENERIC, remove the
  778  * intro point from (our parsed copy of) the HS descriptor.
  779  *
  780  * If <b>failure_type</b> is INTRO_POINT_FAILURE_TIMEOUT, mark the
  781  * intro point as 'timed out'; it will not be retried until the
  782  * current hidden service connection attempt has ended or it has
  783  * appeared in a newly fetched rendezvous descriptor.
  784  *
  785  * If <b>failure_type</b> is INTRO_POINT_FAILURE_UNREACHABLE,
  786  * increment the intro point's reachability-failure count; if it has
  787  * now failed MAX_INTRO_POINT_REACHABILITY_FAILURES or more times,
  788  * remove the intro point from (our parsed copy of) the HS descriptor.
  789  *
  790  * Return -1 if error, 0 if no usable intro points remain or service
  791  * unrecognized, 1 if recognized and some intro points remain.
  792  */
  793 int
  794 rend_client_report_intro_point_failure(extend_info_t *failed_intro,
  795                                        rend_data_t *rend_data,
  796                                        unsigned int failure_type)
  797 {
  798   int i, r;
  799   rend_cache_entry_t *ent;
  800   connection_t *conn;
  801   const char *onion_address = rend_data_get_address(rend_data);
  802 
  803   r = rend_cache_lookup_entry(onion_address, -1, &ent);
  804   if (r < 0) {
  805     /* Either invalid onion address or cache entry not found. */
  806     switch (-r) {
  807     case EINVAL:
  808       log_warn(LD_BUG, "Malformed service ID %s.",
  809                escaped_safe_str_client(onion_address));
  810       return -1;
  811     case ENOENT:
  812       log_info(LD_REND, "Unknown service %s. Re-fetching descriptor.",
  813                escaped_safe_str_client(onion_address));
  814       rend_client_refetch_v2_renddesc(rend_data);
  815       return 0;
  816     default:
  817       log_warn(LD_BUG, "Unknown cache lookup returned code: %d", r);
  818       return -1;
  819     }
  820   }
  821   /* The intro points are not checked here if they are usable or not because
  822    * this is called when an intro point circuit is closed thus there must be
  823    * at least one intro point that is usable and is about to be flagged. */
  824 
  825   for (i = 0; i < smartlist_len(ent->parsed->intro_nodes); i++) {
  826     rend_intro_point_t *intro = smartlist_get(ent->parsed->intro_nodes, i);
  827     if (tor_memeq(failed_intro->identity_digest,
  828                 intro->extend_info->identity_digest, DIGEST_LEN)) {
  829       switch (failure_type) {
  830       default:
  831         log_warn(LD_BUG, "Unknown failure type %u. Removing intro point.",
  832                  failure_type);
  833         tor_fragile_assert();
  834         /* fall through */
  835       case INTRO_POINT_FAILURE_GENERIC:
  836         rend_cache_intro_failure_note(failure_type,
  837                                       (uint8_t *)failed_intro->identity_digest,
  838                                       onion_address);
  839         rend_intro_point_free(intro);
  840         smartlist_del(ent->parsed->intro_nodes, i);
  841         break;
  842       case INTRO_POINT_FAILURE_TIMEOUT:
  843         intro->timed_out = 1;
  844         break;
  845       case INTRO_POINT_FAILURE_UNREACHABLE:
  846         ++(intro->unreachable_count);
  847         {
  848           int zap_intro_point =
  849             intro->unreachable_count >= MAX_INTRO_POINT_REACHABILITY_FAILURES;
  850           log_info(LD_REND, "Failed to reach this intro point %u times.%s",
  851                    intro->unreachable_count,
  852                    zap_intro_point ? " Removing from descriptor.": "");
  853           if (zap_intro_point) {
  854             rend_cache_intro_failure_note(
  855                 failure_type,
  856                 (uint8_t *) failed_intro->identity_digest, onion_address);
  857             rend_intro_point_free(intro);
  858             smartlist_del(ent->parsed->intro_nodes, i);
  859           }
  860         }
  861         break;
  862       }
  863       break;
  864     }
  865   }
  866 
  867   if (! rend_client_any_intro_points_usable(ent)) {
  868     log_info(LD_REND,
  869              "No more intro points remain for %s. Re-fetching descriptor.",
  870              escaped_safe_str_client(onion_address));
  871     rend_client_refetch_v2_renddesc(rend_data);
  872 
  873     /* move all pending streams back to renddesc_wait */
  874     /* NOTE: We can now do this faster, if we use pending_entry_connections */
  875     while ((conn = connection_get_by_type_state_rendquery(CONN_TYPE_AP,
  876                                    AP_CONN_STATE_CIRCUIT_WAIT,
  877                                    onion_address))) {
  878       connection_ap_mark_as_waiting_for_renddesc(TO_ENTRY_CONN(conn));
  879     }
  880 
  881     return 0;
  882   }
  883   log_info(LD_REND,"%d options left for %s.",
  884            smartlist_len(ent->parsed->intro_nodes),
  885            escaped_safe_str_client(onion_address));
  886   return 1;
  887 }
  888 
  889 /** The service sent us a rendezvous cell; join the circuits. */
  890 int
  891 rend_client_receive_rendezvous(origin_circuit_t *circ, const uint8_t *request,
  892                                size_t request_len)
  893 {
  894   if (request_len != DH1024_KEY_LEN+DIGEST_LEN) {
  895     log_warn(LD_PROTOCOL,"Incorrect length (%d) on RENDEZVOUS2 cell.",
  896              (int)request_len);
  897     goto err;
  898   }
  899 
  900   if (hs_circuit_setup_e2e_rend_circ_legacy_client(circ, request) < 0) {
  901     log_warn(LD_GENERAL, "Failed to setup circ");
  902     goto err;
  903   }
  904   return 0;
  905 
  906  err:
  907   circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_TORPROTOCOL);
  908   return -1;
  909 }
  910 
  911 /** Find all the apconns in state AP_CONN_STATE_RENDDESC_WAIT that are
  912  * waiting on <b>query</b>. If there's a working cache entry here with at
  913  * least one intro point, move them to the next state. */
  914 void
  915 rend_client_desc_trynow(const char *query)
  916 {
  917   entry_connection_t *conn;
  918   rend_cache_entry_t *entry;
  919   const rend_data_t *rend_data;
  920   time_t now = time(NULL);
  921 
  922   smartlist_t *conns = get_connection_array();
  923   SMARTLIST_FOREACH_BEGIN(conns, connection_t *, base_conn) {
  924     if (base_conn->type != CONN_TYPE_AP ||
  925         base_conn->state != AP_CONN_STATE_RENDDESC_WAIT ||
  926         base_conn->marked_for_close)
  927       continue;
  928     conn = TO_ENTRY_CONN(base_conn);
  929     rend_data = ENTRY_TO_EDGE_CONN(conn)->rend_data;
  930     if (!rend_data)
  931       continue;
  932     const char *onion_address = rend_data_get_address(rend_data);
  933     if (rend_cmp_service_ids(query, onion_address))
  934       continue;
  935     assert_connection_ok(base_conn, now);
  936     if (rend_cache_lookup_entry(onion_address, -1,
  937                                 &entry) == 0 &&
  938         rend_client_any_intro_points_usable(entry)) {
  939       /* either this fetch worked, or it failed but there was a
  940        * valid entry from before which we should reuse */
  941       log_info(LD_REND,"Rend desc is usable. Launching circuits.");
  942       base_conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
  943 
  944       /* restart their timeout values, so they get a fair shake at
  945        * connecting to the hidden service. */
  946       base_conn->timestamp_created = now;
  947       base_conn->timestamp_last_read_allowed = now;
  948       base_conn->timestamp_last_write_allowed = now;
  949 
  950       connection_ap_mark_as_pending_circuit(conn);
  951     } else { /* 404, or fetch didn't get that far */
  952       log_notice(LD_REND,"Closing stream for '%s.onion': hidden service is "
  953                  "unavailable (try again later).",
  954                  safe_str_client(query));
  955       connection_mark_unattached_ap(conn, END_STREAM_REASON_RESOLVEFAILED);
  956       rend_client_note_connection_attempt_ended(rend_data);
  957     }
  958   } SMARTLIST_FOREACH_END(base_conn);
  959 }
  960 
  961 /** Clear temporary state used only during an attempt to connect to the
  962  * hidden service with <b>rend_data</b>. Called when a connection attempt
  963  * has ended; it is possible for this to be called multiple times while
  964  * handling an ended connection attempt, and any future changes to this
  965  * function must ensure it remains idempotent. */
  966 void
  967 rend_client_note_connection_attempt_ended(const rend_data_t *rend_data)
  968 {
  969   unsigned int have_onion = 0;
  970   rend_cache_entry_t *cache_entry = NULL;
  971   const char *onion_address = rend_data_get_address(rend_data);
  972   rend_data_v2_t *rend_data_v2 = TO_REND_DATA_V2(rend_data);
  973 
  974   if (onion_address[0] != '\0') {
  975     /* Ignore return value; we find an entry, or we don't. */
  976     (void) rend_cache_lookup_entry(onion_address, -1, &cache_entry);
  977     have_onion = 1;
  978   }
  979 
  980   /* Clear the timed_out flag on all remaining intro points for this HS. */
  981   if (cache_entry != NULL) {
  982     SMARTLIST_FOREACH(cache_entry->parsed->intro_nodes,
  983                       rend_intro_point_t *, ip,
  984                       ip->timed_out = 0; );
  985   }
  986 
  987   /* Remove the HS's entries in last_hid_serv_requests. */
  988   if (have_onion) {
  989     unsigned int replica;
  990     for (replica = 0; replica < ARRAY_LENGTH(rend_data_v2->descriptor_id);
  991          replica++) {
  992       const char *desc_id = rend_data_v2->descriptor_id[replica];
  993       purge_v2_hidserv_req(desc_id);
  994     }
  995     log_info(LD_REND, "Connection attempt for %s has ended; "
  996              "cleaning up temporary state.",
  997              safe_str_client(onion_address));
  998   } else {
  999     /* We only have an ID for a fetch. Probably used by HSFETCH. */
 1000     purge_v2_hidserv_req(rend_data_v2->desc_id_fetch);
 1001   }
 1002 }
 1003 
 1004 /** Return a newly allocated extend_info_t* for a randomly chosen introduction
 1005  * point for the named hidden service.  Return NULL if all introduction points
 1006  * have been tried and failed.
 1007  */
 1008 extend_info_t *
 1009 rend_client_get_random_intro(const rend_data_t *rend_query)
 1010 {
 1011   int ret;
 1012   extend_info_t *result;
 1013   rend_cache_entry_t *entry;
 1014   const char *onion_address = rend_data_get_address(rend_query);
 1015 
 1016   ret = rend_cache_lookup_entry(onion_address, -1, &entry);
 1017   if (ret < 0 || !rend_client_any_intro_points_usable(entry)) {
 1018     log_warn(LD_REND,
 1019              "Query '%s' didn't have valid rend desc in cache. Failing.",
 1020              safe_str_client(onion_address));
 1021     /* XXX: Should we refetch the descriptor here if the IPs are not usable
 1022      * anymore ?. */
 1023     return NULL;
 1024   }
 1025 
 1026   /* See if we can get a node that complies with ExcludeNodes */
 1027   if ((result = rend_client_get_random_intro_impl(entry, 1, 1)))
 1028     return result;
 1029   /* If not, and StrictNodes is not set, see if we can return any old node
 1030    */
 1031   if (!get_options()->StrictNodes)
 1032     return rend_client_get_random_intro_impl(entry, 0, 1);
 1033   return NULL;
 1034 }
 1035 
 1036 /** As rend_client_get_random_intro, except assume that StrictNodes is set
 1037  * iff <b>strict</b> is true. If <b>warnings</b> is false, don't complain
 1038  * to the user when we're out of nodes, even if StrictNodes is true.
 1039  */
 1040 static extend_info_t *
 1041 rend_client_get_random_intro_impl(const rend_cache_entry_t *entry,
 1042                                   const int strict,
 1043                                   const int warnings)
 1044 {
 1045   int i;
 1046 
 1047   rend_intro_point_t *intro;
 1048   const or_options_t *options = get_options();
 1049   smartlist_t *usable_nodes;
 1050   int n_excluded = 0;
 1051 
 1052   /* We'll keep a separate list of the usable nodes.  If this becomes empty,
 1053    * no nodes are usable.  */
 1054   usable_nodes = smartlist_new();
 1055   smartlist_add_all(usable_nodes, entry->parsed->intro_nodes);
 1056 
 1057   /* Remove the intro points that have timed out during this HS
 1058    * connection attempt from our list of usable nodes. */
 1059   SMARTLIST_FOREACH(usable_nodes, rend_intro_point_t *, ip,
 1060                     if (ip->timed_out) {
 1061                       SMARTLIST_DEL_CURRENT(usable_nodes, ip);
 1062                     });
 1063 
 1064  again:
 1065   if (smartlist_len(usable_nodes) == 0) {
 1066     if (n_excluded && get_options()->StrictNodes && warnings) {
 1067       /* We only want to warn if StrictNodes is really set. Otherwise
 1068        * we're just about to retry anyways.
 1069        */
 1070       log_warn(LD_REND, "All introduction points for hidden service are "
 1071                "at excluded relays, and StrictNodes is set. Skipping.");
 1072     }
 1073     smartlist_free(usable_nodes);
 1074     return NULL;
 1075   }
 1076 
 1077   i = crypto_rand_int(smartlist_len(usable_nodes));
 1078   intro = smartlist_get(usable_nodes, i);
 1079   if (BUG(!intro->extend_info)) {
 1080     /* This should never happen, but it isn't fatal, just try another */
 1081     smartlist_del(usable_nodes, i);
 1082     goto again;
 1083   }
 1084   /* All version 2 HS descriptors come with a TAP onion key.
 1085    * Clients used to try to get the TAP onion key from the consensus, but this
 1086    * meant that hidden services could discover which consensus clients have. */
 1087   if (!extend_info_supports_tap(intro->extend_info)) {
 1088     log_info(LD_REND, "The HS descriptor is missing a TAP onion key for the "
 1089              "intro-point relay '%s'; trying another.",
 1090              safe_str_client(extend_info_describe(intro->extend_info)));
 1091     smartlist_del(usable_nodes, i);
 1092     goto again;
 1093   }
 1094   /* Check if we should refuse to talk to this router. */
 1095   if (strict &&
 1096       routerset_contains_extendinfo(options->ExcludeNodes,
 1097                                     intro->extend_info)) {
 1098     n_excluded++;
 1099     smartlist_del(usable_nodes, i);
 1100     goto again;
 1101   }
 1102 
 1103   smartlist_free(usable_nodes);
 1104   return extend_info_dup(intro->extend_info);
 1105 }
 1106 
 1107 /** Return true iff any introduction points still listed in <b>entry</b> are
 1108  * usable. */
 1109 int
 1110 rend_client_any_intro_points_usable(const rend_cache_entry_t *entry)
 1111 {
 1112   extend_info_t *extend_info =
 1113     rend_client_get_random_intro_impl(entry, get_options()->StrictNodes, 0);
 1114 
 1115   int rv = (extend_info != NULL);
 1116 
 1117   extend_info_free(extend_info);
 1118   return rv;
 1119 }
 1120 
 1121 /** Client-side authorizations for hidden services; map of onion address to
 1122  * rend_service_authorization_t*. */
 1123 static strmap_t *auth_hid_servs = NULL;
 1124 
 1125 /** Look up the client-side authorization for the hidden service with
 1126  * <b>onion_address</b>. Return NULL if no authorization is available for
 1127  * that address. */
 1128 rend_service_authorization_t*
 1129 rend_client_lookup_service_authorization(const char *onion_address)
 1130 {
 1131   tor_assert(onion_address);
 1132   if (!auth_hid_servs) return NULL;
 1133   return strmap_get(auth_hid_servs, onion_address);
 1134 }
 1135 
 1136 #define rend_service_authorization_free(val)                    \
 1137   FREE_AND_NULL(rend_service_authorization_t,                   \
 1138                 rend_service_authorization_free_, (val))
 1139 
 1140 /** Helper: Free storage held by rend_service_authorization_t. */
 1141 static void
 1142 rend_service_authorization_free_(rend_service_authorization_t *auth)
 1143 {
 1144   tor_free(auth);
 1145 }
 1146 
 1147 /** Helper for strmap_free. */
 1148 static void
 1149 rend_service_authorization_free_void(void *service_auth)
 1150 {
 1151   rend_service_authorization_free_(service_auth);
 1152 }
 1153 
 1154 /** Release all the storage held in auth_hid_servs.
 1155  */
 1156 void
 1157 rend_service_authorization_free_all(void)
 1158 {
 1159   if (!auth_hid_servs) {
 1160     return;
 1161   }
 1162   strmap_free(auth_hid_servs, rend_service_authorization_free_void);
 1163   auth_hid_servs = NULL;
 1164 }
 1165 
 1166 /** Parse <b>config_line</b> as a client-side authorization for a hidden
 1167  * service and add it to the local map of hidden service authorizations.
 1168  * Return 0 for success and -1 for failure. */
 1169 int
 1170 rend_parse_service_authorization(const or_options_t *options,
 1171                                  int validate_only)
 1172 {
 1173   config_line_t *line;
 1174   int res = -1;
 1175   strmap_t *parsed = strmap_new();
 1176   smartlist_t *sl = smartlist_new();
 1177   rend_service_authorization_t *auth = NULL;
 1178   char *err_msg = NULL;
 1179 
 1180   for (line = options->HidServAuth; line; line = line->next) {
 1181     char *onion_address, *descriptor_cookie;
 1182     auth = NULL;
 1183     SMARTLIST_FOREACH(sl, char *, c, tor_free(c););
 1184     smartlist_clear(sl);
 1185     smartlist_split_string(sl, line->value, " ",
 1186                            SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 3);
 1187     if (smartlist_len(sl) < 2) {
 1188       log_warn(LD_CONFIG, "Configuration line does not consist of "
 1189                "\"onion-address authorization-cookie [service-name]\": "
 1190                "'%s'", line->value);
 1191       goto err;
 1192     }
 1193     auth = tor_malloc_zero(sizeof(rend_service_authorization_t));
 1194     /* Parse onion address. */
 1195     onion_address = smartlist_get(sl, 0);
 1196     if (strlen(onion_address) != REND_SERVICE_ADDRESS_LEN ||
 1197         strcmpend(onion_address, ".onion")) {
 1198       log_warn(LD_CONFIG, "Onion address has wrong format: '%s'",
 1199                onion_address);
 1200       goto err;
 1201     }
 1202     strlcpy(auth->onion_address, onion_address, REND_SERVICE_ID_LEN_BASE32+1);
 1203     if (!rend_valid_v2_service_id(auth->onion_address)) {
 1204       log_warn(LD_CONFIG, "Onion address has wrong format: '%s'",
 1205                onion_address);
 1206       goto err;
 1207     }
 1208     /* Parse descriptor cookie. */
 1209     descriptor_cookie = smartlist_get(sl, 1);
 1210     if (rend_auth_decode_cookie(descriptor_cookie, auth->descriptor_cookie,
 1211                                 &auth->auth_type, &err_msg) < 0) {
 1212       tor_assert(err_msg);
 1213       log_warn(LD_CONFIG, "%s", err_msg);
 1214       tor_free(err_msg);
 1215       goto err;
 1216     }
 1217     if (strmap_get(parsed, auth->onion_address)) {
 1218       log_warn(LD_CONFIG, "Duplicate authorization for the same hidden "
 1219                           "service.");
 1220       goto err;
 1221     }
 1222     strmap_set(parsed, auth->onion_address, auth);
 1223     auth = NULL;
 1224   }
 1225   res = 0;
 1226   goto done;
 1227  err:
 1228   res = -1;
 1229  done:
 1230   rend_service_authorization_free(auth);
 1231   SMARTLIST_FOREACH(sl, char *, c, tor_free(c););
 1232   smartlist_free(sl);
 1233   if (!validate_only && res == 0) {
 1234     rend_service_authorization_free_all();
 1235     auth_hid_servs = parsed;
 1236   } else {
 1237     strmap_free(parsed, rend_service_authorization_free_void);
 1238   }
 1239   return res;
 1240 }