Prop#329 params: Consensus parameter and torrc handling

Signed-off-by: David Goulet <dgoulet@torproject.org>
This commit is contained in:
Mike Perry
2023-03-07 19:11:38 +00:00
parent 0d14d6b44a
commit eac2bad86b
6 changed files with 323 additions and 0 deletions
+6
View File
@@ -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
+1
View File
@@ -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"),
+4
View File
@@ -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. */
+281
View File
@@ -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@lists.torproject.org 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);
}
+29
View File
@@ -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 */
+2
View File
@@ -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();