[tor-bugs] #14579 [Tor]: Clients cannot use multiple transports with a single bridge

Tor Bug Tracker & Wiki blackhole at torproject.org
Sat Jan 31 08:00:31 UTC 2015


#14579: Clients cannot use multiple transports with a single bridge
--------------------+------------------------------------
 Reporter:  sysrqb  |          Owner:
     Type:  defect  |         Status:  new
 Priority:  normal  |      Milestone:  Tor: 0.2.7.x-final
Component:  Tor     |        Version:
 Keywords:          |  Actual Points:
Parent ID:          |         Points:
--------------------+------------------------------------
 (note, this bug is unverified)

 It seems that when a client adds more than one of a bridge's pluggable
 transport as its bridges, it only ever uses the address and port of the
 first transport it adds. Therefore, in the current situation, it appears
 if the first PT is disabled on the server-side (or the connection is
 blocked on the wire, or connections timeout for whatever reason) and the
 client attempts to use the second transport, it will try to establish the
 connection using the ip address and port number of the first transport. It
 may try connecting using the correct transport, but it'll probably connect
 to the wrong place.

 Specifically, all the transports are added to the bridge list, but we only
 use the information from the first bridge in the list with a given ID and
 ignore the rest.

 From learned_bridge_descriptor()
 {{{
     /* Choose the first bridge which either has an ID which matches
      * this routerinfo or the same address and orport if we don't
      * know the ID */
     bridge_info_t *bridge = get_configured_bridge_by_routerinfo(ri);
     time_t now = time(NULL);
     router_set_status(ri->cache_info.identity_digest, 1);

     if (bridge) { /* if we actually want to use this one */
       node_t *node;
       /* it's here; schedule its re-fetch for a long time from now. */
       if (!from_cache)
         download_status_reset(&bridge->fetch_status);

       /* get a *node_t for this bridge, based on its ID */
       node = node_get_mutable_by_id(ri->cache_info.identity_digest);
       tor_assert(node);
       /* Fill in the node_t using the details of the bridge we
        * retrieved above - the first bridge in the list
        */
       rewrite_node_address_for_bridge(bridge, node);
 }}}

 Then, we choose which entry node we want to use, in onion_extend_cpath(),
 where choose_good_entry_server() returns the *node_t representing the
 entry guard/bridge we should use, which it gets by ID:
 {{{
     const node_t *r = choose_good_entry_server(purpose, state);
     if (r) {
       /* If we're a client, use the preferred address rather than the
          primary address, for potentially connecting to an IPv6 OR
          port. */
       info = extend_info_from_node(r, server_mode(get_options()) == 0);
 }}}

 from populate_live_entry_guards()
 {{{
   SMARTLIST_FOREACH_BEGIN(all_entry_guards, const entry_guard_t *, entry)
 {
       const char *msg;
       node = entry_is_live(entry, entry_flags, &msg);
 }}}

 and finally, in extend_info_from_node() where we use the address and port
 defined in the *node_t:
 {{{
   if (for_direct_connect)
     node_get_pref_orport(node, &ap);
   else
     node_get_prim_orport(node, &ap);

   log_debug(LD_CIRC, "using %s for %s",
             fmt_addrport(&ap.addr, ap.port),
             node->ri ? node->ri->nickname : node->rs->nickname);

   if (node->ri)
     return extend_info_new(node->ri->nickname,
                              node->identity,
                              node->ri->onion_pkey,
                              node->ri->onion_curve25519_pkey,
                              &ap.addr,
                              ap.port);
 }}}

--
Ticket URL: <https://trac.torproject.org/projects/tor/ticket/14579>
Tor Bug Tracker & Wiki <https://trac.torproject.org/>
The Tor Project: anonymity online


More information about the tor-bugs mailing list