[tor-commits] [tor/main] Hook up client usage of congestion control negotiation

dgoulet at torproject.org dgoulet at torproject.org
Tue Feb 22 20:48:20 UTC 2022


commit 76bdadce121b0c33f46bb3d4e5eb0e8dc3277614
Author: Mike Perry <mikeperry-git at torproject.org>
Date:   Thu Nov 4 00:46:11 2021 +0000

    Hook up client usage of congestion control negotiation
---
 src/core/or/circuitbuild.c        | 52 ++++++++++++++++++++++++++++++++-------
 src/core/or/circuituse.c          |  6 +++--
 src/core/or/command.c             |  4 +--
 src/core/or/extend_info_st.h      |  7 +++---
 src/core/or/extendinfo.c          | 20 +++++++++------
 src/core/or/extendinfo.h          |  6 +++--
 src/feature/control/control_cmd.c |  5 +++-
 7 files changed, 72 insertions(+), 28 deletions(-)

diff --git a/src/core/or/circuitbuild.c b/src/core/or/circuitbuild.c
index 53582d2829..61d67c350d 100644
--- a/src/core/or/circuitbuild.c
+++ b/src/core/or/circuitbuild.c
@@ -72,6 +72,7 @@
 #include "feature/stats/predict_ports.h"
 #include "lib/crypt_ops/crypto_rand.h"
 #include "lib/trace/events.h"
+#include "core/or/congestion_control_common.h"
 
 #include "core/or/cell_st.h"
 #include "core/or/cpath_build_state_st.h"
@@ -80,6 +81,7 @@
 #include "feature/nodelist/node_st.h"
 #include "core/or/or_circuit_st.h"
 #include "core/or/origin_circuit_st.h"
+#include "trunnel/circ_params.h"
 
 static int circuit_send_first_onion_skin(origin_circuit_t *circ);
 static int circuit_build_no_more_hops(origin_circuit_t *circ);
@@ -841,7 +843,10 @@ circuit_pick_create_handshake(uint8_t *cell_type_out,
    * using the TAP handshake, and CREATE2 otherwise. */
   if (extend_info_supports_ntor(ei)) {
     *cell_type_out = CELL_CREATE2;
-    if (ei->supports_ntor3_and_param_negotiation)
+    /* Only use ntor v3 with exits that support congestion control,
+     * and only when it is enabled. */
+    if (ei->exit_supports_congestion_control &&
+        congestion_control_enabled())
       *handshake_type_out = ONION_HANDSHAKE_TYPE_NTOR_V3;
     else
       *handshake_type_out = ONION_HANDSHAKE_TYPE_NTOR;
@@ -1263,12 +1268,14 @@ circuit_finish_handshake(origin_circuit_t *circ,
 
   onion_handshake_state_release(&hop->handshake_state);
 
-  // XXXX TODO-324: use `params` to initialize the congestion control.
-
   if (cpath_init_circuit_crypto(hop, keys, sizeof(keys), 0, 0)<0) {
     return -END_CIRC_REASON_TORPROTOCOL;
   }
 
+  if (params.cc_enabled) {
+    hop->ccontrol = congestion_control_new(&params);
+  }
+
   hop->state = CPATH_STATE_OPEN;
   log_info(LD_CIRC,"Finished building circuit hop:");
   circuit_log_path(LOG_INFO,LD_CIRC,circ);
@@ -2068,7 +2075,10 @@ onion_pick_cpath_exit(origin_circuit_t *circ, extend_info_t *exit_ei,
       log_warn(LD_CIRC,"Failed to choose an exit server");
       return -1;
     }
-    exit_ei = extend_info_from_node(node, state->onehop_tunnel);
+    exit_ei = extend_info_from_node(node, state->onehop_tunnel,
+                /* for_exit_use */
+                !state->is_internal && TO_CIRCUIT(circ)->purpose ==
+                  CIRCUIT_PURPOSE_C_GENERAL);
     if (BUG(exit_ei == NULL))
       return -1;
   }
@@ -2464,7 +2474,7 @@ onion_extend_cpath(origin_circuit_t *circ)
          primary address, for potentially connecting to an IPv6 OR
          port. Servers always want the primary (IPv4) address. */
       int client = (server_mode(get_options()) == 0);
-      info = extend_info_from_node(r, client);
+      info = extend_info_from_node(r, client, false);
       /* Clients can fail to find an allowed address */
       tor_assert_nonfatal(info || client);
     }
@@ -2472,7 +2482,7 @@ onion_extend_cpath(origin_circuit_t *circ)
     const node_t *r =
       choose_good_middle_server(purpose, state, circ->cpath, cur_len);
     if (r) {
-      info = extend_info_from_node(r, 0);
+      info = extend_info_from_node(r, 0, false);
     }
   }
 
@@ -2597,9 +2607,33 @@ client_circ_negotiation_message(const extend_info_t *ei,
                                 size_t *msg_len_out)
 {
   tor_assert(ei && msg_out && msg_len_out);
-  if (! ei->supports_ntor3_and_param_negotiation)
+  circ_params_request_t params = {0};
+  ssize_t msg_len = 0;
+
+  if (! ei->exit_supports_congestion_control)
     return -1;
 
-  /* TODO-324: fill in the client message that gets sent. */
-  tor_assert_unreached();
+  circ_params_request_set_version(&params, 0);
+
+  circ_params_request_set_cc_supported(&params,
+                                       congestion_control_enabled());
+
+  msg_len = circ_params_request_encoded_len(&params);
+
+  if (msg_len < 0) {
+    return -1;
+  }
+
+  *msg_out = tor_malloc_zero(msg_len);
+
+  msg_len = circ_params_request_encode(*msg_out, msg_len, &params);
+
+  if (msg_len < 0) {
+    tor_free(*msg_out);
+    return -1;
+  }
+
+  *msg_len_out = (size_t)msg_len;
+
+  return 0;
 }
diff --git a/src/core/or/circuituse.c b/src/core/or/circuituse.c
index 104e898d6c..a259957d37 100644
--- a/src/core/or/circuituse.c
+++ b/src/core/or/circuituse.c
@@ -2427,7 +2427,8 @@ circuit_get_open_circ_or_launch(entry_connection_t *conn,
           /* We might want to connect to an IPv6 bridge for loading
              descriptors so we use the preferred address rather than
              the primary. */
-          extend_info = extend_info_from_node(r, conn->want_onehop ? 1 : 0);
+          extend_info = extend_info_from_node(r, conn->want_onehop ? 1 : 0,
+                         desired_circuit_purpose == CIRCUIT_PURPOSE_C_GENERAL);
           if (!extend_info) {
             log_warn(LD_CIRC,"Could not make a one-hop connection to %s. "
                      "Discarding this circuit.", conn->chosen_exit_name);
@@ -2463,7 +2464,8 @@ circuit_get_open_circ_or_launch(entry_connection_t *conn,
                                           NULL, /* Ed25519 ID */
                                           NULL, NULL, /* onion keys */
                                           &addr, conn->socks_request->port,
-                                          NULL);
+                                          NULL,
+                                          false);
           } else { /* ! (want_onehop && conn->chosen_exit_name[0] == '$') */
             /* We will need an onion key for the router, and we
              * don't have one. Refuse or relax requirements. */
diff --git a/src/core/or/command.c b/src/core/or/command.c
index 12e4c26768..ffdd1f19d9 100644
--- a/src/core/or/command.c
+++ b/src/core/or/command.c
@@ -367,6 +367,7 @@ command_process_create_cell(cell_t *cell, channel_t *chan)
                                        create_cell->onionskin,
                                        create_cell->handshake_len,
                                        NULL,
+                                       NULL,
                                        created_cell.reply,
                                        sizeof(created_cell.reply),
                                        keys, CPATH_KEY_MATERIAL_LEN,
@@ -381,9 +382,6 @@ command_process_create_cell(cell_t *cell, channel_t *chan)
     created_cell.cell_type = CELL_CREATED_FAST;
     created_cell.handshake_len = len;
 
-    // TODO-324: We should in theory look at params here, though it will
-    // always tell us to use the old-fashioned congestion control.
-
     if (onionskin_answer(circ, &created_cell,
                          (const char *)keys, sizeof(keys),
                          rend_circ_nonce)<0) {
diff --git a/src/core/or/extend_info_st.h b/src/core/or/extend_info_st.h
index 1666b168ad..2ab0beb7e6 100644
--- a/src/core/or/extend_info_st.h
+++ b/src/core/or/extend_info_st.h
@@ -38,9 +38,10 @@ struct extend_info_t {
   crypto_pk_t *onion_key;
   /** Ntor onion key for this hop. */
   curve25519_public_key_t curve25519_onion_key;
-  /** True if this hop supports NtorV3 _and_ negotiation of at least one
-   * relevant circuit parameter (currently only congestion control). */
-  bool supports_ntor3_and_param_negotiation;
+  /** True if this hop is to be used as an _exit_,
+   * and it also supports supports NtorV3 _and_ negotiation
+   * of congestion control parameters */
+  bool exit_supports_congestion_control;
 };
 
 #endif /* !defined(EXTEND_INFO_ST_H) */
diff --git a/src/core/or/extendinfo.c b/src/core/or/extendinfo.c
index ca2288e0a4..ca623f09ce 100644
--- a/src/core/or/extendinfo.c
+++ b/src/core/or/extendinfo.c
@@ -36,7 +36,8 @@ extend_info_new(const char *nickname,
                 crypto_pk_t *onion_key,
                 const curve25519_public_key_t *ntor_key,
                 const tor_addr_t *addr, uint16_t port,
-                const protover_summary_flags_t *pv)
+                const protover_summary_flags_t *pv,
+                bool for_exit_use)
 {
   extend_info_t *info = tor_malloc_zero(sizeof(extend_info_t));
   if (rsa_id_digest)
@@ -58,9 +59,9 @@ extend_info_new(const char *nickname,
     extend_info_add_orport(info, addr, port);
   }
 
-  if (pv) {
-    info->supports_ntor3_and_param_negotiation =
-      pv->supports_ntor3_and_param_negotiation;
+  if (pv && for_exit_use) {
+    info->exit_supports_congestion_control =
+      pv->supports_congestion_control;
   }
 
   return info;
@@ -96,7 +97,8 @@ extend_info_add_orport(extend_info_t *ei,
  * and IP version config.
  **/
 extend_info_t *
-extend_info_from_node(const node_t *node, int for_direct_connect)
+extend_info_from_node(const node_t *node, int for_direct_connect,
+                      bool for_exit)
 {
   crypto_pk_t *rsa_pubkey = NULL;
   extend_info_t *info = NULL;
@@ -157,7 +159,8 @@ extend_info_from_node(const node_t *node, int for_direct_connect)
                            curve_pubkey,
                            &ap.addr,
                            ap.port,
-                           &node->ri->pv);
+                           &node->ri->pv,
+                           for_exit);
   } else if (valid_addr && node->rs && node->md) {
     info = extend_info_new(node->rs->nickname,
                            node->identity,
@@ -166,7 +169,8 @@ extend_info_from_node(const node_t *node, int for_direct_connect)
                            curve_pubkey,
                            &ap.addr,
                            ap.port,
-                           &node->rs->pv);
+                           &node->rs->pv,
+                           for_exit);
   }
 
   crypto_pk_free(rsa_pubkey);
@@ -225,7 +229,7 @@ extend_info_supports_ntor_v3(const extend_info_t *ei)
 {
   tor_assert(ei);
   return extend_info_supports_ntor(ei) &&
-    ei->supports_ntor3_and_param_negotiation;
+    ei->exit_supports_congestion_control;
 }
 
 /* Does ei have an onion key which it would prefer to use?
diff --git a/src/core/or/extendinfo.h b/src/core/or/extendinfo.h
index 8781cc7047..6d1f20597b 100644
--- a/src/core/or/extendinfo.h
+++ b/src/core/or/extendinfo.h
@@ -18,8 +18,10 @@ extend_info_t *extend_info_new(const char *nickname,
                                crypto_pk_t *onion_key,
                                const struct curve25519_public_key_t *ntor_key,
                                const tor_addr_t *addr, uint16_t port,
-                               const struct protover_summary_flags_t *pv);
-extend_info_t *extend_info_from_node(const node_t *r, int for_direct_connect);
+                               const struct protover_summary_flags_t *pv,
+                               bool for_exit_use);
+extend_info_t *extend_info_from_node(const node_t *r, int for_direct_connect,
+                                     bool for_exit);
 extend_info_t *extend_info_dup(extend_info_t *info);
 void extend_info_free_(extend_info_t *info);
 #define extend_info_free(info) \
diff --git a/src/feature/control/control_cmd.c b/src/feature/control/control_cmd.c
index b19935e456..dd0cde4f7d 100644
--- a/src/feature/control/control_cmd.c
+++ b/src/feature/control/control_cmd.c
@@ -823,7 +823,10 @@ handle_control_extendcircuit(control_connection_t *conn,
   first_node = zero_circ;
   SMARTLIST_FOREACH(nodes, const node_t *, node,
   {
-    extend_info_t *info = extend_info_from_node(node, first_node);
+    /* We treat every hop as an exit to try to negotiate congestion
+     * control, because we have no idea which hop the controller wil
+     * try to use for streams and when */
+    extend_info_t *info = extend_info_from_node(node, first_node, true);
     if (!info) {
       tor_assert_nonfatal(first_node);
       log_warn(LD_CONTROL,





More information about the tor-commits mailing list