[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[tor-commits] [tor] 05/20: Prop#329 params: Consensus parameter and torrc handling



This is an automated email from the git hooks/post-receive script.

ahf pushed a commit to branch main
in repository tor.

commit eac2bad86b6491b73b0086528b2b2cffe6c0d862
Author: Mike Perry <mikeperry-git@xxxxxxxxxxxxxx>
AuthorDate: Tue Mar 7 19:11:38 2023 +0000

    Prop#329 params: Consensus parameter and torrc handling
    
    Signed-off-by: David Goulet <dgoulet@xxxxxxxxxxxxxx>
---
 doc/man/tor.1.txt                    |   6 +
 src/app/config/config.c              |   1 +
 src/app/config/or_options_st.h       |   4 +
 src/core/or/conflux_params.c         | 281 +++++++++++++++++++++++++++++++++++
 src/core/or/conflux_params.h         |  29 ++++
 src/feature/nodelist/networkstatus.c |   2 +
 6 files changed, 323 insertions(+)

diff --git a/doc/man/tor.1.txt b/doc/man/tor.1.txt
index e81b290b55..57992cd8d2 100644
--- a/doc/man/tor.1.txt
+++ b/doc/man/tor.1.txt
@@ -348,6 +348,12 @@ forward slash (/) in the configuration file and on the command line.
     forwards its traffic to it. It's the duty of that proxy to properly forward
     the traffic to the bridge. (Default: none)
 
+[[ConfluxEnabled]] **ConfluxEnabled** **0**|**1**|**auto**::
+    If this option is set to 1, general purpose traffic will use Conflux which
+    is traffic splitting among multiple legs (circuits). Onion services are not
+    supported at the moment. Default value is set to "auto" meaning the
+    consensus is used to decide unless set. (Default: auto)
+
 [[ConnLimit]] **ConnLimit** __NUM__::
     The minimum number of file descriptors that must be available to the Tor
     process before it will start. Tor will ask the OS for as many file
diff --git a/src/app/config/config.c b/src/app/config/config.c
index 6b07d58240..66a8fe5853 100644
--- a/src/app/config/config.c
+++ b/src/app/config/config.c
@@ -377,6 +377,7 @@ static const config_var_t option_vars_[] = {
   V(ClientTransportPlugin,       LINELIST, NULL),
   V(ClientUseIPv6,               BOOL,     "0"),
   V(ClientUseIPv4,               BOOL,     "1"),
+  V(ConfluxEnabled,              AUTOBOOL, "auto"),
   V(ConnLimit,                   POSINT,     "1000"),
   V(ConnDirectionStatistics,     BOOL,     "0"),
   V(ConstrainedSockets,          BOOL,     "0"),
diff --git a/src/app/config/or_options_st.h b/src/app/config/or_options_st.h
index 0811af1388..056aa3b776 100644
--- a/src/app/config/or_options_st.h
+++ b/src/app/config/or_options_st.h
@@ -723,6 +723,10 @@ struct or_options_t {
    * accessing this value directly.  */
   int ClientPreferIPv6DirPort;
 
+  /** If true, the tor client will use conflux for its general purpose
+   * circuits which excludes onion service traffic. */
+  int ConfluxEnabled;
+
   /** The length of time that we think a consensus should be fresh. */
   int V3AuthVotingInterval;
   /** The length of time we think it will take to distribute votes. */
diff --git a/src/core/or/conflux_params.c b/src/core/or/conflux_params.c
new file mode 100644
index 0000000000..f149e3356c
--- /dev/null
+++ b/src/core/or/conflux_params.c
@@ -0,0 +1,281 @@
+/* Copyright (c) 2023, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file conflux_params.h
+ * \brief Header file for conflux_params.c.
+ **/
+
+#include "core/or/or.h"
+
+#include "app/config/config.h"
+
+#include "core/or/conflux_params.h"
+#include "core/or/congestion_control_common.h"
+#include "core/or/circuitlist.h"
+
+#include "feature/nodelist/networkstatus.h"
+#include "feature/nodelist/networkstatus_st.h"
+#include "feature/nodelist/routerstatus_st.h"
+#include "feature/relay/routermode.h"
+
+#include "core/or/origin_circuit_st.h"
+
+/**
+ * Consensus parameters defaults, minimums and maximums.
+ */
+
+/* For "cfx_enabled". */
+#define CONFLUX_ENABLED_MIN (0)
+#define CONFLUX_ENABLED_MAX (1)
+#define CONFLUX_ENABLED_DEFAULT (1)
+
+/* For "cfx_low_exit_threshold". This is a percentage scaled to 10000 so we can
+ * support two decimal points. For example, 65.78% would be 6578. */
+#define LOW_EXIT_THRESHOLD_MIN (0)
+#define LOW_EXIT_THRESHOLD_MAX (10000)
+#define LOW_EXIT_THRESHOLD_DEFAULT (6000)
+
+/* For "cfx_max_linked_set". */
+#define MAX_LINKED_SET_MIN (0)
+#define MAX_LINKED_SET_MAX (UINT8_MAX)
+#define MAX_LINKED_SET_DEFAULT (10)
+
+/* For "cfx_max_prebuilt_set". */
+#define MAX_PREBUILT_SET_MIN (0)
+#define MAX_PREBUILT_SET_MAX (UINT8_MAX)
+#define MAX_PREBUILT_SET_DEFAULT (3)
+
+/* For "cfx_max_leg_retry". */
+#define MAX_UNLINKED_LEG_RETRY_DEFAULT (3)
+#define MAX_UNLINKED_LEG_RETRY_MIN (0)
+#define MAX_UNLINKED_LEG_RETRY_MAX (UINT8_MAX)
+
+/* For "cfx_num_legs_set". */
+#define NUM_LEGS_SET_MIN (0)
+#define NUM_LEGS_SET_MAX (UINT8_MAX)
+#define NUM_LEGS_SET_DEFAULT (2)
+
+/* For "cfx_send_pct". */
+#define CFX_SEND_PCT_MIN (0)
+#define CFX_SEND_PCT_MAX (255)
+#define CFX_SEND_PCT_DFLT 100
+
+/* For "cfx_drain_pct". */
+#define CFX_DRAIN_PCT_MIN (0)
+#define CFX_DRAIN_PCT_MAX (255)
+#define CFX_DRAIN_PCT_DFLT 0
+
+/*
+ * Cached consensus parameters.
+ */
+
+/* Indicate if conflux is enabled or disabled. */
+static bool conflux_enabled = CONFLUX_ENABLED_DEFAULT;
+/* Maximum number of linked set we are allowed to have (even if in use). */
+static uint8_t max_linked_set = MAX_LINKED_SET_DEFAULT;
+/* Maximum number of pre built set. */
+static uint8_t max_prebuilt_set = MAX_PREBUILT_SET_DEFAULT;
+/* Maximum number of unlinked leg retry that is how many times are we allowed
+ * to retry a leg until it successfully links. */
+STATIC uint32_t max_unlinked_leg_retry = MAX_UNLINKED_LEG_RETRY_DEFAULT;
+/* Number of legs per set. */
+static uint8_t num_legs_set = NUM_LEGS_SET_DEFAULT;
+/* The low Exit relay threshold, as a ratio between 0 and 1, used as a limit to
+ * decide the amount of pre-built set we build depending on how many Exit relay
+ * supports conflux in our current consensus. */
+static double low_exit_threshold_ratio =
+  LOW_EXIT_THRESHOLD_DEFAULT / (double)LOW_EXIT_THRESHOLD_MAX;
+
+static uint8_t cfx_drain_pct = CFX_DRAIN_PCT_DFLT;
+static uint8_t cfx_send_pct = CFX_SEND_PCT_DFLT;
+
+/* Ratio of Exit relays in our consensus supporting conflux. This is computed
+ * at every consensus and it is between 0 and 1. */
+static double exit_conflux_ratio = 0.0;
+
+/** Sets num_conflux_exit with the latest count of Exits in the given consensus
+ * that supports Conflux. */
+static void
+count_exit_with_conflux_support(const networkstatus_t *ns)
+{
+  double supported = 0.0;
+
+  if (!ns || smartlist_len(ns->routerstatus_list) == 0) {
+    return;
+  }
+
+  SMARTLIST_FOREACH_BEGIN(ns->routerstatus_list, const routerstatus_t *, rs) {
+    if (rs->pv.supports_conflux) {
+      supported++;
+    }
+  } SMARTLIST_FOREACH_END(rs);
+
+  exit_conflux_ratio =
+    supported / smartlist_len(ns->routerstatus_list);
+
+  log_info(LD_GENERAL, "Consensus has %.2f %% Exit relays supporting Conflux",
+           exit_conflux_ratio * 100.0);
+}
+
+/**
+ * Return true iff conflux feature is enabled and usable for a given circuit.
+ *
+ * Circ may be NULL, in which case we only check the consensus and torrc. */
+bool
+conflux_is_enabled(const circuit_t *circ)
+{
+  const or_options_t *opts = get_options();
+
+  /* Conflux CAN NOT operate properly without congestion control and so
+   * automatically disabled conflux if we don't have CC enabled. */
+  if (!congestion_control_enabled()) {
+    return false;
+  }
+
+  if (circ) {
+    /* If circuit is non-null, we need to check to see if congestion
+     * control was successfully negotiated. Conflux depends upon congestion
+     * control, and consensus checks are not enough because there can be a
+     * race between those checks and the consensus update to enable
+     * congestion control. This happens in Shadow, and at relay restart. */
+    if (CIRCUIT_IS_ORIGIN(circ)) {
+      tor_assert(CONST_TO_ORIGIN_CIRCUIT(circ)->cpath);
+      tor_assert(CONST_TO_ORIGIN_CIRCUIT(circ)->cpath->prev);
+      if (!CONST_TO_ORIGIN_CIRCUIT(circ)->cpath->prev->ccontrol)
+        return false;
+    } else {
+      if (!circ->ccontrol)
+        return false;
+    }
+  }
+
+  /* For clients, this is mostly for sbws. For relays, this is an emergency
+   * emergency override, in case a bug is discovered by a relay operator
+   * and we can't set a consensus param fast enough. Basically gives them
+   * an option other than downgrading. */
+  if (opts->ConfluxEnabled != -1) {
+    if (server_mode(opts)) {
+      char *msg;
+      static ratelim_t rlimit = RATELIM_INIT(60 * 60); /* Hourly */
+      if ((msg = rate_limit_log(&rlimit, time(NULL)))) {
+        log_warn(LD_GENERAL,
+                 "This tor is a relay and ConfluxEnabled is set to 0. "
+                 "We would ask you to please write to us on "
+                 "tor-relay@xxxxxxxxxxxxxxxxxxxx or file a bug explaining "
+                 "why you have disabled this option. Without news from you, "
+                 "we might end up marking your relay as a BadExit.");
+        tor_free(msg);
+      }
+    }
+    return opts->ConfluxEnabled;
+  }
+
+  return conflux_enabled;
+}
+
+/** Return the maximum number of linked set we are allowed to have. */
+uint8_t
+conflux_params_get_max_linked_set(void)
+{
+  return max_linked_set;
+}
+
+/** Return the number of maximum pre built sets that is allowed to have. */
+uint8_t
+conflux_params_get_max_prebuilt(void)
+{
+  /* Without any Exit supporting conflux, we won't be able to build a set. The
+   * float problem here is minimal because exit_conflux_ratio is either a flat
+   * 0 or else it means we do have at least an exit. */
+  if (exit_conflux_ratio <= 0.0) {
+    return 0;
+  }
+
+  /* Allow only 1 pre built set if we are lower than the low exit threshold
+   * parameter from the consensus. */
+  if (exit_conflux_ratio < low_exit_threshold_ratio) {
+    return 1;
+  }
+  return max_prebuilt_set;
+}
+
+/** Return the maximum number of retry we can do until a leg links. */
+uint8_t
+conflux_params_get_max_unlinked_leg_retry(void)
+{
+  return max_unlinked_leg_retry;
+}
+
+/** Return the number of legs per set. */
+uint8_t
+conflux_params_get_num_legs_set(void)
+{
+  return num_legs_set;
+}
+
+/** Return the drain percent we must hit before switching */
+uint8_t
+conflux_params_get_drain_pct(void)
+{
+  return cfx_drain_pct;
+}
+
+/** Return the percent of the congestion window to send before switching. */
+uint8_t
+conflux_params_get_send_pct(void)
+{
+  return cfx_send_pct;
+}
+
+/** Update global conflux related consensus parameter values, every consensus
+ * update. */
+void
+conflux_params_new_consensus(const networkstatus_t *ns)
+{
+  /* Params used by conflux_pool.c */
+  conflux_enabled =
+    networkstatus_get_param(ns, "cfx_enabled",
+                            CONFLUX_ENABLED_DEFAULT,
+                            CONFLUX_ENABLED_MIN, CONFLUX_ENABLED_MAX);
+
+  low_exit_threshold_ratio =
+    networkstatus_get_param(ns, "cfx_low_exit_threshold",
+                            LOW_EXIT_THRESHOLD_DEFAULT,
+                            LOW_EXIT_THRESHOLD_MIN, LOW_EXIT_THRESHOLD_MAX) /
+    (double)LOW_EXIT_THRESHOLD_MAX;
+
+  max_linked_set =
+    networkstatus_get_param(ns, "cfx_max_linked_set",
+                            MAX_LINKED_SET_DEFAULT,
+                            MAX_LINKED_SET_MIN, MAX_LINKED_SET_MAX);
+
+  max_prebuilt_set =
+    networkstatus_get_param(ns, "cfx_max_prebuilt_set",
+                            MAX_PREBUILT_SET_DEFAULT,
+                            MAX_PREBUILT_SET_MIN, MAX_PREBUILT_SET_MAX);
+
+  max_unlinked_leg_retry =
+    networkstatus_get_param(ns, "cfx_max_unlinked_leg_retry",
+                            MAX_UNLINKED_LEG_RETRY_DEFAULT,
+                            MAX_UNLINKED_LEG_RETRY_MIN,
+                            MAX_UNLINKED_LEG_RETRY_MAX);
+
+  num_legs_set =
+    networkstatus_get_param(ns, "cfx_num_legs_set",
+                            NUM_LEGS_SET_DEFAULT,
+                            NUM_LEGS_SET_MIN, NUM_LEGS_SET_MAX);
+
+  /* Params used by conflux.c */
+  cfx_send_pct = networkstatus_get_param(ns, "cfx_send_pct",
+      CFX_SEND_PCT_DFLT,
+      CFX_SEND_PCT_MIN,
+      CFX_SEND_PCT_MAX);
+
+  cfx_drain_pct = networkstatus_get_param(ns, "cfx_drain_pct",
+      CFX_DRAIN_PCT_DFLT,
+      CFX_DRAIN_PCT_MIN,
+      CFX_DRAIN_PCT_MAX);
+
+  count_exit_with_conflux_support(ns);
+}
diff --git a/src/core/or/conflux_params.h b/src/core/or/conflux_params.h
new file mode 100644
index 0000000000..22c3e4ad1f
--- /dev/null
+++ b/src/core/or/conflux_params.h
@@ -0,0 +1,29 @@
+/* Copyright (c) 2023, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file conflux_params.h
+ * \brief Header file for conflux_params.c.
+ **/
+
+#ifndef TOR_CONFLUX_PARAMS_H
+#define TOR_CONFLUX_PARAMS_H
+
+#include "core/or/or.h"
+
+bool conflux_is_enabled(const struct circuit_t *circ);
+uint8_t conflux_params_get_max_linked_set(void);
+uint8_t conflux_params_get_max_prebuilt(void);
+uint8_t conflux_params_get_max_unlinked_leg_retry(void);
+uint8_t conflux_params_get_num_legs_set(void);
+uint8_t conflux_params_get_drain_pct(void);
+uint8_t conflux_params_get_send_pct(void);
+
+void conflux_params_new_consensus(const networkstatus_t *ns);
+
+#ifdef TOR_UNIT_TESTS
+extern uint32_t max_unlinked_leg_retry;
+#endif
+
+#endif /* TOR_CONFLUX_PARAMS_H */
+
diff --git a/src/feature/nodelist/networkstatus.c b/src/feature/nodelist/networkstatus.c
index b994cfabc4..f14034c2b7 100644
--- a/src/feature/nodelist/networkstatus.c
+++ b/src/feature/nodelist/networkstatus.c
@@ -51,6 +51,7 @@
 #include "core/or/circuitmux.h"
 #include "core/or/circuitmux_ewma.h"
 #include "core/or/circuitstats.h"
+#include "core/or/conflux_params.h"
 #include "core/or/connection_edge.h"
 #include "core/or/connection_or.h"
 #include "core/or/dos.h"
@@ -1711,6 +1712,7 @@ notify_after_networkstatus_changes(void)
   flow_control_new_consensus_params(c);
   hs_service_new_consensus_params(c);
   dns_new_consensus_params(c);
+  conflux_params_new_consensus(c);
 
   /* Maintenance of our L2 guard list */
   maintain_layer2_guards();

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits