LCOV - code coverage report
Current view: top level - feature/client - bridges.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 174 398 43.7 %
Date: 2021-11-24 03:28:48 Functions: 21 35 60.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 bridges.c
       9             :  * \brief Code to manage bridges and bridge selection.
      10             :  *
      11             :  * Bridges are fixed entry nodes, used for censorship circumvention.
      12             :  **/
      13             : 
      14             : #define TOR_BRIDGES_PRIVATE
      15             : 
      16             : #include "core/or/or.h"
      17             : #include "app/config/config.h"
      18             : #include "core/mainloop/connection.h"
      19             : #include "core/or/circuitbuild.h"
      20             : #include "core/or/policies.h"
      21             : #include "feature/client/bridges.h"
      22             : #include "feature/client/entrynodes.h"
      23             : #include "feature/client/transports.h"
      24             : #include "feature/dirclient/dirclient.h"
      25             : #include "feature/dirclient/dlstatus.h"
      26             : #include "feature/dircommon/directory.h"
      27             : #include "feature/nodelist/describe.h"
      28             : #include "feature/nodelist/dirlist.h"
      29             : #include "feature/nodelist/nodelist.h"
      30             : #include "feature/nodelist/routerinfo.h"
      31             : #include "feature/nodelist/routerlist.h"
      32             : #include "feature/nodelist/routerset.h"
      33             : 
      34             : #include "core/or/extend_info_st.h"
      35             : #include "feature/nodelist/node_st.h"
      36             : #include "feature/nodelist/routerinfo_st.h"
      37             : #include "feature/nodelist/routerstatus_st.h"
      38             : #include "feature/nodelist/microdesc_st.h"
      39             : 
      40             : /** Information about a configured bridge. Currently this just matches the
      41             :  * ones in the torrc file, but one day we may be able to learn about new
      42             :  * bridges on our own, and remember them in the state file. */
      43             : struct bridge_info_t {
      44             :   /** Address and port of the bridge, as configured by the user.*/
      45             :   tor_addr_port_t addrport_configured;
      46             :   /** Address of the bridge. */
      47             :   tor_addr_t addr;
      48             :   /** TLS port for the bridge. */
      49             :   uint16_t port;
      50             :   /** Boolean: We are re-parsing our bridge list, and we are going to remove
      51             :    * this one if we don't find it in the list of configured bridges. */
      52             :   unsigned marked_for_removal : 1;
      53             :   /** Expected identity digest, or all zero bytes if we don't know what the
      54             :    * digest should be. */
      55             :   char identity[DIGEST_LEN];
      56             : 
      57             :   /** Name of pluggable transport protocol taken from its config line. */
      58             :   char *transport_name;
      59             : 
      60             :   /** When should we next try to fetch a descriptor for this bridge? */
      61             :   download_status_t fetch_status;
      62             : 
      63             :   /** A smartlist of k=v values to be passed to the SOCKS proxy, if
      64             :       transports are used for this bridge. */
      65             :   smartlist_t *socks_args;
      66             : };
      67             : 
      68             : #define bridge_free(bridge) \
      69             :   FREE_AND_NULL(bridge_info_t, bridge_free_, (bridge))
      70             : 
      71             : static void bridge_free_(bridge_info_t *bridge);
      72             : static void rewrite_node_address_for_bridge(const bridge_info_t *bridge,
      73             :                                             node_t *node);
      74             : 
      75             : /** A list of configured bridges. Whenever we actually get a descriptor
      76             :  * for one, we add it as an entry guard.  Note that the order of bridges
      77             :  * in this list does not necessarily correspond to the order of bridges
      78             :  * in the torrc. */
      79             : static smartlist_t *bridge_list = NULL;
      80             : 
      81             : /** Mark every entry of the bridge list to be removed on our next call to
      82             :  * sweep_bridge_list unless it has first been un-marked. */
      83             : void
      84          41 : mark_bridge_list(void)
      85             : {
      86          41 :   if (!bridge_list)
      87          10 :     bridge_list = smartlist_new();
      88         145 :   SMARTLIST_FOREACH(bridge_list, bridge_info_t *, b,
      89             :                     b->marked_for_removal = 1);
      90          41 : }
      91             : 
      92             : /** Remove every entry of the bridge list that was marked with
      93             :  * mark_bridge_list if it has not subsequently been un-marked. */
      94             : void
      95          45 : sweep_bridge_list(void)
      96             : {
      97          45 :   if (!bridge_list)
      98           3 :     bridge_list = smartlist_new();
      99         277 :   SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, b) {
     100         232 :     if (b->marked_for_removal) {
     101         105 :       SMARTLIST_DEL_CURRENT(bridge_list, b);
     102         105 :       bridge_free(b);
     103             :     }
     104         232 :   } SMARTLIST_FOREACH_END(b);
     105          45 : }
     106             : 
     107             : /** Initialize the bridge list to empty, creating it if needed. */
     108             : STATIC void
     109         236 : clear_bridge_list(void)
     110             : {
     111         236 :   if (!bridge_list)
     112         226 :     bridge_list = smartlist_new();
     113         252 :   SMARTLIST_FOREACH(bridge_list, bridge_info_t *, b, bridge_free(b));
     114         236 :   smartlist_clear(bridge_list);
     115         236 : }
     116             : 
     117             : /** Free the bridge <b>bridge</b>. */
     118             : static void
     119         121 : bridge_free_(bridge_info_t *bridge)
     120             : {
     121         121 :   if (!bridge)
     122             :     return;
     123             : 
     124         121 :   tor_free(bridge->transport_name);
     125         121 :   if (bridge->socks_args) {
     126         112 :     SMARTLIST_FOREACH(bridge->socks_args, char*, s, tor_free(s));
     127          48 :     smartlist_free(bridge->socks_args);
     128             :   }
     129             : 
     130         121 :   tor_free(bridge);
     131             : }
     132             : 
     133             : /** Return a list of all the configured bridges, as bridge_info_t pointers. */
     134             : const smartlist_t *
     135           7 : bridge_list_get(void)
     136             : {
     137           7 :   if (!bridge_list)
     138           1 :     bridge_list = smartlist_new();
     139           7 :   return bridge_list;
     140             : }
     141             : 
     142             : /**
     143             :  * Given a <b>bridge</b>, return a pointer to its RSA identity digest, or
     144             :  * NULL if we don't know one for it.
     145             :  */
     146             : const uint8_t *
     147           1 : bridge_get_rsa_id_digest(const bridge_info_t *bridge)
     148             : {
     149           1 :   tor_assert(bridge);
     150           1 :   if (tor_digest_is_zero(bridge->identity))
     151             :     return NULL;
     152             :   else
     153           1 :     return (const uint8_t *) bridge->identity;
     154             : }
     155             : 
     156             : /**
     157             :  * Given a <b>bridge</b>, return a pointer to its configured addr:port
     158             :  * combination.
     159             :  */
     160             : const tor_addr_port_t *
     161           8 : bridge_get_addr_port(const bridge_info_t *bridge)
     162             : {
     163           8 :   tor_assert(bridge);
     164           8 :   return &bridge->addrport_configured;
     165             : }
     166             : 
     167             : /**
     168             :  * Given a <b>bridge</b>, return the transport name. If none were configured,
     169             :  * NULL is returned.
     170             :  */
     171             : const char *
     172           0 : bridget_get_transport_name(const bridge_info_t *bridge)
     173             : {
     174           0 :   tor_assert(bridge);
     175           0 :   return bridge->transport_name;
     176             : }
     177             : 
     178             : /**
     179             :  * Return true if @a bridge has a transport name for which we don't actually
     180             :  * know a transport.
     181             :  */
     182             : bool
     183           0 : bridge_has_invalid_transport(const bridge_info_t *bridge)
     184             : {
     185           0 :   const char *tname = bridget_get_transport_name(bridge);
     186           0 :   return tname && transport_get_by_name(tname) == NULL;
     187             : }
     188             : 
     189             : /** If we have a bridge configured whose digest matches <b>digest</b>, or a
     190             :  * bridge with no known digest whose address matches any of the
     191             :  * tor_addr_port_t's in <b>orports</b>, return that bridge.  Else return
     192             :  * NULL. */
     193             : STATIC bridge_info_t *
     194           1 : get_configured_bridge_by_orports_digest(const char *digest,
     195             :                                         const smartlist_t *orports)
     196             : {
     197           1 :   if (!bridge_list)
     198             :     return NULL;
     199           1 :   SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, bridge)
     200             :     {
     201           1 :       if (tor_digest_is_zero(bridge->identity)) {
     202           1 :         SMARTLIST_FOREACH_BEGIN(orports, tor_addr_port_t *, ap)
     203             :           {
     204           1 :             if (tor_addr_compare(&bridge->addr, &ap->addr, CMP_EXACT) == 0 &&
     205           1 :                 bridge->port == ap->port)
     206           1 :               return bridge;
     207             :           }
     208           0 :         SMARTLIST_FOREACH_END(ap);
     209             :       }
     210           0 :       if (digest && tor_memeq(bridge->identity, digest, DIGEST_LEN))
     211           0 :         return bridge;
     212             :     }
     213           0 :   SMARTLIST_FOREACH_END(bridge);
     214             :   return NULL;
     215             : }
     216             : 
     217             : /** If we have a bridge configured whose digest matches <b>digest</b>, or a
     218             :  * bridge with no known digest whose address matches <b>addr</b>:<b>port</b>,
     219             :  * return that bridge.  Else return NULL. If <b>digest</b> is NULL, check for
     220             :  * address/port matches only. */
     221             : bridge_info_t *
     222       13616 : get_configured_bridge_by_addr_port_digest(const tor_addr_t *addr,
     223             :                                           uint16_t port,
     224             :                                           const char *digest)
     225             : {
     226       13616 :   if (!bridge_list)
     227             :     return NULL;
     228          63 :   SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, bridge)
     229             :     {
     230          71 :       if ((tor_digest_is_zero(bridge->identity) || digest == NULL) &&
     231          21 :           !tor_addr_compare(&bridge->addr, addr, CMP_EXACT) &&
     232           7 :           bridge->port == port)
     233           7 :         return bridge;
     234          43 :       if (digest && tor_memeq(bridge->identity, digest, DIGEST_LEN))
     235           1 :         return bridge;
     236             :     }
     237          42 :   SMARTLIST_FOREACH_END(bridge);
     238             :   return NULL;
     239             : }
     240             : 
     241             : /**
     242             :  * As get_configured_bridge_by_addr_port, but require that the
     243             :  * address match <b>addr</b>:<b>port</b>, and that the ID digest match
     244             :  * <b>digest</b>.  (The other function will ignore the address if the
     245             :  * digest matches.)
     246             :  */
     247             : bridge_info_t *
     248          10 : get_configured_bridge_by_exact_addr_port_digest(const tor_addr_t *addr,
     249             :                                                 uint16_t port,
     250             :                                                 const char *digest)
     251             : {
     252          10 :   if (!bridge_list)
     253             :     return NULL;
     254          22 :   SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, bridge) {
     255          19 :     if (!tor_addr_compare(&bridge->addr, addr, CMP_EXACT) &&
     256           2 :         bridge->port == port) {
     257             : 
     258           2 :       if (digest && tor_memeq(bridge->identity, digest, DIGEST_LEN))
     259           1 :         return bridge;
     260           1 :       else if (!digest || tor_digest_is_zero(bridge->identity))
     261           1 :         return bridge;
     262             :     }
     263             : 
     264          17 :   } SMARTLIST_FOREACH_END(bridge);
     265             :   return NULL;
     266             : }
     267             : 
     268             : /** If we have a bridge configured whose digest matches <b>digest</b>, or a
     269             :  * bridge with no known digest whose address matches <b>addr</b>:<b>port</b>,
     270             :  * return 1.  Else return 0. If <b>digest</b> is NULL, check for
     271             :  * address/port matches only. */
     272             : int
     273           1 : addr_is_a_configured_bridge(const tor_addr_t *addr,
     274             :                             uint16_t port,
     275             :                             const char *digest)
     276             : {
     277           1 :   tor_assert(addr);
     278           1 :   return get_configured_bridge_by_addr_port_digest(addr, port, digest) ? 1 : 0;
     279             : }
     280             : 
     281             : /** If we have a bridge configured whose digest matches
     282             :  * <b>ei->identity_digest</b>, or a bridge with no known digest whose address
     283             :  * matches <b>ei->addr</b>:<b>ei->port</b>, return 1.  Else return 0.
     284             :  * If <b>ei->onion_key</b> is NULL, check for address/port matches only.
     285             :  *
     286             :  * Note that if the extend_info_t contains multiple addresses, we return true
     287             :  * only if _every_ address is a bridge.
     288             :  */
     289             : int
     290           0 : extend_info_is_a_configured_bridge(const extend_info_t *ei)
     291             : {
     292           0 :   const char *digest = ei->onion_key ? ei->identity_digest : NULL;
     293           0 :   const tor_addr_port_t *ap1 = NULL, *ap2 = NULL;
     294           0 :   if (! tor_addr_is_null(&ei->orports[0].addr))
     295           0 :     ap1 = &ei->orports[0];
     296           0 :   if (! tor_addr_is_null(&ei->orports[1].addr))
     297           0 :     ap2 = &ei->orports[1];
     298           0 :   IF_BUG_ONCE(ap1 == NULL) {
     299             :     return 0;
     300             :   }
     301           0 :   return addr_is_a_configured_bridge(&ap1->addr, ap1->port, digest) &&
     302           0 :     (ap2 == NULL ||
     303           0 :      addr_is_a_configured_bridge(&ap2->addr, ap2->port, digest));
     304             : }
     305             : 
     306             : /** Wrapper around get_configured_bridge_by_addr_port_digest() to look
     307             :  * it up via router descriptor <b>ri</b>. */
     308             : static bridge_info_t *
     309           0 : get_configured_bridge_by_routerinfo(const routerinfo_t *ri)
     310             : {
     311           0 :   bridge_info_t *bi = NULL;
     312           0 :   smartlist_t *orports = router_get_all_orports(ri);
     313           0 :   bi = get_configured_bridge_by_orports_digest(ri->cache_info.identity_digest,
     314             :                                                orports);
     315           0 :   SMARTLIST_FOREACH(orports, tor_addr_port_t *, p, tor_free(p));
     316           0 :   smartlist_free(orports);
     317           0 :   return bi;
     318             : }
     319             : 
     320             : /** Return 1 if <b>ri</b> is one of our known bridges, else 0. */
     321             : int
     322           0 : routerinfo_is_a_configured_bridge(const routerinfo_t *ri)
     323             : {
     324           0 :   return get_configured_bridge_by_routerinfo(ri) ? 1 : 0;
     325             : }
     326             : 
     327             : /**
     328             :  * Return 1 iff <b>bridge_list</b> contains entry matching given
     329             :  * <b>addr</b> and <b>port</b> (and no identity digest) OR
     330             :  * it contains an  entry whose identity matches <b>digest</b>.
     331             :  * Otherwise, return 0.
     332             :  */
     333             : static int
     334       57541 : bridge_exists_with_addr_and_port(const tor_addr_t *addr,
     335             :                                  const uint16_t port,
     336             :                                  const char *digest)
     337             : {
     338       57541 :   if (!tor_addr_port_is_valid(addr, port, 0))
     339       43928 :     return 0;
     340             : 
     341       13613 :   bridge_info_t *bridge =
     342       13613 :    get_configured_bridge_by_addr_port_digest(addr, port, digest);
     343             : 
     344       13613 :   return (bridge != NULL);
     345             : }
     346             : 
     347             : /** Return 1 if <b>node</b> is one of our configured bridges, else 0.
     348             :  * More specifically, return 1 iff: a bridge_info_t object exists in
     349             :  * <b>bridge_list</b> such that: 1) It's identity is equal to node
     350             :  * identity OR 2) It's identity digest is zero, but it matches
     351             :  * address and port of any ORPort in the node.
     352             :  */
     353             : int
     354       28778 : node_is_a_configured_bridge(const node_t *node)
     355             : {
     356             :   /* First, let's try searching for a bridge with matching identity. */
     357       28778 :   if (BUG(fast_mem_is_zero(node->identity, DIGEST_LEN)))
     358           0 :     return 0;
     359             : 
     360       28778 :   if (find_bridge_by_digest(node->identity) != NULL)
     361             :     return 1;
     362             : 
     363             :   /* At this point, we have established that no bridge exists with
     364             :    * matching identity digest. However, we still pass it into
     365             :    * bridge_exists_* functions because we want further code to
     366             :    * check for absence of identity digest in a bridge.
     367             :    */
     368       28774 :   if (node->ri) {
     369          14 :     if (bridge_exists_with_addr_and_port(&node->ri->ipv4_addr,
     370          14 :                                          node->ri->ipv4_orport,
     371             :                                          node->identity))
     372             :       return 1;
     373             : 
     374          12 :     if (bridge_exists_with_addr_and_port(&node->ri->ipv6_addr,
     375          12 :                                          node->ri->ipv6_orport,
     376             :                                          node->identity))
     377           1 :       return 1;
     378       28760 :   } else if (node->rs) {
     379       28757 :     if (bridge_exists_with_addr_and_port(&node->rs->ipv4_addr,
     380       28757 :                                          node->rs->ipv4_orport,
     381             :                                          node->identity))
     382             :       return 1;
     383             : 
     384       28756 :     if (bridge_exists_with_addr_and_port(&node->rs->ipv6_addr,
     385       28756 :                                          node->rs->ipv6_orport,
     386             :                                          node->identity))
     387           1 :       return 1;
     388           3 :   }  else if (node->md) {
     389           2 :     if (bridge_exists_with_addr_and_port(&node->md->ipv6_addr,
     390           2 :                                          node->md->ipv6_orport,
     391             :                                          node->identity))
     392           1 :       return 1;
     393             :   }
     394             : 
     395             :   return 0;
     396             : }
     397             : 
     398             : /** We made a connection to a router at <b>addr</b>:<b>port</b>
     399             :  * without knowing its digest. Its digest turned out to be <b>digest</b>.
     400             :  * If it was a bridge, and we still don't know its digest, record it.
     401             :  */
     402             : void
     403           3 : learned_router_identity(const tor_addr_t *addr, uint16_t port,
     404             :                         const char *digest,
     405             :                         const ed25519_public_key_t *ed_id)
     406             : {
     407             :   // XXXX prop220 use ed_id here, once there is some way to specify
     408           3 :   (void)ed_id;
     409           3 :   int learned = 0;
     410           3 :   bridge_info_t *bridge =
     411           3 :     get_configured_bridge_by_exact_addr_port_digest(addr, port, digest);
     412           3 :   if (bridge && tor_digest_is_zero(bridge->identity)) {
     413           0 :     memcpy(bridge->identity, digest, DIGEST_LEN);
     414           0 :     learned = 1;
     415             :   }
     416             :   /* XXXX prop220 remember bridge ed25519 identities -- add a field */
     417             : #if 0
     418             :   if (bridge && ed_id &&
     419             :       ed25519_public_key_is_zero(&bridge->ed25519_identity) &&
     420             :       !ed25519_public_key_is_zero(ed_id)) {
     421             :     memcpy(&bridge->ed25519_identity, ed_id, sizeof(*ed_id));
     422             :     learned = 1;
     423             :   }
     424             : #endif /* 0 */
     425           0 :   if (learned) {
     426           0 :     char *transport_info = NULL;
     427           0 :     const char *transport_name =
     428           0 :       find_transport_name_by_bridge_addrport(addr, port);
     429           0 :     if (transport_name)
     430           0 :       tor_asprintf(&transport_info, " (with transport '%s')", transport_name);
     431             : 
     432             :     // XXXX prop220 log both fingerprints.
     433           0 :     log_notice(LD_DIR, "Learned fingerprint %s for bridge %s%s.",
     434             :                hex_str(digest, DIGEST_LEN), fmt_addrport(addr, port),
     435             :                transport_info ? transport_info : "");
     436           0 :     tor_free(transport_info);
     437           0 :     entry_guard_learned_bridge_identity(&bridge->addrport_configured,
     438             :                                         (const uint8_t *)digest);
     439             :   }
     440           3 : }
     441             : 
     442             : /** Return true if <b>bridge</b> has the same identity digest as
     443             :  *  <b>digest</b>. If <b>digest</b> is NULL, it matches
     444             :  *  bridges with unspecified identity digests. */
     445             : static int
     446           1 : bridge_has_digest(const bridge_info_t *bridge, const char *digest)
     447             : {
     448           1 :   if (digest)
     449           1 :     return tor_memeq(digest, bridge->identity, DIGEST_LEN);
     450             :   else
     451           0 :     return tor_digest_is_zero(bridge->identity);
     452             : }
     453             : 
     454             : /** We are about to add a new bridge at <b>addr</b>:<b>port</b>, with optional
     455             :  * <b>digest</b> and <b>transport_name</b>. Mark for removal any previously
     456             :  * existing bridge with the same address and port, and warn the user as
     457             :  * appropriate.
     458             :  */
     459             : STATIC void
     460         125 : bridge_resolve_conflicts(const tor_addr_t *addr, uint16_t port,
     461             :                          const char *digest, const char *transport_name)
     462             : {
     463             :   /* Iterate the already-registered bridge list:
     464             : 
     465             :      If you find a bridge with the same address and port, mark it for
     466             :      removal. It doesn't make sense to have two active bridges with
     467             :      the same IP:PORT. If the bridge in question has a different
     468             :      digest or transport than <b>digest</b>/<b>transport_name</b>,
     469             :      it's probably a misconfiguration and we should warn the user.
     470             :   */
     471         468 :   SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, bridge) {
     472         343 :     if (bridge->marked_for_removal)
     473           0 :       continue;
     474             : 
     475         343 :     if (tor_addr_eq(&bridge->addr, addr) && (bridge->port == port)) {
     476             : 
     477           1 :       bridge->marked_for_removal = 1;
     478             : 
     479           1 :       if (!bridge_has_digest(bridge, digest) ||
     480           0 :           strcmp_opt(bridge->transport_name, transport_name)) {
     481             :         /* warn the user */
     482           1 :         char *bridge_description_new, *bridge_description_old;
     483           2 :         tor_asprintf(&bridge_description_new, "%s:%s:%s",
     484             :                      fmt_addrport(addr, port),
     485           1 :                      digest ? hex_str(digest, DIGEST_LEN) : "",
     486             :                      transport_name ? transport_name : "");
     487           2 :         tor_asprintf(&bridge_description_old, "%s:%s:%s",
     488           1 :                      fmt_addrport(&bridge->addr, bridge->port),
     489           1 :                      tor_digest_is_zero(bridge->identity) ?
     490           1 :                      "" : hex_str(bridge->identity,DIGEST_LEN),
     491           1 :                      bridge->transport_name ? bridge->transport_name : "");
     492             : 
     493           1 :         log_warn(LD_GENERAL,"Tried to add bridge '%s', but we found a conflict"
     494             :                  " with the already registered bridge '%s'. We will discard"
     495             :                  " the old bridge and keep '%s'. If this is not what you"
     496             :                  " wanted, please change your configuration file accordingly.",
     497             :                  bridge_description_new, bridge_description_old,
     498             :                  bridge_description_new);
     499             : 
     500           1 :         tor_free(bridge_description_new);
     501           1 :         tor_free(bridge_description_old);
     502             :       }
     503             :     }
     504         343 :   } SMARTLIST_FOREACH_END(bridge);
     505         125 : }
     506             : 
     507             : /** Return True if we have a bridge that uses a transport with name
     508             :  *  <b>transport_name</b>. */
     509          19 : MOCK_IMPL(int,
     510             : transport_is_needed, (const char *transport_name))
     511             : {
     512          19 :   if (!bridge_list)
     513             :     return 0;
     514             : 
     515          11 :   SMARTLIST_FOREACH_BEGIN(bridge_list, const bridge_info_t *, bridge) {
     516          10 :     if (bridge->transport_name &&
     517           5 :         !strcmp(bridge->transport_name, transport_name))
     518             :       return 1;
     519           9 :   } SMARTLIST_FOREACH_END(bridge);
     520             : 
     521             :   return 0;
     522             : }
     523             : 
     524             : /** Register the bridge information in <b>bridge_line</b> to the
     525             :  *  bridge subsystem. Steals reference of <b>bridge_line</b>. */
     526             : void
     527         124 : bridge_add_from_config(bridge_line_t *bridge_line)
     528             : {
     529         124 :   bridge_info_t *b;
     530             : 
     531             :   // XXXX prop220 add a way to specify ed25519 ID to bridge_line_t.
     532             : 
     533             :   { /* Log the bridge we are about to register: */
     534         188 :     log_debug(LD_GENERAL, "Registering bridge at %s (transport: %s) (%s)",
     535             :               fmt_addrport(&bridge_line->addr, bridge_line->port),
     536             :               bridge_line->transport_name ?
     537             :               bridge_line->transport_name : "no transport",
     538             :               tor_digest_is_zero(bridge_line->digest) ?
     539             :               "no key listed" : hex_str(bridge_line->digest, DIGEST_LEN));
     540             : 
     541         124 :     if (bridge_line->socks_args) { /* print socks arguments */
     542          48 :       int i = 0;
     543             : 
     544          48 :       tor_assert(smartlist_len(bridge_line->socks_args) > 0);
     545             : 
     546          48 :       log_debug(LD_GENERAL, "Bridge uses %d SOCKS arguments:",
     547             :                 smartlist_len(bridge_line->socks_args));
     548         112 :       SMARTLIST_FOREACH(bridge_line->socks_args, const char *, arg,
     549             :                         log_debug(LD_CONFIG, "%d: %s", ++i, arg));
     550             :     }
     551             :   }
     552             : 
     553         124 :   bridge_resolve_conflicts(&bridge_line->addr,
     554         124 :                            bridge_line->port,
     555             :                            bridge_line->digest,
     556         124 :                            bridge_line->transport_name);
     557             : 
     558         124 :   b = tor_malloc_zero(sizeof(bridge_info_t));
     559         124 :   tor_addr_copy(&b->addrport_configured.addr, &bridge_line->addr);
     560         124 :   b->addrport_configured.port = bridge_line->port;
     561         124 :   tor_addr_copy(&b->addr, &bridge_line->addr);
     562         124 :   b->port = bridge_line->port;
     563         124 :   memcpy(b->identity, bridge_line->digest, DIGEST_LEN);
     564         124 :   if (bridge_line->transport_name)
     565          64 :     b->transport_name = bridge_line->transport_name;
     566         124 :   b->fetch_status.schedule = DL_SCHED_BRIDGE;
     567         124 :   b->fetch_status.increment_on = DL_SCHED_INCREMENT_ATTEMPT;
     568             :   /* We can't reset the bridge's download status here, because UseBridges
     569             :    * might be 0 now, and it might be changed to 1 much later. */
     570         124 :   b->socks_args = bridge_line->socks_args;
     571         124 :   if (!bridge_list)
     572           0 :     bridge_list = smartlist_new();
     573             : 
     574         124 :   tor_free(bridge_line); /* Deallocate bridge_line now. */
     575             : 
     576         124 :   smartlist_add(bridge_list, b);
     577         124 : }
     578             : 
     579             : /** If <b>digest</b> is one of our known bridges, return it. */
     580             : STATIC bridge_info_t *
     581       28780 : find_bridge_by_digest(const char *digest)
     582             : {
     583       28780 :   if (! bridge_list)
     584             :     return NULL;
     585          93 :   SMARTLIST_FOREACH(bridge_list, bridge_info_t *, bridge,
     586             :     {
     587             :       if (tor_memeq(bridge->identity, digest, DIGEST_LEN))
     588             :         return bridge;
     589             :     });
     590             :   return NULL;
     591             : }
     592             : 
     593             : /** Given the <b>addr</b> and <b>port</b> of a bridge, if that bridge
     594             :  *  supports a pluggable transport, return its name. Otherwise, return
     595             :  *  NULL. */
     596             : const char *
     597           0 : find_transport_name_by_bridge_addrport(const tor_addr_t *addr, uint16_t port)
     598             : {
     599           0 :   if (!bridge_list)
     600             :     return NULL;
     601             : 
     602           0 :   SMARTLIST_FOREACH_BEGIN(bridge_list, const bridge_info_t *, bridge) {
     603           0 :     if (tor_addr_eq(&bridge->addr, addr) &&
     604           0 :         (bridge->port == port))
     605           0 :       return bridge->transport_name;
     606           0 :   } SMARTLIST_FOREACH_END(bridge);
     607             : 
     608             :   return NULL;
     609             : }
     610             : 
     611             : /** If <b>addr</b> and <b>port</b> match the address and port of a
     612             :  * bridge of ours that uses pluggable transports, place its transport
     613             :  * in <b>transport</b>.
     614             :  *
     615             :  * Return 0 on success (found a transport, or found a bridge with no
     616             :  * transport, or found no bridge); return -1 if we should be using a
     617             :  * transport, but the transport could not be found.
     618             :  */
     619             : int
     620           2 : get_transport_by_bridge_addrport(const tor_addr_t *addr, uint16_t port,
     621             :                                  const transport_t **transport)
     622             : {
     623           2 :   *transport = NULL;
     624           2 :   if (!bridge_list)
     625             :     return 0;
     626             : 
     627          10 :   SMARTLIST_FOREACH_BEGIN(bridge_list, const bridge_info_t *, bridge) {
     628          10 :     if (tor_addr_eq(&bridge->addr, addr) &&
     629           2 :         (bridge->port == port)) { /* bridge matched */
     630           2 :       if (bridge->transport_name) { /* it also uses pluggable transports */
     631           2 :         *transport = transport_get_by_name(bridge->transport_name);
     632           2 :         if (*transport == NULL) { /* it uses pluggable transports, but
     633             :                                      the transport could not be found! */
     634             :           return -1;
     635             :         }
     636           1 :         return 0;
     637             :       } else { /* bridge matched, but it doesn't use transports. */
     638             :         break;
     639             :       }
     640             :     }
     641           8 :   } SMARTLIST_FOREACH_END(bridge);
     642             : 
     643           0 :   *transport = NULL;
     644           0 :   return 0;
     645             : }
     646             : 
     647             : /** Return a smartlist containing all the SOCKS arguments that we
     648             :  *  should pass to the SOCKS proxy. */
     649             : const smartlist_t *
     650           0 : get_socks_args_by_bridge_addrport(const tor_addr_t *addr, uint16_t port)
     651             : {
     652           0 :   bridge_info_t *bridge = get_configured_bridge_by_addr_port_digest(addr,
     653             :                                                                     port,
     654             :                                                                     NULL);
     655           0 :   return bridge ? bridge->socks_args : NULL;
     656             : }
     657             : 
     658             : /** We need to ask <b>bridge</b> for its server descriptor. */
     659             : static void
     660           0 : launch_direct_bridge_descriptor_fetch(bridge_info_t *bridge)
     661             : {
     662           0 :   const or_options_t *options = get_options();
     663           0 :   circuit_guard_state_t *guard_state = NULL;
     664             : 
     665           0 :   if (connection_get_by_type_addr_port_purpose(
     666           0 :       CONN_TYPE_DIR, &bridge->addr, bridge->port,
     667             :       DIR_PURPOSE_FETCH_SERVERDESC))
     668           0 :     return; /* it's already on the way */
     669             : 
     670           0 :   if (bridge_has_invalid_transport(bridge)) {
     671           0 :     download_status_mark_impossible(&bridge->fetch_status);
     672           0 :     log_warn(LD_CONFIG, "Can't use bridge at %s: there is no configured "
     673             :              "transport called \"%s\".",
     674             :              safe_str_client(fmt_and_decorate_addr(&bridge->addr)),
     675             :              bridget_get_transport_name(bridge));
     676           0 :     return; /* Can't use this bridge; it has not */
     677             :   }
     678             : 
     679           0 :   if (routerset_contains_bridge(options->ExcludeNodes, bridge)) {
     680           0 :     download_status_mark_impossible(&bridge->fetch_status);
     681           0 :     log_warn(LD_APP, "Not using bridge at %s: it is in ExcludeNodes.",
     682             :              safe_str_client(fmt_and_decorate_addr(&bridge->addr)));
     683           0 :     return;
     684             :   }
     685             : 
     686             :   /* Until we get a descriptor for the bridge, we only know one address for
     687             :    * it. */
     688           0 :   if (!reachable_addr_allows_addr(&bridge->addr, bridge->port,
     689             :                                             FIREWALL_OR_CONNECTION, 0, 0)) {
     690           0 :     log_notice(LD_CONFIG, "Tried to fetch a descriptor directly from a "
     691             :                "bridge, but that bridge is not reachable through our "
     692             :                "firewall.");
     693           0 :     return;
     694             :   }
     695             : 
     696             :   /* If we already have a node_t for this bridge, rewrite its address now. */
     697           0 :   node_t *node = node_get_mutable_by_id(bridge->identity);
     698           0 :   if (node) {
     699           0 :     rewrite_node_address_for_bridge(bridge, node);
     700             :   }
     701             : 
     702           0 :   tor_addr_port_t bridge_addrport;
     703           0 :   memcpy(&bridge_addrport.addr, &bridge->addr, sizeof(tor_addr_t));
     704           0 :   bridge_addrport.port = bridge->port;
     705             : 
     706           0 :   guard_state = get_guard_state_for_bridge_desc_fetch(bridge->identity);
     707             : 
     708           0 :   directory_request_t *req =
     709           0 :     directory_request_new(DIR_PURPOSE_FETCH_SERVERDESC);
     710           0 :   directory_request_set_or_addr_port(req, &bridge_addrport);
     711           0 :   directory_request_set_directory_id_digest(req, bridge->identity);
     712           0 :   directory_request_set_router_purpose(req, ROUTER_PURPOSE_BRIDGE);
     713           0 :   directory_request_set_resource(req, "authority.z");
     714           0 :   if (guard_state) {
     715           0 :     directory_request_set_guard_state(req, guard_state);
     716             :   }
     717           0 :   directory_initiate_request(req);
     718           0 :   directory_request_free(req);
     719             : }
     720             : 
     721             : /** Fetching the bridge descriptor from the bridge authority returned a
     722             :  * "not found". Fall back to trying a direct fetch. */
     723             : void
     724           0 : retry_bridge_descriptor_fetch_directly(const char *digest)
     725             : {
     726           0 :   bridge_info_t *bridge = find_bridge_by_digest(digest);
     727           0 :   if (!bridge)
     728             :     return; /* not found? oh well. */
     729             : 
     730           0 :   launch_direct_bridge_descriptor_fetch(bridge);
     731             : }
     732             : 
     733             : /** For each bridge in our list for which we don't currently have a
     734             :  * descriptor, fetch a new copy of its descriptor -- either directly
     735             :  * from the bridge or via a bridge authority. */
     736             : void
     737           0 : fetch_bridge_descriptors(const or_options_t *options, time_t now)
     738             : {
     739           0 :   int num_bridge_auths = get_n_authorities(BRIDGE_DIRINFO);
     740           0 :   int ask_bridge_directly;
     741           0 :   int can_use_bridge_authority;
     742             : 
     743           0 :   if (!bridge_list)
     744             :     return;
     745             : 
     746             :   /* If we still have unconfigured managed proxies, don't go and
     747             :      connect to a bridge. */
     748           0 :   if (pt_proxies_configuration_pending())
     749             :     return;
     750             : 
     751           0 :   SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, bridge)
     752             :     {
     753             :       /* This resets the download status on first use */
     754           0 :       if (!download_status_is_ready(&bridge->fetch_status, now))
     755           0 :         continue; /* don't bother, no need to retry yet */
     756           0 :       if (routerset_contains_bridge(options->ExcludeNodes, bridge)) {
     757           0 :         download_status_mark_impossible(&bridge->fetch_status);
     758           0 :         log_warn(LD_APP, "Not using bridge at %s: it is in ExcludeNodes.",
     759             :                  safe_str_client(fmt_and_decorate_addr(&bridge->addr)));
     760           0 :         continue;
     761             :       }
     762             : 
     763             :       /* schedule the next attempt
     764             :        * we can't increment after a failure, because sometimes we use the
     765             :        * bridge authority, and sometimes we use the bridge direct */
     766           0 :       download_status_increment_attempt(
     767             :                         &bridge->fetch_status,
     768           0 :                         safe_str_client(fmt_and_decorate_addr(&bridge->addr)),
     769             :                         now);
     770             : 
     771           0 :       can_use_bridge_authority = !tor_digest_is_zero(bridge->identity) &&
     772             :                                  num_bridge_auths;
     773           0 :       ask_bridge_directly = !can_use_bridge_authority ||
     774           0 :                             !options->UpdateBridgesFromAuthority;
     775           0 :       log_debug(LD_DIR, "ask_bridge_directly=%d (%d, %d, %d)",
     776             :                 ask_bridge_directly, tor_digest_is_zero(bridge->identity),
     777             :                 !options->UpdateBridgesFromAuthority, !num_bridge_auths);
     778             : 
     779           0 :       if (ask_bridge_directly &&
     780           0 :           !reachable_addr_allows_addr(&bridge->addr, bridge->port,
     781             :                                                 FIREWALL_OR_CONNECTION, 0,
     782             :                                                 0)) {
     783           0 :         log_notice(LD_DIR, "Bridge at '%s' isn't reachable by our "
     784             :                    "firewall policy. %s.",
     785             :                    fmt_addrport(&bridge->addr, bridge->port),
     786             :                    can_use_bridge_authority ?
     787             :                      "Asking bridge authority instead" : "Skipping");
     788           0 :         if (can_use_bridge_authority)
     789             :           ask_bridge_directly = 0;
     790             :         else
     791           0 :           continue;
     792             :       }
     793             : 
     794           0 :       if (ask_bridge_directly) {
     795             :         /* we need to ask the bridge itself for its descriptor. */
     796           0 :         launch_direct_bridge_descriptor_fetch(bridge);
     797             :       } else {
     798             :         /* We have a digest and we want to ask an authority. We could
     799             :          * combine all the requests into one, but that may give more
     800             :          * hints to the bridge authority than we want to give. */
     801           0 :         char resource[10 + HEX_DIGEST_LEN];
     802           0 :         memcpy(resource, "fp/", 3);
     803           0 :         base16_encode(resource+3, HEX_DIGEST_LEN+1,
     804             :                       bridge->identity, DIGEST_LEN);
     805           0 :         memcpy(resource+3+HEX_DIGEST_LEN, ".z", 3);
     806           0 :         log_info(LD_DIR, "Fetching bridge info '%s' from bridge authority.",
     807             :                  resource);
     808           0 :         directory_get_from_dirserver(DIR_PURPOSE_FETCH_SERVERDESC,
     809             :                 ROUTER_PURPOSE_BRIDGE, resource, 0, DL_WANT_AUTHORITY);
     810             :       }
     811             :     }
     812           0 :   SMARTLIST_FOREACH_END(bridge);
     813             : }
     814             : 
     815             : /** If our <b>bridge</b> is configured to be a different address than
     816             :  * the bridge gives in <b>node</b>, rewrite the routerinfo
     817             :  * we received to use the address we meant to use. Now we handle
     818             :  * multihomed bridges better.
     819             :  */
     820             : static void
     821           0 : rewrite_node_address_for_bridge(const bridge_info_t *bridge, node_t *node)
     822             : {
     823             :   /* XXXX move this function. */
     824             :   /* XXXX overridden addresses should really live in the node_t, so that the
     825             :    *   routerinfo_t and the microdesc_t can be immutable.  But we can only
     826             :    *   do that safely if we know that no function that connects to an OR
     827             :    *   does so through an address from any source other than node_get_addr().
     828             :    */
     829           0 :   const or_options_t *options = get_options();
     830             : 
     831           0 :   if (node->ri) {
     832           0 :     routerinfo_t *ri = node->ri;
     833           0 :     if ((!tor_addr_compare(&bridge->addr, &ri->ipv4_addr, CMP_EXACT) &&
     834           0 :          bridge->port == ri->ipv4_orport) ||
     835           0 :         (!tor_addr_compare(&bridge->addr, &ri->ipv6_addr, CMP_EXACT) &&
     836           0 :          bridge->port == ri->ipv6_orport)) {
     837             :       /* they match, so no need to do anything */
     838             :     } else {
     839           0 :       if (tor_addr_family(&bridge->addr) == AF_INET) {
     840           0 :         tor_addr_copy(&ri->ipv4_addr, &bridge->addr);
     841           0 :         ri->ipv4_orport = bridge->port;
     842           0 :         log_info(LD_DIR,
     843             :                  "Adjusted bridge routerinfo for '%s' to match configured "
     844             :                  "address %s:%d.",
     845             :                  ri->nickname, fmt_addr(&ri->ipv4_addr), ri->ipv4_orport);
     846           0 :       } else if (tor_addr_family(&bridge->addr) == AF_INET6) {
     847           0 :         tor_addr_copy(&ri->ipv6_addr, &bridge->addr);
     848           0 :         ri->ipv6_orport = bridge->port;
     849           0 :         log_info(LD_DIR,
     850             :                  "Adjusted bridge routerinfo for '%s' to match configured "
     851             :                  "address %s.",
     852             :                  ri->nickname, fmt_addrport(&ri->ipv6_addr, ri->ipv6_orport));
     853             :       } else {
     854           0 :         log_err(LD_BUG, "Address family not supported: %d.",
     855             :                 tor_addr_family(&bridge->addr));
     856           0 :         return;
     857             :       }
     858             :     }
     859             : 
     860           0 :     if (options->ClientPreferIPv6ORPort == -1) {
     861             :       /* Mark which address to use based on which bridge_t we got. */
     862           0 :       node->ipv6_preferred = (tor_addr_family(&bridge->addr) == AF_INET6 &&
     863           0 :                               !tor_addr_is_null(&node->ri->ipv6_addr));
     864             :     } else {
     865             :       /* Mark which address to use based on user preference */
     866           0 :       node->ipv6_preferred = (reachable_addr_prefer_ipv6_orport(options) &&
     867           0 :                               !tor_addr_is_null(&node->ri->ipv6_addr));
     868             :     }
     869             : 
     870             :     /* XXXipv6 we lack support for falling back to another address for
     871             :        the same relay, warn the user */
     872           0 :     if (!tor_addr_is_null(&ri->ipv6_addr)) {
     873           0 :       tor_addr_port_t ap;
     874           0 :       node_get_pref_orport(node, &ap);
     875           0 :       log_notice(LD_CONFIG,
     876             :                  "Bridge '%s' has both an IPv4 and an IPv6 address.  "
     877             :                  "Will prefer using its %s address (%s) based on %s.",
     878             :                  ri->nickname,
     879             :                  node->ipv6_preferred ? "IPv6" : "IPv4",
     880             :                  fmt_addrport(&ap.addr, ap.port),
     881             :                  options->ClientPreferIPv6ORPort == -1 ?
     882             :                  "the configured Bridge address" :
     883             :                  "ClientPreferIPv6ORPort");
     884             :     }
     885             :   }
     886           0 :   if (node->rs) {
     887           0 :     routerstatus_t *rs = node->rs;
     888             : 
     889           0 :     if ((!tor_addr_compare(&bridge->addr, &rs->ipv4_addr, CMP_EXACT) &&
     890           0 :         bridge->port == rs->ipv4_orport) ||
     891           0 :        (!tor_addr_compare(&bridge->addr, &rs->ipv6_addr, CMP_EXACT) &&
     892           0 :         bridge->port == rs->ipv6_orport)) {
     893             :       /* they match, so no need to do anything */
     894             :     } else {
     895           0 :       if (tor_addr_family(&bridge->addr) == AF_INET) {
     896           0 :         tor_addr_copy(&rs->ipv4_addr, &bridge->addr);
     897           0 :         rs->ipv4_orport = bridge->port;
     898           0 :         log_info(LD_DIR,
     899             :                  "Adjusted bridge routerstatus for '%s' to match "
     900             :                  "configured address %s.",
     901             :                  rs->nickname, fmt_addrport(&bridge->addr, rs->ipv4_orport));
     902             :       /* set IPv6 preferences even if there is no ri */
     903           0 :       } else if (tor_addr_family(&bridge->addr) == AF_INET6) {
     904           0 :         tor_addr_copy(&rs->ipv6_addr, &bridge->addr);
     905           0 :         rs->ipv6_orport = bridge->port;
     906           0 :         log_info(LD_DIR,
     907             :                  "Adjusted bridge routerstatus for '%s' to match configured"
     908             :                  " address %s.",
     909             :                  rs->nickname, fmt_addrport(&rs->ipv6_addr, rs->ipv6_orport));
     910             :       } else {
     911           0 :         log_err(LD_BUG, "Address family not supported: %d.",
     912             :                 tor_addr_family(&bridge->addr));
     913           0 :         return;
     914             :       }
     915             :     }
     916             : 
     917           0 :     if (options->ClientPreferIPv6ORPort == -1) {
     918             :       /* Mark which address to use based on which bridge_t we got. */
     919           0 :       node->ipv6_preferred = (tor_addr_family(&bridge->addr) == AF_INET6 &&
     920           0 :                               !tor_addr_is_null(&node->rs->ipv6_addr));
     921             :     } else {
     922             :       /* Mark which address to use based on user preference */
     923           0 :       node->ipv6_preferred = (reachable_addr_prefer_ipv6_orport(options) &&
     924           0 :                               !tor_addr_is_null(&node->rs->ipv6_addr));
     925             :     }
     926             : 
     927             :     /* XXXipv6 we lack support for falling back to another address for
     928             :     the same relay, warn the user */
     929           0 :     if (!tor_addr_is_null(&rs->ipv6_addr)) {
     930           0 :       tor_addr_port_t ap;
     931           0 :       node_get_pref_orport(node, &ap);
     932           0 :       log_notice(LD_CONFIG,
     933             :                  "Bridge '%s' has both an IPv4 and an IPv6 address.  "
     934             :                  "Will prefer using its %s address (%s) based on %s.",
     935             :                  rs->nickname,
     936             :                  node->ipv6_preferred ? "IPv6" : "IPv4",
     937             :                  fmt_addrport(&ap.addr, ap.port),
     938             :                  options->ClientPreferIPv6ORPort == -1 ?
     939             :                  "the configured Bridge address" :
     940             :                  "ClientPreferIPv6ORPort");
     941             :     }
     942             :   }
     943             : }
     944             : 
     945             : /** We just learned a descriptor for a bridge. See if that
     946             :  * digest is in our entry guard list, and add it if not. */
     947             : void
     948           0 : learned_bridge_descriptor(routerinfo_t *ri, int from_cache)
     949             : {
     950           0 :   tor_assert(ri);
     951           0 :   tor_assert(ri->purpose == ROUTER_PURPOSE_BRIDGE);
     952           0 :   if (get_options()->UseBridges) {
     953             :     /* Retry directory downloads whenever we get a bridge descriptor:
     954             :      * - when bootstrapping, and
     955             :      * - when we aren't sure if any of our bridges are reachable.
     956             :      * Keep on retrying until we have at least one reachable bridge. */
     957           0 :     int first = num_bridges_usable(0) < 1;
     958           0 :     bridge_info_t *bridge = get_configured_bridge_by_routerinfo(ri);
     959           0 :     time_t now = time(NULL);
     960           0 :     router_set_status(ri->cache_info.identity_digest, 1);
     961             : 
     962           0 :     if (bridge) { /* if we actually want to use this one */
     963           0 :       node_t *node;
     964             :       /* it's here; schedule its re-fetch for a long time from now. */
     965           0 :       if (!from_cache) {
     966             :         /* This schedules the re-fetch at a constant interval, which produces
     967             :          * a pattern of bridge traffic. But it's better than trying all
     968             :          * configured bridges several times in the first few minutes. */
     969           0 :         download_status_reset(&bridge->fetch_status);
     970             :       }
     971             : 
     972           0 :       node = node_get_mutable_by_id(ri->cache_info.identity_digest);
     973           0 :       tor_assert(node);
     974           0 :       rewrite_node_address_for_bridge(bridge, node);
     975           0 :       if (tor_digest_is_zero(bridge->identity)) {
     976           0 :         memcpy(bridge->identity,ri->cache_info.identity_digest, DIGEST_LEN);
     977           0 :         log_notice(LD_DIR, "Learned identity %s for bridge at %s:%d",
     978             :                    hex_str(bridge->identity, DIGEST_LEN),
     979             :                    fmt_and_decorate_addr(&bridge->addr),
     980             :                    (int) bridge->port);
     981             :       }
     982           0 :       entry_guard_learned_bridge_identity(&bridge->addrport_configured,
     983             :                               (const uint8_t*)ri->cache_info.identity_digest);
     984             : 
     985           0 :       log_notice(LD_DIR, "new bridge descriptor '%s' (%s): %s", ri->nickname,
     986             :                  from_cache ? "cached" : "fresh", router_describe(ri));
     987             :       /* If we didn't have a reachable bridge before this one, try directory
     988             :        * documents again. */
     989           0 :       if (first) {
     990           0 :         routerlist_retry_directory_downloads(now);
     991             :       }
     992             :     }
     993             :   }
     994           0 : }
     995             : 
     996             : /** Return a smartlist containing all bridge identity digests */
     997           0 : MOCK_IMPL(smartlist_t *,
     998             : list_bridge_identities, (void))
     999             : {
    1000           0 :   smartlist_t *result = NULL;
    1001           0 :   char *digest_tmp;
    1002             : 
    1003           0 :   if (get_options()->UseBridges && bridge_list) {
    1004           0 :     result = smartlist_new();
    1005             : 
    1006           0 :     SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, b) {
    1007           0 :       digest_tmp = tor_malloc(DIGEST_LEN);
    1008           0 :       memcpy(digest_tmp, b->identity, DIGEST_LEN);
    1009           0 :       smartlist_add(result, digest_tmp);
    1010           0 :     } SMARTLIST_FOREACH_END(b);
    1011             :   }
    1012             : 
    1013           0 :   return result;
    1014             : }
    1015             : 
    1016             : /** Get the download status for a bridge descriptor given its identity */
    1017           0 : MOCK_IMPL(download_status_t *,
    1018             : get_bridge_dl_status_by_id, (const char *digest))
    1019             : {
    1020           0 :   download_status_t *dl = NULL;
    1021             : 
    1022           0 :   if (digest && get_options()->UseBridges && bridge_list) {
    1023           0 :     SMARTLIST_FOREACH_BEGIN(bridge_list, bridge_info_t *, b) {
    1024           0 :       if (tor_memeq(digest, b->identity, DIGEST_LEN)) {
    1025           0 :         dl = &(b->fetch_status);
    1026           0 :         break;
    1027             :       }
    1028           0 :     } SMARTLIST_FOREACH_END(b);
    1029             :   }
    1030             : 
    1031           0 :   return dl;
    1032             : }
    1033             : 
    1034             : /** Release all storage held in bridges.c */
    1035             : void
    1036         235 : bridges_free_all(void)
    1037             : {
    1038         235 :   clear_bridge_list();
    1039         235 :   smartlist_free(bridge_list);
    1040         235 :   bridge_list = NULL;
    1041         235 : }

Generated by: LCOV version 1.14