aboutsummaryrefslogtreecommitdiff
path: root/guard-spec.txt
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2023-08-25 10:47:56 -0400
committerNick Mathewson <nickm@torproject.org>2023-08-25 10:47:56 -0400
commit8869cf39b6a10ab92a84504efafd48353dbc6707 (patch)
treeaf621b207662daa58dad5f175c39c0e63dc1faa8 /guard-spec.txt
parentc2976c825c6c3155b6e10f2b900555283aa302ab (diff)
downloadtorspec-8869cf39b6a10ab92a84504efafd48353dbc6707.tar.gz
torspec-8869cf39b6a10ab92a84504efafd48353dbc6707.zip
Merge 337-simpler-guard-usability.md into guard-spec
This proposal gives an alternative formulation of the usability rules of guard-spec, and the relationship between guard status and circuit status.
Diffstat (limited to 'guard-spec.txt')
-rw-r--r--guard-spec.txt59
1 files changed, 55 insertions, 4 deletions
diff --git a/guard-spec.txt b/guard-spec.txt
index 9a15eb8..154edae 100644
--- a/guard-spec.txt
+++ b/guard-spec.txt
@@ -257,6 +257,10 @@ Table of Contents
are trying to build an exploratory circuit through the
guard, and we don't know whether it will succeed.
+ - {tvar:pending_since}: A timestamp. Set whenever we set
+ {tvar:is_pending} to true; cleared whenever we set
+ {tvar:is_pending} to false. NOTE
+
We require that {SAMPLED_GUARDS} contain at least
{MIN_FILTERED_SAMPLE} guards from the consensus (if possible),
but not more than {MAX_SAMPLE_THRESHOLD} of the number of guards
@@ -519,13 +523,16 @@ Table of Contents
* Otherwise, if the ordered intersection of {CONFIRMED_GUARDS}
and {USABLE_FILTERED_GUARDS} is nonempty, return the first
entry in that intersection that has {is_pending} set to
- false. Set its value of {is_pending} to true. The circuit
+ false. Set its value of {is_pending} to true,
+ and set its {pending_since} to the current time.
+ The circuit
is now <usable_if_no_better_guard>. (If all entries have
{is_pending} true, pick the first one.)
* Otherwise, if there is no such entry, select a member from
{USABLE_FILTERED_GUARDS} in sample order. Set its {is_pending} field to
- true. The circuit is <usable_if_no_better_guard>.
+ true, and set its {pending_since} to the current time.
+ The circuit is <usable_if_no_better_guard>.
* Otherwise, if USABLE_FILTERED_GUARDS is empty, we have exhausted
all the sampled guards. In this case we proceed by marking all guards
@@ -565,7 +572,8 @@ Table of Contents
is not reachable, we take the following steps:
* Set the guard's {is_reachable} status to <no>. If it had
- {is_pending} set to true, we make it non-pending.
+ {is_pending} set to true, we make it non-pending and clear
+ {pending_since}.
* Close the circuit, of course. (This removes it from
consideration by the algorithm in [UPDATE_WAITING].)
@@ -588,7 +596,8 @@ Table of Contents
* We set its {is_reachable} status to <yes>.
* We set its {failing_since} to "never".
- * If the guard was {is_pending}, we clear the {is_pending} flag.
+ * If the guard was {is_pending}, we clear the {is_pending} flag
+ and set {pending_since} to false.
* If the guard was not a member of {CONFIRMED_GUARDS}, we add
it to the end of {CONFIRMED_GUARDS}.
@@ -652,6 +661,48 @@ Table of Contents
them after all if the <complete> circuit goes down before
{NONPRIMARY_GUARD_IDLE_TIMEOUT} seconds.
+4.9.1. Without a list of waiting circuits [Section:NO_CIRCLIST]
+
+ As an alternative to the section [SECTION:UPDATE_WAITING] above,
+ this section presents a new way to maintain guard status
+ independently of tracking individual circuit status. This
+ formulation gives a result equivalent or similar to the approach
+ above, but simplifies the necessary communications between the
+ guard and circuit subsystems.
+
+ As before, when all primary guards are Unreachable, we need to
+ try non-primary guards. We select the first such guard (in
+ preference order) that is neither Unreachable nor Pending.
+ Whenever we give out such a guard, if the guard's status is
+ Unknown, then we call that guard "Pending" with its {is_pending}
+ flag, until the attempt to use it succeeds or fails. We remember
+ when the guard became Pending with the {pending_since variable}.
+
+ After completing a circuit, the implementation must check whether
+ its guard is usable. A guard's usability status may be "usable",
+ "unusable", or "unknown". A guard is usable according to
+ these rules:
+
+ 1. Primary guards are always usable.
+
+ 2. Non-primary guards are usable _for a given circuit_ if every
+ guard earlier in the preference list is either unsuitable for
+ that circuit (e.g. because of family restrictions), or marked as
+ Unreachable, or has been pending for at least
+ `{NONPRIMARY_GUARD_CONNECT_TIMEOUT}`.
+
+ Non-primary guards are not usable _for a given circuit_ if some
+ guard earlier in the preference list is suitable for the circuit
+ _and_ Reachable.
+
+ Non-primary guards are unusable if they have not become
+ usable after `{NONPRIMARY_GUARD_IDLE_TIMEOUT}` seconds.
+
+ 3. If a circuit's guard is not usable or unusable immediately, the
+ circuit is not discarded; instead, it is kept (but not used) until the
+ guard becomes usable or unusable.
+
+
4.10. Whenever we get a new consensus. [Section:ON_CONSENSUS]
We update {GUARDS}.