aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cert-spec.txt30
-rw-r--r--dir-spec.txt245
-rw-r--r--param-spec.txt426
-rw-r--r--proposals/000-index.txt4
-rw-r--r--proposals/316-flashflow.md (renamed from proposals/316-flashflow.txt)659
-rw-r--r--proposals/326-tor-relay-well-known-uri-rfc8615.md72
-rw-r--r--proposals/327-pow-over-intro.txt1129
-rw-r--r--proposals/BY_INDEX.md4
-rw-r--r--proposals/README.md4
-rw-r--r--pt-spec.txt35
-rw-r--r--tor-spec.txt38
11 files changed, 2084 insertions, 562 deletions
diff --git a/cert-spec.txt b/cert-spec.txt
index 1d57645..08d754d 100644
--- a/cert-spec.txt
+++ b/cert-spec.txt
@@ -49,11 +49,11 @@
The "VERSION" field holds the value [01]. The "CERT_TYPE" field
holds a value depending on the type of certificate. (See appendix
A.1.) The CERTIFIED_KEY field is an Ed25519 public key if
- CERT_KEY_TYPE is [01], or a SHA256 hash of some other key type
- depending on the value of CERT_KEY_TYPE. The EXPIRATION_DATE is a
- date, given in HOURS since the epoch, after which this
- certificate isn't valid. (A four-byte field here will work fine
- until 10136 A.D.)
+ CERT_KEY_TYPE is [01], or a digest of some other key type
+ depending on the value of CERT_KEY_TYPE. (See appendix A.4.)
+ The EXPIRATION_DATE is a date, given in HOURS since the epoch,
+ after which this certificate isn't valid. (A four-byte field here
+ will work fine until 10136 A.D.)
The EXTENSIONS field contains zero or more extensions, each of
the format:
@@ -116,7 +116,7 @@
acts with the authority of the RSA key that signed this
certificate."
-A.1. List of certificate types
+A.1. List of certificate types (CERT_TYPE field)
The values marked with asterisks are not types corresponding to
the certificate format of section 2.1. Instead, they are
@@ -166,14 +166,14 @@ A.3. List of signature prefixes
"Tor router descriptor signature v1" (see dir-spec.txt)
-A.4. List of certified key types
+A.4. List of certified key types (CERT_KEY_TYPE field)
[01] ed25519 key
- [02] SHA256 hash of an RSA key
- [03] SHA256 hash of an X.509 certificate
- [08] short-term HS descriptor signing key, signed with blinded public key (rend-spec-v3.txt)
- [09] intro point authentication key, cross-certifying the HS descriptor
- signing key (rend-spec-v3.txt)
- [0B] ed25519 key derived from the curve25519 intro point encryption key,
- cross-certifying the HS descriptor signing key (rend-spec-v3.txt)
-
+ [02] SHA256 hash of an RSA key. (Not currently used.)
+ [03] SHA256 hash of an X.509 certificate. (Used with certificate
+ type 5.)
+
+ (NOTE: Up till 0.4.5.1-alpha, all versions of Tor have incorrectly used
+ "01" for all types of certified key. Implementations SHOULD
+ allow "01" in this position, and infer the actual key type from
+ the CERT_TYPE field.)
diff --git a/dir-spec.txt b/dir-spec.txt
index 6b0f438..dbb15ab 100644
--- a/dir-spec.txt
+++ b/dir-spec.txt
@@ -343,7 +343,8 @@
change does remove one common cause of consensus splits.
VA-DistSeconds: The authorities calculate the consensus and exchange
- signatures.
+ signatures. (This is the earliest point at which anybody can
+ possibly get a given consensus if they ask for it.)
VA-DistSeconds/2: The authorities try to download any signatures
they don't have.
@@ -1758,7 +1759,14 @@
[Exactly once.]
The start of the Interval for this vote. Before this time, the
- consensus document produced from this vote should not be used.
+ consensus document produced from this vote is not officially in
+ use.
+
+ (Note that because of propagation delays, clients and relays
+ may see consensus documents that are up to `DistSeconds`
+ earlier than this this time, and should not warn about
+ them.)
+
See section 1.4 for voting timeline information.
"fresh-until" SP YYYY-MM-DD SP HH:MM:SS NL
@@ -1923,238 +1931,7 @@
(Only included when the vote is generated with consensus-method 7 or
later.)
- Commonly used "param" arguments at this point include:
-
- "circwindow" -- the default package window that circuits should
- be established with. It started out at 1000 cells, but some
- research indicates that a lower value would mean fewer cells in
- transit in the network at any given time.
- Min: 100, Max: 1000
- First-appeared: Tor 0.2.1.20
-
- "CircuitPriorityHalflifeMsec" -- the halflife parameter used when
- weighting which circuit will send the next cell. Obeyed by Tor
- 0.2.2.10-alpha and later. (Versions of Tor between 0.2.2.7-alpha
- and 0.2.2.10-alpha recognized a "CircPriorityHalflifeMsec" parameter,
- but mishandled it badly.)
- Min: -1, Max: 2147483647 (INT32_MAX)
- First-appeared: Tor 0.2.2.11-alpha
-
- "perconnbwrate" and "perconnbwburst" -- if set, each relay sets
- up a separate token bucket for every client OR connection,
- and rate limits that connection indepedently. Typically left
- unset, except when used for performance experiments around trac
- entry 1750. Only honored by relays running Tor 0.2.2.16-alpha
- and later. (Note that relays running 0.2.2.7-alpha through
- 0.2.2.14-alpha looked for bwconnrate and bwconnburst, but then
- did the wrong thing with them; see bug 1830 for details.)
- Min: 1, Max: 2147483647 (INT32_MAX)
- First-appeared: 0.2.2.7-alpha
- Removed-in: 0.2.2.16-alpha
-
- "refuseunknownexits" -- if set to one, exit relays look at
- the previous hop of circuits that ask to open an exit stream,
- and refuse to exit if they don't recognize it as a relay. The
- goal is to make it harder for people to use them as one-hop
- proxies. See trac entry 1751 for details.
- Min: 0, Max: 1
- First-appeared: 0.2.2.17-alpha
-
- "bwweightscale" -- Value that bandwidth-weights are divided by. If not
- present then this defaults to 10000.
- Min: 1
- First-appeared: 0.2.2.10-alpha
-
- "cbtdisabled", "cbtnummodes", "cbtrecentcount", "cbtmaxtimeouts",
- "cbtmincircs", "cbtquantile", "cbtclosequantile", "cbttestfreq",
- "cbtmintimeout", "cbtlearntimeout", "cbtmaxopencircs", and
- "cbtinitialtimeout" -- see "2.4.5. Consensus parameters governing
- behavior" in path-spec.txt for a series of circuit build time related
- consensus params.
-
- "UseOptimisticData" -- If set to zero, clients by default
- shouldn't try to send optimistic data to servers until they have
- received a RELAY_CONNECTED cell.
- Min: 0, Max: 1, Default: 1
- First-appeared: 0.2.3.3-alpha
- Default was 0 before: 0.2.9.1-alpha
-
- "maxunmeasuredbw" -- Used by authorities during voting with
- method 17 or later. The maximum value to give for any Bandwidth=
- entry for a router that isn't based on at least three
- measurements.
- First-appeared: 0.2.4.11-alpha
-
- "Support022HiddenServices" -- Used to implement a mass switch-over
- from sending timestamps to hidden services by default to sending
- no timestamps at all. If this option is absent, or is set to 1,
- clients with the default configuration send timestamps; otherwise,
- they do not.
- Min: 0, Max: 1. Default: 1.
- First-appeared: 0.2.4.18-rc
-
- "usecreatefast" -- Used to control whether clients use the
- CREATE_FAST handshake on the first hop of their circuits.
- Min: 0, Max: 1. Default: 1.
- First-appeared: 0.2.4.23, 0.2.5.2-alpha
-
- "pb_mincircs", "pb_noticepct", "pb_warnpct", "pb_extremepct",
- "pb_dropguards", "pb_scalecircs", "pb_scalefactor",
- "pb_multfactor", "pb_minuse", "pb_noticeusepct",
- "pb_extremeusepct", "pb_scaleuse" -- DOCDOC
-
- "UseNTorHandshake" -- If true, then versions of Tor that support
- NTor will prefer to use it by default.
- Min: 0, Max: 1. Default: 1.
- First-appeared: 0.2.4.8-alpha
-
- "FastFlagMinThreshold", "FastFlagMaxThreshold" -- lowest and
- highest allowable values for the cutoff for routers that should get
- the Fast flag. This is used during voting to prevent the threshold
- for getting the Fast flag from being too low or too high.
- FastFlagMinThreshold: Min: 4. Max: INT32_MAX: Default: 4.
- FastFlagMaxThreshold: Min: -. Max: INT32_MAX: Default: INT32_MAX
- First-appeared: 0.2.3.11-alpha
-
- "NumDirectoryGuards", "NumEntryGuards" -- Number of guard nodes
- clients should use by default. If NumDirectoryGuards is 0,
- we default to NumEntryGuards.
- NumDirectoryGuards: Min: 0. Max: 10. Default: 0
- NumEntryGuards: Min: 1. Max: 10. Default: 3
- First-appeared: 0.2.4.23, 0.2.5.6-alpha
-
- "GuardLifetime" -- Duration for which clients should choose guard
- nodes, in seconds.
- Min: 30 days. Max: 1826 days. Default: 60 days.
- First-appeared: 0.2.4.12-alpha
-
- "min_paths_for_circs_pct" -- DOCDOC
-
- "NumNTorsPerTAP" -- When balancing ntor and TAP cells at relays,
- how many ntor handshakes should we perform for each TAP handshake?
- Min: 1. Max: 100000. Default: 10.
- First-appeared: 0.2.4.17-rc
-
- "AllowNonearlyExtend" -- If true, permit EXTEND cells that are not
- inside RELAY_EARLY cells.
- Min: 0. Max: 1. Default: 0.
- First-appeared: 0.2.3.11-alpha
-
- "AuthDirNumSRVAgreements" -- Minimum number of agreeing directory
- authority votes required for a fresh shared random value to be written
- in the consensus (this rule only applies on the first commit round of
- the shared randomness protocol).
- Min: 1. Max: INT32_MAX. Default: 2/3 of the total number of
- dirauth.
-
- "max-consensuses-age-to-cache-for-diff" -- Determines how
- much consensus history (in hours) relays should try to cache
- in order to serve diffs. (min 0, max 8192, default 72)
-
- "try-diff-for-consensus-newer-than" -- This parameter
- determines how old a consensus can be (in hours) before a
- client should no longer try to find a diff for it. (min 0,
- max 8192, default 72)
-
- onion key lifetime parameters:
- "onion-key-rotation-days" -- (min 1, max 90, default 28)
- "onion-key-grace-period-days" -- (min 1, max
- onion-key-rotation-days, default 7)
- Every relay should list each onion key it generates for
- onion-key-rotation-days days after generating it, and then
- replace it. Relays should continue to accept their most recent
- previous onion key for an additional onion-key-grace-period-days
- days after it is replaced. (Introduced in 0.3.1.1-alpha;
- prior versions of tor hardcoded both of these values to 7 days.)
-
- Hidden service v3 parameters:
- "hs_intro_min_introduce2"
- "hs_intro_max_introduce2" -- Minimum/maximum amount of INTRODUCE2 cells
- allowed per circuits before rotation (actual
- amount picked at random between these two values).
- "hs_intro_min_lifetime"
- "hs_intro_max_lifetime" -- Minimum/maximum lifetime in seconds that a service
- should keep an intro point for (actual lifetime picked at
- random between these two values).
- "hs_intro_num_extra" -- Number of extra intro points a service is allowed to open.
- This concept comes from proposal #155.
- "hsdir_interval" -- The length of a time period. See rend-spec-v3.txt
- section [TIME-PERIODS].
- "hsdir_n_replicas" -- Number of HS descriptor replicas.
- "hsdir_spread_fetch" -- Total number of HSDirs per replica a tor client
- should select to try to fetch a descriptor.
- "hsdir_spread_store" -- Total number of HSDirs per replica a service
- will upload its descriptor to.
- "HSV3MaxDescriptorSize" -- Maximum descriptor size (in bytes).
-
- "hs_service_max_rdv_failures" -- This parameter determines the maximum
- number of rendezvous attempt an HS service can make per introduction.
- Min 1. Max 10. Default 2.
- First-appeared: 0.3.3.0-alpha.
-
- Denial of Service mitigation parameters. Introduced in 0.3.3.2-alpha:
-
- "DoSCircuitCreationEnabled" -- Enable the circuit creation DoS
- mitigation.
-
- "DoSCircuitCreationMinConnections" -- Minimum threshold of concurrent
- connections before a client address can be flagged as executing a
- circuit creation DoS
-
- "DoSCircuitCreationRate" -- Allowed circuit creation rate per second
- per client IP address once the minimum concurrent connection
- threshold is reached.
-
- "DoSCircuitCreationBurst" -- The allowed circuit creation burst per
- client IP address once the minimum concurrent connection threshold is
- reached.
-
- "DoSCircuitCreationDefenseType" -- Defense type applied to a detected
- client address for the circuit creation mitigation.
-
- 1: No defense.
- 2: Refuse circuit creation for the
- DoSCircuitCreationDefenseTimePeriod period.
-
- "DoSCircuitCreationDefenseTimePeriod" -- The base time period that
- the DoS defense is activated for.
-
- "DoSConnectionEnabled" -- Enable the connection DoS mitigation.
-
- "DoSConnectionMaxConcurrentCount" -- The maximum threshold of
- concurrent connection from a client IP address.
-
- "DoSConnectionDefenseType" -- Defense type applied to a detected
- client address for the connection mitigation. Possible values are:
-
- 1: No defense.
- 2: Immediately close new connections.
-
- "DoSRefuseSingleHopClientRendezvous" -- Refuse establishment of
- rendezvous points for single hop clients.
-
- "circ_max_cell_queue_size" -- This parameter determines the maximum
- number of cells allowed per circuit queue.
- Min 1000. Max 4294967295. Default 50000.
- First-appeared: 0.3.3.6-rc.
-
- "circpad_max_circ_queued_cells" -- The circuitpadding module will
- stop sending more padding cells if more than this many cells are in
- the circuit queue a given circuit. Min: 0. Max: 50000. Default 1000.
- First appeared: 0.4.0.3-alpha.
-
- "sendme_emit_min_version" -- Minimum SENDME version that can be sent.
- Min: 0. Max: 255. Default 0. First
- appeared: 0.4.1.1-alpha.
-
- "sendme_accept_min_version" -- Minimum SENDME version that is accepted.
- Min: 0. Max: 255. Default 0. First
- appeared: 0.4.1.1-alpha.
-
- "HiddenServiceEnableIntroDoSDefense" -- This parameter makes tor start
- using this new proposed extension if available by the introduction
- point (for protover HSIntro=5). Min: 0. Max: 1. Default: 0. First
- appeared: 0.4.2.1-alpha.
+ See param-spec.txt for a list of parameters and their meanings.
"shared-rand-previous-value" SP NumReveals SP Value NL
diff --git a/param-spec.txt b/param-spec.txt
new file mode 100644
index 0000000..e2b23f0
--- /dev/null
+++ b/param-spec.txt
@@ -0,0 +1,426 @@
+
+ Tor network parameters
+
+This file lists the recognized parameters that can appear on the "params"
+line of a directory consensus.
+
+1. Network protocol parameters
+
+ "circwindow" -- the default package window that circuits should be
+ established with. It started out at 1000 cells, but some research
+ indicates that a lower value would mean fewer cells in transit in the
+ network at any given time.
+ Min: 100, Max: 1000
+ First-appeared: Tor 0.2.1.20
+
+ "refuseunknownexits" -- if set to one, exit relays look at the previous
+ hop of circuits that ask to open an exit stream, and refuse to exit if
+ they don't recognize it as a relay. The goal is to make it harder for
+ people to use them as one-hop proxies. See trac entry 1751 for details.
+ Min: 0, Max: 1
+ First-appeared: 0.2.2.17-alpha
+
+ "UseOptimisticData" -- If set to zero, clients by default shouldn't try
+ to send optimistic data to servers until they have received a
+ RELAY_CONNECTED cell.
+ Min: 0, Max: 1, Default: 1
+ First-appeared: 0.2.3.3-alpha
+ Default was 0 before: 0.2.9.1-alpha
+
+ "usecreatefast" -- Used to control whether clients use the CREATE_FAST
+ handshake on the first hop of their circuits.
+ Min: 0, Max: 1. Default: 1.
+ First-appeared: 0.2.4.23, 0.2.5.2-alpha
+
+ "min_paths_for_circs_pct" -- A percentage threshold that determines
+ whether clients believe they have enough directory information to
+ build circuits. This value applies to the total fraction of
+ bandwidth-weighted paths that the client could build; see
+ path-spec.txt for more information.
+ Min: 25, Max: 95, Default: 60
+ First-appeared: 0.2.4
+
+ "AllowNonearlyExtend" -- If true, permit EXTEND cells that are not inside
+ RELAY_EARLY cells.
+ Min: 0. Max: 1. Default: 0.
+ First-appeared: 0.2.3.11-alpha
+
+ "ExtendByEd25519ID" -- If true, clients should include Ed25519
+ identities for relays when generating EXTEND2 cells.
+ Min: 0. Max: 1. Default: 0.
+ First-appeared: 0.3.0
+
+
+2. Performance-tuning parameters
+
+ "CircuitPriorityHalflifeMsec" -- the halflife parameter used when
+ weighting which circuit will send the next cell. Obeyed by Tor
+ 0.2.2.10-alpha and later. (Versions of Tor between 0.2.2.7-alpha and
+ 0.2.2.10-alpha recognized a "CircPriorityHalflifeMsec" parameter, but
+ mishandled it badly.)
+ Min: -1, Max: 2147483647 (INT32_MAX)
+ First-appeared: Tor 0.2.2.11-alpha
+
+ "perconnbwrate" and "perconnbwburst" -- if set, each relay sets up a
+ separate token bucket for every client OR connection, and rate limits
+ that connection indepedently. Typically left unset, except when used for
+ performance experiments around trac entry 1750. Only honored by relays
+ running Tor 0.2.2.16-alpha and later. (Note that relays running
+ 0.2.2.7-alpha through 0.2.2.14-alpha looked for bwconnrate and
+ bwconnburst, but then did the wrong thing with them; see bug 1830 for
+ details.)
+ Min: 1, Max: 2147483647 (INT32_MAX)
+ First-appeared: 0.2.2.7-alpha
+ Removed-in: 0.2.2.16-alpha
+
+ "NumNTorsPerTAP" -- When balancing ntor and TAP cells at relays,
+ how many ntor handshakes should we perform for each TAP handshake?
+ Min: 1. Max: 100000. Default: 10.
+ First-appeared: 0.2.4.17-rc
+
+ "circ_max_cell_queue_size" -- This parameter determines the maximum
+ number of cells allowed per circuit queue.
+ Min 1000. Max 4294967295. Default 50000.
+ First-appeared: 0.3.3.6-rc.
+
+ "sendme_emit_min_version" -- Minimum SENDME version that can be sent.
+ Min: 0. Max: 255. Default 0.
+ First appeared: 0.4.1.1-alpha.
+
+ "sendme_accept_min_version" -- Minimum SENDME version that is accepted.
+ Min: 0. Max: 255. Default 0.
+ First appeared: 0.4.1.1-alpha.
+
+ "KISTSchedRunInterval" -- How frequently should the "KIST" scheduler
+ run in order to decide which data to write to the network? Value in
+ units of milliseconds. If 0, then the KIST scheduler should be
+ disabled.
+ Min: 0. Max: 100. Default: 10.
+ First appeared: 0.3.2
+
+3. Voting-related parameters
+
+ "bwweightscale" -- Value that bandwidth-weights are divided by. If not
+ present then this defaults to 10000.
+ Min: 1
+ First-appeared: 0.2.2.10-alpha
+
+ "maxunmeasuredbw" -- Used by authorities during voting with method 17 or
+ later. The maximum value to give for any Bandwidth= entry for a router
+ that isn't based on at least three measurements.
+ First-appeared: 0.2.4.11-alpha
+
+ "FastFlagMinThreshold", "FastFlagMaxThreshold" -- lowest and highest
+ allowable values for the cutoff for routers that should get the Fast
+ flag. This is used during voting to prevent the threshold for getting
+ the Fast flag from being too low or too high.
+ FastFlagMinThreshold: Min: 4. Max: INT32_MAX: Default: 4.
+ FastFlagMaxThreshold: Min: -. Max: INT32_MAX: Default: INT32_MAX
+ First-appeared: 0.2.3.11-alpha
+
+ "AuthDirNumSRVAgreements" -- Minimum number of agreeing directory
+ authority votes required for a fresh shared random value to be written in
+ the consensus (this rule only applies on the first commit round of the
+ shared randomness protocol).
+ Min: 1. Max: INT32_MAX. Default: 2/3 of the total number of
+ dirauth.
+
+4. Circuit-build-timeout parameters
+
+ "cbtdisabled", "cbtnummodes", "cbtrecentcount", "cbtmaxtimeouts",
+ "cbtmincircs", "cbtquantile", "cbtclosequantile", "cbttestfreq",
+ "cbtmintimeout", "cbtlearntimeout", "cbtmaxopencircs", and
+ "cbtinitialtimeout" -- see "2.4.5. Consensus parameters governing
+ behavior" in path-spec.txt for a series of circuit build time related
+ consensus parameters.
+
+
+5. Directory-related parameters
+
+ "max-consensus-age-to-cache-for-diff" -- Determines how much
+ consensus history (in hours) relays should try to cache in order to
+ serve diffs. (min 0, max 8192, default 72)
+
+ "try-diff-for-consensus-newer-than" -- This parameter determines how
+ old a consensus can be (in hours) before a client should no longer
+ try to find a diff for it. (min 0, max 8192, default 72)
+
+6. Pathbias parameters
+
+ "pb_mincircs", "pb_noticepct", "pb_warnpct", "pb_extremepct",
+ "pb_dropguards", "pb_scalecircs", "pb_scalefactor",
+ "pb_multfactor", "pb_minuse", "pb_noticeusepct",
+ "pb_extremeusepct", "pb_scaleuse" -- DOCDOC
+
+7. Relay behavior
+
+ "onion-key-rotation-days" -- (min 1, max 90, default 28)
+
+ "onion-key-grace-period-days" -- (min 1, max
+ onion-key-rotation-days, default 7)
+
+ Every relay should list each onion key it generates for
+ onion-key-rotation-days days after generating it, and then
+ replace it. Relays should continue to accept their most recent
+ previous onion key for an additional onion-key-grace-period-days
+ days after it is replaced. (Introduced in 0.3.1.1-alpha;
+ prior versions of tor hardcoded both of these values to 7 days.)
+
+8. V3 onion service parameters
+
+ "hs_intro_min_introduce2", "hs_intro_max_introduce2" --
+ Minimum/maximum amount of INTRODUCE2 cells allowed per circuits
+ before rotation (actual amount picked at random between these two
+ values).
+
+ "hs_intro_min_lifetime", "hs_intro_max_lifetime" -- Minimum/maximum
+ lifetime in seconds that a service should keep an intro point for
+ (actual lifetime picked at random between these two values).
+
+ "hs_intro_num_extra" -- Number of extra intro points a service is
+ allowed to open. This concept comes from proposal #155.
+
+ "hsdir_interval" -- The length of a time period. See
+ rend-spec-v3.txt section [TIME-PERIODS].
+
+ "hsdir_n_replicas" -- Number of HS descriptor replicas.
+
+ "hsdir_spread_fetch" -- Total number of HSDirs per replica a tor
+ client should select to try to fetch a descriptor.
+
+ "hsdir_spread_store" -- Total number of HSDirs per replica a service
+ will upload its descriptor to.
+
+ "HSV3MaxDescriptorSize" -- Maximum descriptor size (in bytes).
+
+ "hs_service_max_rdv_failures" -- This parameter determines the
+ maximum number of rendezvous attempt an HS service can make per
+ introduction.
+ Min 1. Max 10. Default 2.
+ First-appeared: 0.3.3.0-alpha.
+
+ "HiddenServiceEnableIntroDoSDefense" -- This parameter makes tor
+ start using this defense if the introduction point supports it
+ (for protover HSIntro=5).
+ Min: 0. Max: 1. Default: 0.
+ First appeared: 0.4.2.1-alpha.
+
+ "HiddenServiceEnableIntroDoSBurstPerSec" -- Maximum burst to be used
+ for token bucket for the introduction point rate-limiting.
+ Min: 0. Max: INT32_MAX. Default: 200
+ First appeared: 0.4.2.1-alpha.
+
+ "HiddenServiceEnableIntroDoSRatePerSec" -- Refill rate to be used
+ for token bucket for the introduction point rate-limiting.
+ Min: 0. Max: INT32_MAX. Default: 25
+ First appeared: 0.4.2.1-alpha.
+
+9. Denial-of-service parameters
+
+ Denial of Service mitigation parameters. Introduced in 0.3.3.2-alpha:
+
+ "DoSCircuitCreationEnabled" -- Enable the circuit creation DoS
+ mitigation.
+
+ "DoSCircuitCreationMinConnections" -- Minimum threshold of
+ concurrent connections before a client address can be flagged as
+ executing a circuit creation DoS
+
+ "DoSCircuitCreationRate" -- Allowed circuit creation rate per second
+ per client IP address once the minimum concurrent connection
+ threshold is reached.
+
+ "DoSCircuitCreationBurst" -- The allowed circuit creation burst per
+ client IP address once the minimum concurrent connection threshold
+ is reached.
+
+ "DoSCircuitCreationDefenseType" -- Defense type applied to a
+ detected client address for the circuit creation mitigation.
+ 1: No defense.
+ 2: Refuse circuit creation for the length of
+ "DoSCircuitCreationDefenseTimePeriod".
+
+
+ "DoSCircuitCreationDefenseTimePeriod" -- The base time period that
+ the DoS defense is activated for.
+
+ "DoSConnectionEnabled" -- Enable the connection DoS mitigation.
+
+ "DoSConnectionMaxConcurrentCount" -- The maximum threshold of
+ concurrent connection from a client IP address.
+
+ "DoSConnectionDefenseType" -- Defense type applied to a detected
+ client address for the connection mitigation. Possible values are:
+ 1: No defense.
+ 2: Immediately close new connections.
+
+ "DoSRefuseSingleHopClientRendezvous" -- Refuse establishment of
+ rendezvous points for single hop clients.
+
+10. Padding-related parameters
+
+ "circpad_max_circ_queued_cells" -- The circuitpadding module will
+ stop sending more padding cells if more than this many cells are in
+ the circuit queue a given circuit.
+ Min: 0. Max: 50000. Default 1000.
+ First appeared: 0.4.0.3-alpha.
+
+ "circpad_global_allowed_cells" -- DOCDOC
+
+ "circpad_global_max_padding_pct" -- DOCDOC
+
+ "circpad_padding_disabled" -- DOCDOC
+
+ "circpad_padding_reduced" -- DOCDOC
+
+ "nf_conntimeout_clients" -- DOCDOC
+
+ "nf_conntimeout_relays" -- DOCDOC
+
+ "nf_ito_high_reduced" -- DOCDOC
+
+ "nf_ito_low" -- DOCDOC
+
+ "nf_ito_low_reduced" -- DOCDOC
+
+ "nf_pad_before_usage" -- DOCDOC
+
+ "nf_pad_relays" -- DOCDOC
+
+ "nf_pad_single_onion" -- DOCDOC
+
+11. Guard-related parameters
+
+ (See guard-spec.txt for more information on the vocabulary used here.)
+
+ "UseGuardFraction" -- If true, clients use `GuardFraction`
+ information from the consensus in order to decide how to weight
+ guards when picking them.
+ Min: 0. Max: 1. Default: 0.
+ First appeared: 0.2.6
+
+ "guard-lifetime-days" -- Controls guard lifetime. If a unconfirmed
+ guard has been sampled more than this many days ago, it should be
+ removed from the guard sample.
+ Min: 1. Max: 3650. Default: 120.
+ First appeared: 0.3.0
+
+ "guard-confirmed-min-lifetime-days" -- Controls confirmed guard
+ lifetime: if a guard was confirmed more than this many days ago, it
+ should be removed from the guard sample.
+ Min: 1. Max: 3650. Default: 60.
+ First appeared: 0.3.0
+
+ "guard-internet-likely-down-interval" -- If Tor has been unable to
+ build a circuit for this long (in seconds), assume that the internet
+ connection is down, and treat guard failures as unproven.
+ Min: 1. Max: INT32_MAX. Default: 600.
+ First appeared: 0.3.0
+
+ "guard-max-sample-size" -- Largest number of guards that clients
+ should try to collect in their sample.
+ Min: 1. Max: INT32_MAX. Default: 60.
+ First appeared: 0.3.0
+
+ "guard-max-sample-threshold-percent" -- Largest bandwidth-weighted
+ fraction of guards that clients should try to collect in their
+ sample.
+ Min: 1. Max: 100. Default: 20.
+ First appeared: 0.3.0
+
+ "guard-meaningful-restriction-percent" -- If the client has
+ configured tor to exclude so many guards that the available guard
+ bandwidth is less than this percentage of the total, treat the guard
+ sample as "restricted", and keep it in a separate sample.
+ Min: 1. Max: 100. Default: 20.
+ First appeared: 0.3.0
+
+ "guard-extreme-restriction-percent" -- Warn the user if they have
+ configured tor to exclude so many guards that the available guard
+ bandwidth is less than this percentage of the total.
+ Min: 1. Max: INT32_MAX. Default: 1.
+ First appeared: 0.3.0
+
+ "guard-min-filtered-sample-size" -- If fewer than this number of
+ guards is available in the sample after filtering out unusable
+ guards, the client should try to add more guards to the sample (if
+ allowed).
+ Min: 1. Max: INT32_MAX. Default: 20.
+ First appeared: 0.3.0
+
+ "guard-n-primary-guards" -- The number of confirmed guards that the
+ client should treat as "primary guards".
+ Min: 1. Max: INT32_MAX. Default: 3.
+ First appeared: 0.3.0
+
+ "guard-n-primary-guards-to-use", "guard-n-primary-dir-guards-to-use"
+ -- number of primary guards and primary directory guards that the
+ client should be willing to use in parallel. Other primary guards
+ won't get used unless the earlier ones are down.
+ "guard-n-primary-guards-to-use":
+ Min 1, Max INT32_MAX: Default: 1.
+ "guard-n-primary-dir-guards-to-use"
+ Min 1, Max INT32_MAX: Default: 3.
+ First appeared: 0.3.0
+
+ "guard-nonprimary-guard-connect-timeout" -- When trying to confirm
+ nonprimary guards, if a guard doesn't answer for more than this long
+ in seconds, treat lower-priority guards as usable.
+ Min: 1. Max: INT32_MAX. Default: 15
+ First appeared: 0.3.0
+
+ "guard-nonprimary-guard-idle-timeout" -- When trying to confirm
+ nonprimary guards, if a guard doesn't answer for more than this long
+ in seconds, treat it as down.
+ Min: 1. Max: INT32_MAX. Default: 600
+ First appeared: 0.3.0
+
+ "guard-remove-unlisted-guards-after-days" -- If a guard has been
+ unlisted in the consensus for at least this many days, remove it
+ from the sample.
+ Min: 1. Max: 3650. Default: 20.
+ First appeared: 0.3.0
+
+12. Relay behavior
+
+ "assume-reachable" -- If true, relays should publish descriptors
+ even when they cannot make a connection to their IPv4 ORPort.
+ Min: 0. Max: 1. Default: 0.
+ First appeared: 0.4.5.1-alpha.
+
+ "assume-reachable-ipv6" -- If true, relays should publish
+ descriptors even when they cannot make a connection to their IPv6
+ ORPort.
+ Min: 0. Max: 1. Default: 0.
+ First appeared: 0.4.5.1-alpha.
+
+X. Obsolete parameters
+
+ "NumDirectoryGuards", "NumEntryGuards" -- Number of guard nodes
+ clients should use by default. If NumDirectoryGuards is 0, we
+ default to NumEntryGuards.
+ NumDirectoryGuards: Min: 0. Max: 10. Default: 0
+ NumEntryGuards: Min: 1. Max: 10. Default: 3
+ First-appeared: 0.2.4.23, 0.2.5.6-alpha
+ Removed in: 0.3.0
+
+ "GuardLifetime" -- Duration for which clients should choose guard
+ nodes, in seconds.
+ Min: 30 days. Max: 1826 days. Default: 60 days.
+ First-appeared: 0.2.4.12-alpha
+ Removed in: 0.3.0.
+
+ "UseNTorHandshake" -- If true, then versions of Tor that support
+ NTor will prefer to use it by default.
+ Min: 0, Max: 1. Default: 1.
+ First-appeared: 0.2.4.8-alpha
+ Removed in: 0.2.9.
+
+ "Support022HiddenServices" -- Used to implement a mass switch-over
+ from sending timestamps to hidden services by default to sending no
+ timestamps at all. If this option is absent, or is set to 1,
+ clients with the default configuration send timestamps; otherwise,
+ they do not.
+ Min: 0, Max: 1. Default: 1.
+ First-appeared: 0.2.4.18-rc
+ Removed in: 0.2.6
diff --git a/proposals/000-index.txt b/proposals/000-index.txt
index 4bbd8d3..b6658ff 100644
--- a/proposals/000-index.txt
+++ b/proposals/000-index.txt
@@ -246,6 +246,8 @@ Proposals by number:
323 Specification for Walking Onions [OPEN]
324 RTT-based Congestion Control for Tor [OPEN]
325 Packed relay cells: saving space on small commands [OPEN]
+326 The "tor-relay" Well-Known Resource Identifier [OPEN]
+327 A First Take at PoW Over Introduction Circuits [DRAFT]
Proposals by status:
@@ -254,6 +256,7 @@ Proposals by status:
273 Exit relay pinning for web services [for n/a]
294 TLS 1.3 Migration
316 FlashFlow: A Secure Speed Test for Tor (Parent Proposal)
+ 327 A First Take at PoW Over Introduction Circuits
NEEDS-REVISION:
212 Increase Acceptable Consensus Age [for 0.2.4.x+]
219 Support for full DNS and DNSSEC resolution in Tor [for 0.2.5.x]
@@ -282,6 +285,7 @@ Proposals by status:
323 Specification for Walking Onions
324 RTT-based Congestion Control for Tor
325 Packed relay cells: saving space on small commands
+ 326 The "tor-relay" Well-Known Resource Identifier
ACCEPTED:
265 Load Balancing with Overhead Parameters [for 0.2.9.x]
275 Stop including meaningful "published" time in microdescriptor consensus [for 0.3.1.x-alpha]
diff --git a/proposals/316-flashflow.txt b/proposals/316-flashflow.md
index 733bec2..8258d76 100644
--- a/proposals/316-flashflow.txt
+++ b/proposals/316-flashflow.md
@@ -1,33 +1,35 @@
-Filename: 316-flashflow.txt
+```
+Filename: 316-flashflow.md
Title: FlashFlow: A Secure Speed Test for Tor (Parent Proposal)
Author: Matthew Traudt, Aaron Johnson, Rob Jansen, Mike Perry
Created: 23 April 2020
Status: Draft
+```
-1. Introduction
+# 1. Introduction
FlashFlow is a new distributed bandwidth measurement system for Tor that
consists of a single authority node ("coordinator") instructing one or
more measurement nodes ("measurers") when and how to measure Tor relays.
A measurement consists of the following steps:
- 1. The measurement nodes demonstrate to the target relay permission to
- perform measurements.
- 2. The measurement nodes open many TCP connections to the target relay
- and create a one-hop circuit to the target relay on each one.
- 3. For 30 seconds the measurement nodes send measurement cells to the
- target relay and verify that the cells echoed back match the ones
- sent. During this time the relay caps the amount of background
- traffic it transfers. Background and measurement traffic are
- handled separately at the relay. Measurement traffic counts towards
- all the standard existing relay statistics.
- 4. For every second during the measurement, the measurement nodes
- report to the authority node how much traffic was echoed back. The
- target relay also reports the amount of per-second background
- (non-measurement) traffic.
- 5. The authority node sums the per-second reported throughputs into 30
- sums (one for each second) and calculates the median. This is the
- estimated capacity of the relay.
+1. The measurement nodes demonstrate to the target relay permission to
+ perform measurements.
+2. The measurement nodes open many TCP connections to the target relay
+ and create a one-hop circuit to the target relay on each one.
+3. For 30 seconds the measurement nodes send measurement cells to the
+ target relay and verify that the cells echoed back match the ones
+ sent. During this time the relay caps the amount of background
+ traffic it transfers. Background and measurement traffic are
+ handled separately at the relay. Measurement traffic counts towards
+ all the standard existing relay statistics.
+4. For every second during the measurement, the measurement nodes
+ report to the authority node how much traffic was echoed back. The
+ target relay also reports the amount of per-second background
+ (non-measurement) traffic.
+5. The authority node sums the per-second reported throughputs into 30
+ sums (one for each second) and calculates the median. This is the
+ estimated capacity of the relay.
FlashFlow performs a measurement of every relay according to a schedule
described later in this document. Periodically it produces relay
@@ -40,8 +42,9 @@ It is envisioned that each directory authority that wants to use
FlashFlow will run their own FlashFlow deployment consisting of a
coordinator that they run and one or more measurers that they trust
(e.g. because they run them themselves), similar to how each runs their
-own Torflow/sbws. Section 5.2 of this proposal describes long term plans
-involving multiple FlashFlow deployments.
+own Torflow/sbws. Section 5 of this proposal describes long term plans
+involving multiple FlashFlow deployments. *FlashFlow coordinators do not need
+to communicate with each other*.
FlashFlow is more performant than Torflow: FlashFlow takes 5 hours to
measure the entire existing Tor network from scratch (with 3 Gbit/s
@@ -59,7 +62,7 @@ After an overview in section 2 of the planned deployment stages, section
3, 4, and 5 discuss the short, medium, and long term deployment plans in
more detail.
-2. Deployment Stages
+# 2. Deployment Stages
FlashFlow's deployment shall be broken up into three stages.
@@ -82,7 +85,7 @@ relay capacity than observed bandwidth. Authentication and other
FlashFlow features necessary to make it completely ready for full
production deployment will be worked on during this long term phase.
-3. FlashFlow measurement system: Short term
+# 3. FlashFlow measurement system: Short term
The core measurement mechanics will be implemented in little-t tor, but
a separate codebase for the FlashFlow side of the measurement system
@@ -93,20 +96,20 @@ separate FlashFlow code that also requires some amount of tor changes
(essentially: measurer-side and coordinator-side modifications), and
third a security discussion.
-3.1 Little-T Tor Components
+## 3.1 Little-T Tor Components
The primary additions/changes that entirely reside within tor on the
relay side:
- - New torrc options/consensus parameters.
- - New cell commands.
- - Pre-measurement handshaking (with a simplified authentication
- scheme).
- - Measurement mode, during which the relay will echo traffic with
- measurers, set a cap on the amount of background traffic it
- transfers, and report the amount of transferred background traffic.
+- New torrc options/consensus parameters.
+- New cell commands.
+- Pre-measurement handshaking (with a simplified authentication
+ scheme).
+- Measurement mode, during which the relay will echo traffic with
+ measurers, set a cap on the amount of background traffic it
+ transfers, and report the amount of transferred background traffic.
-3.1.1 Parameters
+### 3.1.1 Parameters
FlashFlow will require some consensus parameters/torrc options. Each has
some default value if nothing is specified; the consensus parameter
@@ -151,153 +154,158 @@ time, thus it necessarily is larger than the expected actual measurement
duration. Possible values are in the range [10, 120] inclusive.
Default: 45.
-3.1.2 New Cell Types
+### 3.1.2 New Cell Types
-FlashFlow will introduce a new cell command MEASURE.
+FlashFlow will introduce a new cell command MEASUREMENT.
-The payload of each MEASURE cell consists of:
+The payload of each MEASUREMENT cell consists of:
- Measure command [1 byte]
- Length [2 bytes]
- Data [Length-3 bytes]
+```
+Measure command [1 byte]
+Data [varied]
+```
The measure commands are:
- 0 -- MSM_PARAMS [forward]
- 1 -- MSM_PARAMS_OK [backward]
- 2 -- MSM_ECHO [forward and backward]
- 3 -- MSM_BG [backward]
- 4 -- MSM_ERR [forward and backward]
+```
+0 -- MEAS_PARAMS [forward]
+1 -- MEAS_PARAMS_OK [backward]
+2 -- MEAS_BG [backward]
+3 -- MEAS_ERR [forward and backward]
+```
Forward cells are sent from the measurer/coordinator to the relay.
Backward cells are sent from the relay to the measurer/coordinator.
-MSM_PARAMS and MSM_PARAMS_OK are used during the pre-measurement stage
+MEAS_PARAMS and MEAS_PARAMS_OK are used during the pre-measurement stage
to tell the target what to expect and for the relay to positively
-acknowledge the message. MSM_ECHO cells are the measurement traffic;
-the measurer generates them, sends them to the target, and the target
-echos them back. The target send a MSM_BG cell once per second to report
-the amount of background traffic it is handling. MSM_ERR cells are used
+acknowledge the message.
+The target send a MEAS_BG cell once per second to report
+the amount of background traffic it is handling. MEAS_ERR cells are used
to signal to the other party that there has been some sort of problem
and that the measurement should be aborted. These measure commands are
described in more detail in the next section.
-The only cell that sometimes undergoes cell encryption is MSM_ECHO; no
-other cell ever gets cell encrypted. (All cells are transmitted on a
-regular TLS-wrapped OR connection; that encryption still exists.)
-
-The relay "decrypts" MSM_ECHO cells before sending them back to the
-measurer; this mirrors the way relays decrypt/encrypt RELAY_DATA cells
-in order to induce realistic cryptographic CPU load. The measurer
-usually skips encrypting MSM_ECHO cells to reduce its own CPU load;
-however, to verify the relay is actually correctly decrypting all cells,
-the measurer will choose random outgoing cells, encrypt them, remember
-the ciphertext, and verify the corresponding incoming cell matches.
-
-3.1.3 Pre-Measurement Handshaking/Starting a Measurement
-
-The coordinator connects to the target relay and sends it a MSM_PARAMS
-cell. If the target is unwilling to be measured at this time or if the
-coordinator didn't use a TLS certificate that the target trusts, it
-responds with an error cell and closes the connection. Otherwise it
-checks that the parameters of the measurement are acceptable (e.g. the
-version is acceptable, the duration isn't too long, etc.). If the
-target is happy, it sends a MSM_PARAMS_OK, otherwise it sends a MSM_ERR
-and closes the connection.
+FlashFlow also introduces a new relay command, MEAS_ECHO. Relay celsl with
+this relay command are the measurement traffic. The measurer generates and
+encrypts them, sends them to the target, the target decrypts them, then it
+sends them back. A variation where the measurer skips encryption of MEAS_ECHO
+cells in most cases is described in Appendix A, and was found to be necessary
+in paper prototypes to save CPU load at the measurer.
+
+MEASUREMENT cells, on the other hand, are not encrypted (beyond the regular
+TLS on the connection).
+
+### 3.1.3 Pre-Measurement Handshaking/Starting a Measurement
+
+The coordinator establishes a one-hop circuit with the target relay and sends
+it a MEAS_PARAMS cell. If the target is unwilling to be measured at this time
+or if the coordinator didn't use a TLS certificate that the target trusts, it
+responds with an error cell and closes the connection. Otherwise it checks
+that the parameters of the measurement are acceptable (e.g. the version is
+acceptable, the duration isn't too long, etc.). If the target is happy, it
+sends a MEAS_PARAMS_OK, otherwise it sends a MEAS_ERR and closes the
+connection.
Upon learning the IP addresses of the measurers from the coordinator in
-the MSM_PARAMS cell, the target whitelists their IPs in its DoS
+the MEAS_PARAMS cell, the target whitelists their IPs in its DoS
detection subsystem until the measurement ends (successfully or
otherwise), at which point the whitelist is cleared.
-Upon receiving a MSM_PARAMS_OK from the target, the coordinator will
-instruct the measurers to open their TCP connections with the target. If
-the coordinator or any measurer receives a MSM_ERR, it reports the error
-to the coordinator and considers the measurement a failure. It is also a
-failure if any measurer is unable to open at least half of its TCP
-connections with the target.
+Upon receiving a MEAS_PARAMS_OK from the target, the coordinator will instruct
+the measurers to open their circuits (one circuit per connection) with the
+target. If the coordinator or any measurer receives a MEAS_ERR, it reports the
+error to the coordinator and considers the measurement a failure. It is also a
+failure if any measurer is unable to open at least half of its circuits with
+the target.
-The payload of MSM_PARAMS cells [XXX more may need to be added]:
+The payload of MEAS_PARAMS cells [XXX more may need to be added]:
- - version [1 byte]
- - msm_duration [1 byte]
- - num_measurers [1 byte]
- - measurer_info [num_measurers times]
- - ipv4_addr [4 bytes]
- - num_conns [2 bytes]
+```
+- meas_duration [2 bytes] [1, 600]
+- num_measurers [1 byte] [1, 10]
+- measurer_info [num_measurers times]
+```
-version dictates how this MSM_PARAMS cell shall be parsed. msm_duration
-is the duration, in seconds, that the actual measurement will last.
-num_measurers is how many measurer_info structs follow. For each
-measurer, the ipv4_addr it will use when connecting to the target is
-provided, as is num_conns, the number of TCP connections that measurer
-will open with the target. Future versions of FlashFlow and MSM_PARAMS
-will use TLS certificates instead of IP addresses.
+meas_duration is the duration, in seconds, that the actual measurement will
+last. num_measurers is how many link_specifier structs follow containing
+information on the measurers that the relay should expect. Future versions of
+FlashFlow and MEAS_PARAMS will use TLS certificates instead of IP addresses.
+[XXX probably need diff layout to allow upgrade to TLS certs instead of
+link_specifier structs. probably using ext-type-length-value like teor
+suggests]
+[XXX want to specify number of conns to expect from each measurer here?]
-MSM_PARAMS_OK has no payload: it's just padding bytes to make the cell
-514 bytes long.
+MEAS_PARAMS_OK has no payload: it's just padding bytes to make the cell
+PAYLOAD_LEN (509) bytes long.
-The payload of MSM_ECHO cells:
+The payload of MEAS_ECHO cells:
- - arbitrary bytes [max to fill up 514 byte cell]
+```
+- arbitrary bytes [PAYLOAD_LEN bytes]
+```
-The payload of MSM_BG cells:
+The payload of MEAS_BG cells [XXX more for extra info? like CPU usage]:
- - second [1 byte]
- - sent_bg_bytes [4 bytes]
- - recv_bg_bytes [4 bytes]
+```
+- second [2 byte] [1, 600]
+- sent_bg_bytes [4 bytes] [0, 2^32-1]
+- recv_bg_bytes [4 bytes] [0, 2^32-1]
+```
-second is the number of seconds since the measurement began. MSM_BG
+second is the number of seconds since the measurement began. MEAS_BG
cells are sent once per second from the relay to the FlashFlow
coordinator. The first cell will have this set to 1, and each
subsequent cell will increment it by one. sent_bg_bytes is the number of
-background traffic bytes sent in the last second (since the last MSM_BG
+background traffic bytes sent in the last second (since the last MEAS_BG
cell). recv_bg_bytes is the same but for received bytes.
-The payload of MSM_ERR cells:
+The payload of MEAS_ERR cells [XXX need field for more info]:
- - err_code [1 byte]
- - err_str [possibly zero-len null-terminated string]
+```
+- err_code [1 byte] [0, 255]
+```
The error code is one of:
- [... XXX TODO ...]
- 255 -- OTHER
+```
+[... XXX TODO ...]
+255 -- OTHER
+```
-The error string is optional in all cases. It isn't present if the first
-byte of err_str is null, otherwise it is present. It ends at the first
-null byte or the end of the cell, whichever comes first.
-
-3.1.4 Measurement Mode
+### 3.1.4 Measurement Mode
The relay considers the measurement to have started the moment it
-receives the first MSM_ECHO cell from any measurer. At this point, the
+receives the first MEAS_ECHO cell from any measurer. At this point, the
relay
- - Starts a repeating 1s timer on which it will report the amount of
- background traffic to the coordinator over the coordinator's
- connection.
- - Enters "measurement mode" and limits the amount of background
- traffic it handles according to the torrc option/consensus
- parameter.
+- Starts a repeating 1s timer on which it will report the amount of
+ background traffic to the coordinator over the coordinator's
+ connection.
+- Enters "measurement mode" and limits the amount of background
+ traffic it handles according to the torrc option/consensus
+ parameter.
-The relay decrypts and echos back all MSM_ECHO cells it receives on
+The relay decrypts and echos back all MEAS_ECHO cells it receives on
measurement connections until it has reported its amount of background
traffic the same number of times as there are seconds in the measurement
(e.g. 30 per-second reports for a 30 second measurement). After sending
-the last MSM_BG cell, the relay drops all buffered MSM_ECHO cells,
+the last MEAS_BG cell, the relay drops all buffered MEAS_ECHO cells,
closes all measurement connections, and exits measurement mode.
During the measurement the relay targets a ratio of background traffic
to measurement traffic as specified by a consensus parameter/torrc
option. For a given ratio r, if the relay has handled x cells of
measurement traffic recently, Tor then limits itself to y = xr/(1-r)
-cells of non-measurement traffic this scheduling round. The target will
-enforce that a minimum of 10 Mbit/s of measurement traffic is recorded
-since the last background traffic scheduling round to ensure it always
-allows some minimum amount of background traffic.
+cells of non-measurement traffic this scheduling round.
+If x is very small, the relay will perform the calculation s.t. x is the
+number of cells required to produce 10 Mbit/s of measurement traffic, thus
+ensuring some minimum amount of background traffic is allowed.
+
+[XXX teor suggests in [4] that the number 10 Mbit/s could be derived more
+intelligently. E.g. based on AuthDirFastGuarantee or AuthDirGuardBWGuarantee]
-3.2 FlashFlow Components
+## 3.2 FlashFlow Components
The FF coordinator and measurer code will reside in a FlashFlow
repository separate from little-t tor.
@@ -305,19 +313,19 @@ repository separate from little-t tor.
There are three notable parameters for which a FF deployment must choose
values. They are:
- - The number of sockets, s, the measurers should open, in aggregate,
- with the target relay. We suggest s=160 based on the FF paper.
- - The bandwidth multiplier, m. Given an existing capacity estimate for
- a relay, z, the coordinator will instruct the measurers to, in
- aggregate, send m*z Mbit/s to the target relay. We recommend m=2.25.
- - The measurement duration, d. Based on the FF paper, we recommend
- d=30 seconds.
+- The number of sockets, s, the measurers should open, in aggregate,
+ with the target relay. We suggest s=160 based on the FF paper.
+- The bandwidth multiplier, m. Given an existing capacity estimate for
+ a relay, z, the coordinator will instruct the measurers to, in
+ aggregate, send m*z Mbit/s to the target relay. We recommend m=2.25.
+- The measurement duration, d. Based on the FF paper, we recommend
+ d=30 seconds.
The rest of this section first discusses notable functions of the
FlashFlow coordinator, then goes on to discuss FF measurer code that
will require supporting tor code.
-3.2.1 FlashFlow Coordinator
+### 3.2.1 FlashFlow Coordinator
The coordinator is responsible for scheduling measurements, aggregating
results, and producing v3bw files. It needs continuous access to new
@@ -327,15 +335,15 @@ process in client mode.
The coordinator has the following functions, which will be described in
this section:
- - result aggregation.
- - schedule measurements.
- - v3bw file generation.
+- result aggregation.
+- schedule measurements.
+- v3bw file generation.
-3.2.1.1 Aggregating Results
+#### 3.2.1.1 Aggregating Results
Every second during a measurement, the measurers send the amount of
verified measurement traffic they have received back from the relay.
-Additionally, the relay sends a MSM_BG cell each second to the
+Additionally, the relay sends a MEAS_BG cell each second to the
coordinator with amount of non-measurement background traffic it is
sending and receiving.
@@ -353,7 +361,7 @@ measurement (e.g. 30 times for a 30 second measurement), the coordinator
takes the median of the 30 per-second throughputs and records it as the
estimated capacity of the target relay.
-3.2.1.2 Measurement Schedule
+#### 3.2.1.2 Measurement Schedule
The short term implementation of measurement scheduling will be simpler
than the long term one due to (1) there only being one FlashFlow
@@ -383,7 +391,7 @@ percentile capacity of the current network.
If a relay is not online when it's scheduled to be measured, it doesn't
get measured that day.
-3.2.1.2.1 Example
+##### 3.2.1.2.1 Example
Assume the FF deployment has 1 Gbit/s of measurer capacity. Assume the
chosen multiplier m=2. Assume there are only 5 slots in a measurement
@@ -392,21 +400,23 @@ period.
Consider a set of relays with the following existing capacity estimates
and that have opted in to being measured by FlashFlow.
- - 500 Mbit/s
- - 300 Mbit/s
- - 250 Mbit/s
- - 200 Mbit/s
- - 100 Mbit/s
- - 50 Mbit/s
+- 500 Mbit/s
+- 300 Mbit/s
+- 250 Mbit/s
+- 200 Mbit/s
+- 100 Mbit/s
+- 50 Mbit/s
The coordinator takes the largest relay, 500 Mbit/s, and picks a random
slot for it. It picks slot 3. The coordinator takes the next largest,
300, and randomly picks slot 2. The slots are now:
- 0 | 1 | 2 | 3 | 4
- -------|-------|-------|-------|-------
- | | 300 | 500 |
- | | | |
+```
+ 0 | 1 | 2 | 3 | 4
+-------|-------|-------|-------|-------
+ | | 300 | 500 |
+ | | | |
+```
The coordinator takes the next largest, 250, and randomly picks slot 2.
Slot 2 already has 600 Mbit/s of measurer capacity reserved (300*m);
@@ -415,29 +425,35 @@ Mbit/s of spare capacity while this relay requires 500 Mbit/s. There is
not enough room in slot 2 for this relay. The coordinator picks a new
random slot, 0.
- 0 | 1 | 2 | 3 | 4
- -------|-------|-------|-------|-------
- 250 | | 300 | 500 |
- | | | |
+```
+ 0 | 1 | 2 | 3 | 4
+-------|-------|-------|-------|-------
+ 250 | | 300 | 500 |
+ | | | |
+```
The next largest is 200 and the coordinator randomly picks slot 2 again
(wow!). As there is just enough spare capacity, the coordinator assigns
this relay to slot 2.
- 0 | 1 | 2 | 3 | 4
- -------|-------|-------|-------|-------
- 250 | | 300 | 500 |
- | | 200 | |
+```
+ 0 | 1 | 2 | 3 | 4
+-------|-------|-------|-------|-------
+ 250 | | 300 | 500 |
+ | | 200 | |
+```
The coordinator randomly picks slot 4 for the last remaining relays, in
that order.
- 0 | 1 | 2 | 3 | 4
- -------|-------|-------|-------|-------
- 250 | | 300 | 500 | 100
- | | 200 | | 50
+```
+ 0 | 1 | 2 | 3 | 4
+-------|-------|-------|-------|-------
+ 250 | | 300 | 500 | 100
+ | | 200 | | 50
+```
-3.2.1.3 Generating V3BW files
+#### 3.2.1.3 Generating V3BW files
Every hour the FF coordinator produces a v3bw file in which it stores
the latest capacity estimate for every relay it has measured in the last
@@ -446,35 +462,35 @@ system. Previously-generated v3bw files will not be deleted by the
coordinator. A symbolic link at a static path will always point to the
latest v3bw file.
- $ ls -l
- v3bw -> v3bw.2020-03-01-05-00-00
- v3bw.2020-03-01-00-00-00
- v3bw.2020-03-01-01-00-00
- v3bw.2020-03-01-02-00-00
- v3bw.2020-03-01-03-00-00
- v3bw.2020-03-01-04-00-00
- v3bw.2020-03-01-05-00-00
+```
+$ ls -l
+v3bw -> v3bw.2020-03-01-05-00-00
+v3bw.2020-03-01-00-00-00
+v3bw.2020-03-01-01-00-00
+v3bw.2020-03-01-02-00-00
+v3bw.2020-03-01-03-00-00
+v3bw.2020-03-01-04-00-00
+v3bw.2020-03-01-05-00-00
+```
+
+[XXX Either FF should auto-delete old ones, logrotate config should be
+provided, a script provided, or something to help bwauths not accidentally
+fill up their disk]
-3.2.2 FlashFlow Measurer
+[XXX What's the approxmiate disk usage for, say, a few years of these?]
+
+### 3.2.2 FlashFlow Measurer
The measurers take commands from the coordinator, connect to target
relays with many sockets, send them traffic, and verify the received
-traffic is the same as what was sent. Measurers need access to a lot of
-internal tor functionality. One strategy is to house as much logic as
-possible inside an compile-time-optional control port module that calls
-into other parts of tor. Alternatively FlashFlow could link against tor
-and call internal tor functions directly.
-
-[XXX for now I'll assume that an optional little-t tor control port
-module housing a lot of this code is the best idea.]
+traffic is the same as what was sent.
Notable new things that internal tor code will need to do on the
measurer (client) side:
- 1. Open many TLS+TCP connections to the same relay on purpose.
- 2. Verify echo cells.
+1. Open many TLS+TCP connections to the same relay on purpose.
-3.2.2.1 Open many connections
+#### 3.2.2.1 Open many connections
FlashFlow prototypes needed to "hack in" a flag in the
open-a-connection-with-this-relay function call chain that indicated
@@ -486,118 +502,12 @@ accomplish this will be investigated.
On the relay side, these measurer connections do not count towards DoS
detection algorithms.
-3.2.2.2 Verify echo cells
-
-A parameter will exist to tell the measurers with what frequency they
-shall verify that cells echoed back to them match what was sent. This
-parameter does not need to exist outside of the FF deployment (e.g. it
-doesn't need to be a consensus parameter).
-
-The parameter instructs the measurers to check 1 out of every N cells.
-
-The measurer keeps a count of how many measurement cells it has sent. It
-also logically splits its output stream of cells into buckets of size N.
-At the start of each bucket (when num_sent % N == 0), the measurer
-chooses a random index in the bucket. Upon sending the cell at that
-index (num_sent % N == chosen_index), the measurer records the cell.
-
-The measurer also counts cells that it receives. When it receives a cell
-at an index that was recorded, it verifies that the received cell
-matches the recorded sent cell. If they match, no special action is
-taken. If they don't match, the measurer indicates failure to the
-coordinator and target relay and closes all connections, ending the
-measurement.
-
-3.2.2.2.1 Example
-
-Consider bucket_size is 1000. For the moment ignore cell encryption.
-
-We start at idx=0 and pick an idx in [0, 1000) to record, say 640. At
-idx=640 we record the cell. At idx=1000 we choose a new idx in [1000,
-2000) to record, say 1236. At idx=1236 we record the cell. At idx=2000
-we choose a new idx in [2000, 3000). Etc.
-
-There's 2000+ cells in flight and the measurer has recorded two items:
-
- - (640, contents_of_cellA)
- - (1236, contents_of_cellB)
-
-Consider the receive side now. It counts the cells it receives. At
-receive idx=640, it checks the received cell matches the saved cell from
-before. At receive idx=1236, it again checks the received cell matches.
-Etc.
-
-3.2.2.2.2 Motivation
-
-A malicious relay may want to skip decryption of measurement cells to
-save CPU cycles and obtain a higher capacity estimate. More generally,
-it could generate fake measurement cells locally, ignore the measurement
-traffic it is receiving, and flood the measurer with more traffic that
-it (the measurer) is even sending.
-
-The security of echo cell verification is discussed in section 3.3.1.
-
-3.3 Security
+## 3.3 Security
In this section we discuss the security of various aspects of FlashFlow
and the tor changes it requires.
-3.3.1 Echo Cell Verification: Bucket Size
-
-A smaller bucket size means more cells are checked and FF is more likely
-to detect a malicious target. It also means more bookkeeping overhead
-(CPU/RAM).
-
-An adversary that knows bucket_size and cheats on one item out of every
-bucket_size items will have a 1/bucket_size chance of getting caught in
-the first bucket. This is the worst case adversary. While cheating on
-just a single item per bucket yields very little advantage, cheating on
-more items per bucket increases the likelihood the adversary gets
-caught. Thus only the worst case is considered here.
-
-In general, the odds the adversary can successfully cheat in a single
-bucket are
-
- (bucket_size-1)/bucket_size
-
-Thus the odds the adversary can cheat in X consecutive buckets are
-
- [(bucket_size-1)/bucket_size]^X
-
-In our case, X will be highly varied: Slow relays won't see very many
-buckets, but fast relays will. The damage to the network a very slow
-relay can do by faking being only slightly faster is limited.
-Nonetheless, for now we motivate the selection of bucket_size with a
-slow relay:
-
- - Assume a very slow relay of 1 Mbit/s capacity that will cheat 1 cell
- in each bucket. Assume a 30 second measurement.
- - The relay will handle 1*30 = 30 Mbit of traffic during the
- measurement, or 3.75 MB, or 3.75 million bytes.
- - Cells are 514 bytes. Approximately (e.g. ignoring TLS) 7300 cells
- will be sent/recv over the course of the measurement.
- - A bucket_size of 50 results in about 146 buckets over the course of
- the 30s measurement.
- - Therefore, the odds of the adversary cheating successfully as
- (49/50)^(146), or about 5.2%.
-
-This sounds high, but a relay capable of double the bandwidth (2 Mbit/s)
-will have (49/50)^(2*146) or 0.2% odds of success, which is quite low.
-
-Wanting a <1% chance that a 10 Mbit/s relay can successfully cheat
-results in a bucket size of approximately 125:
-
- - 10*30 = 300 Mbit of traffic during 30s measurement. 37.5 million
- bytes.
- - 37,500,000 bytes / 514 bytes/cell = ~73,000 cells
- - bucket_size of 125 cells means 73,000 / 125 = 584 buckets
- - (124/125)^(584) = 0.918% chance of successfully cheating
-
-Slower relays can cheat more easily but the amount of extra weight they
-can obtain is insignificant in absolute terms. Faster relays are
-essentially unable to cheat.
-
-3.3.2 Weight Inflation
+### 3.3.1 Weight Inflation
Target relays are an active part of the measurement process; they know
they are getting measured. While a relay cannot fake the measurement
@@ -638,19 +548,19 @@ the measurer (or some party on its behalf) create a regular stream
through the relay and measure the throughput on the stream
before/during/after the measurement. This can be explored longer term.
-3.3.3 Incomplete Authentication
+### 3.3.2 Incomplete Authentication
The short term FlashFlow implementation has the relay set two torrc
options if they would like to allow themselves to be measured: a flag
allowing measurement, and the list of coordinator TLS certificate that
are allowed to start a measurement.
-The relay drops MSM_PARAMS cells from coordinators it does not trust,
+The relay drops MEAS_PARAMS cells from coordinators it does not trust,
and immediately closes the connection after that. A FF coordinator
cannot convince a relay to enter measurement mode unless the relay
trusts its TLS certificate.
-A trusted coordinator specifies in the MSM_PARAMS cell the IP addresses
+A trusted coordinator specifies in the MEAS_PARAMS cell the IP addresses
of the measurers the relay shall expect to connect to it shortly. The
target adds the measurer IP addresses to a whitelist in the DoS
connection limit system, exempting them from any configured connection
@@ -660,12 +570,16 @@ The adversary could also pretend to be the measurer. Such an adversary
could induce measurement failures and inaccuracies. (Note: the whitelist
is cleared after the measurement is over.)
-4. FlashFlow measurement system: Medium term
+# 4. FlashFlow measurement system: Medium term
The medium term deployment stage begins after FlashFlow has been
implemented and relays are starting to update to a version of Tor that
supports it.
+New link- and relay-subprotocol versions will be used by the relay to indicate
+FF support. E.g. at the time of writing, the next relay subprotocol version is
+4 [3].
+
We plan to host a FlashFlow deployment consisting of a FF coordinator
and a single FF measurer on a single 1 Gbit/s machine. Data produced by
this deployment will be made available (semi?) publicly, including both
@@ -674,7 +588,7 @@ v3bw files and intermediate results.
Any development changes needed during this time would go through
separate proposals.
-5. FlashFlow measurement system: Long term
+# 5. FlashFlow measurement system: Long term
In the long term, finishing-touch development work will be done,
including adding better authentication and measurement scheduling, and
@@ -684,7 +598,7 @@ into the Tor ecosystem.
Any development changes needed during this time would go through
separate proposals.
-5.1 Authentication to Target Relay
+## 5.1 Authentication to Target Relay
Short term deployment already had FlashFlow coordinators using TLS
certificates when connecting to relays, but in the long term, directory
@@ -694,10 +608,10 @@ same way they currently vote on recommended tor versions.
FlashFlow measurers will be updated to use TLS certificates when
connecting to relays too. FlashFlow coordinators will update the
-contents of MSM_PARAMS cells to contain measurer TLS certificates
+contents of MEAS_PARAMS cells to contain measurer TLS certificates
instead of IP addresses, and relays will update to expect this change.
-5.2 Measurement Scheduling
+## 5.2 Measurement Scheduling
Short term deployment only has one FF deployment running. Long term this
may no longer be the case because, for example, more than one directory
@@ -706,6 +620,11 @@ deployment. FF deployments will need to coordinate between themselves
to not measure the same relay at the same time, and to handle new relays
as they join during the middle of a measurement period (during the day).
+The measurement scheduling process shall be non-interactive. All the inputs
+(e.g. the shared random value, the identities of the coords, the relays
+currently in the network) are publicly known to (at least) the bwauths, thus
+each individual bwauth can calculate same multi-coord measurement schedule.
+
The following is quoted from Section 4.3 of the FlashFlow paper.
To measure all relays in the network, the BWAuths periodically
@@ -733,11 +652,22 @@ The following is quoted from Section 4.3 of the FlashFlow paper.
ensures that old relays will continue to be measured, with new
relays given secondary priority in the order they arrive.
-5.3 Experiments
+[XXX Teor leaves good ideas in his tor-dev@ post [5],
+including a good plain language description of what the FF paper quotes says,
+and a recommendation on which consensus to use when making a new schedule]
+
+A problem arises when two relays are hosted on the same machine but measured
+at different times: they both will be measured to have the full capacity of
+their host. At the very least, the scheduling algo should schedule relays with
+the same IP to be measured at the same time. Perhaps better is measuring all
+relays in the same MyFamily, same ipv4/24, and/or same ipv6/48 at the same
+time. What specifically to do here is left for medium/long term work.
+
+## 5.3 Experiments
[XXX todo]
-5.4 Other Changes/Investigations/Ideas
+## 5.4 Other Changes/Investigations/Ideas
- How can FlashFlow data be used in a way that doesn't lead to poor load
balancing given the following items that lead to non-uniform client
@@ -768,13 +698,136 @@ The following is quoted from Section 4.3 of the FlashFlow paper.
ticket? Was it because of the speed test? Why? Will FlashFlow produce
the same behavior?
-6. Citations
+# Citations
[0] F. Thill. Hidden Service Tracking Detection and Bandwidth Cheating
in Tor Anonymity Network. Master’s thesis, Univ. Luxembourg, 2014.
+ https://www.cryptolux.org/images/b/bc/Tor_Issues_Thesis_Thill_Fabrice.pdf
[1] A. Johnson, R. Jansen, N. Hopper, A. Segal, and P. Syverson.
PeerFlow: Secure Load Balancing in Tor. Proceedings on Privacy
Enhancing Technologies (PoPETs), 2017(2), April 2017.
+ https://ohmygodel.com/publications/peerflow-popets2017.pdf
[2] Mike Perry: Graph onionperf and consensus information from Rob's
- experiments https://trac.torproject.org/projects/tor/ticket/33076
+ experiments
+ https://trac.torproject.org/projects/tor/ticket/33076
+[3] tor-spec.txt Section 9.3 "Relay" Subprotocol versioning
+ https://gitweb.torproject.org/torspec.git/tree/tor-spec.txt#n2132
+[4] Teor's second respose to FlashFlow proposal
+ https://lists.torproject.org/pipermail/tor-dev/2020-April/014251.html
+[5] Teor's first respose to FlashFlow proposal
+ https://lists.torproject.org/pipermail/tor-dev/2020-April/014246.html
+
+# Appendix A: Save CPU at measurer by not encrypting all MEAS_ECHO cells
+
+## Verify echo cells
+
+A parameter will exist to tell the measurers with what frequency they
+shall verify that cells echoed back to them match what was sent. This
+parameter does not need to exist outside of the FF deployment (e.g. it
+doesn't need to be a consensus parameter).
+
+The parameter instructs the measurers to check 1 out of every N cells.
+
+The measurer keeps a count of how many measurement cells it has sent. It
+also logically splits its output stream of cells into buckets of size N.
+At the start of each bucket (when num_sent % N == 0), the measurer
+chooses a random index in the bucket. Upon sending the cell at that
+index (num_sent % N == chosen_index), the measurer records the cell.
+
+The measurer also counts cells that it receives. When it receives a cell
+at an index that was recorded, it verifies that the received cell
+matches the recorded sent cell. If they match, no special action is
+taken. If they don't match, the measurer indicates failure to the
+coordinator and target relay and closes all connections, ending the
+measurement.
+
+### Example
+
+Consider bucket_size is 1000. For the moment ignore cell encryption.
+
+We start at idx=0 and pick an idx in [0, 1000) to record, say 640. At
+idx=640 we record the cell. At idx=1000 we choose a new idx in [1000,
+2000) to record, say 1236. At idx=1236 we record the cell. At idx=2000
+we choose a new idx in [2000, 3000). Etc.
+
+There's 2000+ cells in flight and the measurer has recorded two items:
+
+```
+- (640, contents_of_cellA)
+- (1236, contents_of_cellB)
+```
+
+Consider the receive side now. It counts the cells it receives. At
+receive idx=640, it checks the received cell matches the saved cell from
+before. At receive idx=1236, it again checks the received cell matches.
+Etc.
+
+### Motivation
+
+A malicious relay may want to skip decryption of measurement cells to
+save CPU cycles and obtain a higher capacity estimate. More generally,
+it could generate fake measurement cells locally, ignore the measurement
+traffic it is receiving, and flood the measurer with more traffic that
+it (the measurer) is even sending.
+
+The security of echo cell verification is discussed in section 3.3.1.
+
+### Security
+
+A smaller bucket size means more cells are checked and FF is more likely
+to detect a malicious target. It also means more bookkeeping overhead
+(CPU/RAM).
+
+An adversary that knows bucket_size and cheats on one item out of every
+bucket_size items will have a 1/bucket_size chance of getting caught in
+the first bucket. This is the worst case adversary. While cheating on
+just a single item per bucket yields very little advantage, cheating on
+more items per bucket increases the likelihood the adversary gets
+caught. Thus only the worst case is considered here.
+
+In general, the odds the adversary can successfully cheat in a single
+bucket are
+
+```
+(bucket_size-1)/bucket_size
+```
+
+Thus the odds the adversary can cheat in X consecutive buckets are
+
+```
+[(bucket_size-1)/bucket_size]^X
+```
+
+In our case, X will be highly varied: Slow relays won't see very many
+buckets, but fast relays will. The damage to the network a very slow
+relay can do by faking being only slightly faster is limited.
+Nonetheless, for now we motivate the selection of bucket_size with a
+slow relay:
+
+- Assume a very slow relay of 1 Mbit/s capacity that will cheat 1 cell
+ in each bucket. Assume a 30 second measurement.
+- The relay will handle 1*30 = 30 Mbit of traffic during the
+ measurement, or 3.75 MB, or 3.75 million bytes.
+- Cells are 514 bytes. Approximately (e.g. ignoring TLS) 7300 cells
+ will be sent/recv over the course of the measurement.
+- A bucket_size of 50 results in about 146 buckets over the course of
+ the 30s measurement.
+- Therefore, the odds of the adversary cheating successfully as
+ (49/50)^(146), or about 5.2%.
+
+This sounds high, but a relay capable of double the bandwidth (2 Mbit/s)
+will have (49/50)^(2*146) or 0.2% odds of success, which is quite low.
+
+Wanting a <1% chance that a 10 Mbit/s relay can successfully cheat
+results in a bucket size of approximately 125:
+
+- 10*30 = 300 Mbit of traffic during 30s measurement. 37.5 million
+ bytes.
+- 37,500,000 bytes / 514 bytes/cell = ~73,000 cells
+- bucket_size of 125 cells means 73,000 / 125 = 584 buckets
+- (124/125)^(584) = 0.918% chance of successfully cheating
+
+Slower relays can cheat more easily but the amount of extra weight they
+can obtain is insignificant in absolute terms. Faster relays are
+essentially unable to cheat.
diff --git a/proposals/326-tor-relay-well-known-uri-rfc8615.md b/proposals/326-tor-relay-well-known-uri-rfc8615.md
new file mode 100644
index 0000000..cd7f074
--- /dev/null
+++ b/proposals/326-tor-relay-well-known-uri-rfc8615.md
@@ -0,0 +1,72 @@
+```
+Filename: 326-tor-relay-well-known-uri-rfc8615.md
+Title: The "tor-relay" Well-Known Resource Identifier
+Author: nusenu
+Created: 14 August 2020
+Status: Open
+```
+
+# The "tor-relay" Well-Known Resource Identifier
+
+This is a specification for a well-known [registry](https://www.iana.org/assignments/well-known-uris/) entry according to [RFC8615](https://tools.ietf.org/html/rfc8615).
+
+This resource identifier is used for the the verification of [Tor](https://www.torproject.org/) relay contact information
+(more specifically the [operatorurl](https://nusenu.github.io/ContactInfo-Information-Sharing-Specification/#operatorurl)).
+It can also be used for autodiscovery of Tor relays run by a given entity, if the entity domain is known.
+It solves the issue that Tor relay contact information is an unidirectional and unverified claim by nature.
+This well-known URI aims to allow the verification of the unidirectional claim.
+It aims to reduce the risk of impersonation attacks, where a Tor relay claims to be operated by a certain entity, but actually isn't.
+The automated verification will also support the [visualization of relay groups](https://gitlab.torproject.org/tpo/metrics/relay-search/-/issues/40001).
+
+* An initially (unverified) Tor relay contact information might claim to be related to an
+organization by pointing to its website: Tor relay contact information field -> website
+* The "tor-relay" URI allows for the verification of that claim by fetching the files containing Tor relay ID(s) under the specified URI,
+because attackers can not easily place these files at the given location.
+
+* By publishing Tor relay IDs under this URI the website operator claims to operate these relays.
+The verification of listed Tor relay IDs only succeeds if the claim can be verified bidirectionally (website -> relay and relay -> website).
+
+* This URI is not related to Tor bridges or Tor onion services.
+
+* The URL MUST be HTTPS and use a valid TLS certificate from a generally trusted root CA. Plain HTTP MUST not be used.
+
+* The URL MUST be accessible by robots (no CAPTCHAs).
+
+## /.well-known/tor-relay/rsa-fingerprint.txt
+
+* The file contains one or more Tor relay RSA SHA1 fingerprints operated by the entity in control of this website.
+* Each line contains one fingerprint.
+* The file may contain comments (starting with #).
+* Non-comment lines must be exactly 40 characters long and consist of the following characters [a-fA-F0-9].
+* Fingerprints are not case-sensitive.
+* Each fingerprint MUST appear at most once.
+* The file MUST not be larger than one MByte.
+* The file MUST NOT contain fingerprints of Tor bridges (or hashes of bridge fingerprints).
+* The content MUST be a media type of "text/plain".
+
+Example file content:
+
+```
+# we operate these Tor relays
+A234567890123456789012345678901234567ABC
+B234567890123456789012345678901234567890
+```
+The RSA SHA1 relay fingerprint can be found in the file named "fingerprint" located in the Tor data directory on the relay.
+
+
+# Change Controller
+
+Tor Project Development Mailing List <tor-dev@lists.torproject.org>
+
+# Related Information
+
+* [https://gitweb.torproject.org/torspec.git/tree/tor-spec.txt](https://gitweb.torproject.org/torspec.git/tree/tor-spec.txt)
+* [https://gitweb.torproject.org/torspec.git/tree/cert-spec.txt](https://gitweb.torproject.org/torspec.git/tree/cert-spec.txt)
+* [https://nusenu.github.io/ContactInfo-Information-Sharing-Specification/#operatorurl](https://nusenu.github.io/ContactInfo-Information-Sharing-Specification/#operatorurl)
+* [RFC8615](https://tools.ietf.org/html/rfc8615)
+
+
+
+
+
+
diff --git a/proposals/327-pow-over-intro.txt b/proposals/327-pow-over-intro.txt
new file mode 100644
index 0000000..fb58a7d
--- /dev/null
+++ b/proposals/327-pow-over-intro.txt
@@ -0,0 +1,1129 @@
+Filename: 327-pow-over-intro.txt
+Title: A First Take at PoW Over Introduction Circuits
+Author: George Kadianakis, Mike Perry, David Goulet, tevador
+Created: 2 April 2020
+Status: Draft
+
+0. Abstract
+
+ This proposal aims to thwart introduction flooding DoS attacks by introducing
+ a dynamic Proof-Of-Work protocol that occurs over introduction circuits.
+
+1. Motivation
+
+ So far our attempts at limiting the impact of introduction flooding DoS
+ attacks on onion services has been focused on horizontal scaling with
+ Onionbalance, optimizing the CPU usage of Tor and applying congestion control
+ using rate limiting. While these measures move the goalpost forward, a core
+ problem with onion service DoS is that building rendezvous circuits is a
+ costly procedure both for the service and for the network. For more
+ information on the limitations of rate-limiting when defending against DDoS,
+ see [REF_TLS_1].
+
+ If we ever hope to have truly reachable global onion services, we need to
+ make it harder for attackers to overload the service with introduction
+ requests. This proposal achieves this by allowing onion services to specify
+ an optional dynamic proof-of-work scheme that its clients need to participate
+ in if they want to get served.
+
+ With the right parameters, this proof-of-work scheme acts as a gatekeeper to
+ block amplification attacks by attackers while letting legitimate clients
+ through.
+
+1.1. Related work
+
+ For a similar concept, see the three internet drafts that have been proposed
+ for defending against TLS-based DDoS attacks using client puzzles [REF_TLS].
+
+1.2. Threat model [THREAT_MODEL]
+
+1.2.1. Attacker profiles [ATTACKER_MODEL]
+
+ This proposal is written to thwart specific attackers. A simple PoW proposal
+ cannot defend against all and every DoS attack on the Internet, but there are
+ adverary models we can defend against.
+
+ Let's start with some adversary profiles:
+
+ "The script-kiddie"
+
+ The script-kiddie has a single computer and pushes it to its
+ limits. Perhaps it also has a VPS and a pwned server. We are talking about
+ an attacker with total access to 10 Ghz of CPU and 10 GBs of RAM. We
+ consider the total cost for this attacker to be zero $.
+
+ "The small botnet"
+
+ The small botnet is a bunch of computers lined up to do an introduction
+ flooding attack. Assuming 500 medium-range computers, we are talking about
+ an attacker with total access to 10 Thz of CPU and 10 TB of RAM. We consider
+ the upfront cost for this attacker to be about $400.
+
+ "The large botnet"
+
+ The large botnet is a serious operation with many thousands of computers
+ organized to do this attack. Assuming 100k medium-range computers, we are
+ talking about an attacker with total access to 200 Thz of CPU and 200 TB of
+ RAM. The upfront cost for this attacker is about $36k.
+
+ We hope that this proposal can help us defend against the script-kiddie
+ attacker and small botnets. To defend against a large botnet we would need
+ more tools in our disposal (see [FUTURE_DESIGNS]).
+
+1.2.2. User profiles [USER_MODEL]
+
+ We have attackers and we have users. Here are a few user profiles:
+
+ "The standard web user"
+
+ This is a standard laptop/desktop user who is trying to browse the
+ web. They don't know how these defences work and they don't care to
+ configure or tweak them. They are gonna use the default values and if the
+ site doesn't load, they are gonna close their browser and be sad at Tor.
+ They run a 2Ghz computer with 4GB of RAM.
+
+ "The motivated user"
+
+ This is a user that really wants to reach their destination. They don't
+ care about the journey; they just want to get there. They know what's going
+ on; they are willing to tweak the default values and make their computer do
+ expensive multi-minute PoW computations to get where they want to be.
+
+ "The mobile user"
+
+ This is a motivated user on a mobile phone. Even tho they want to read the
+ news article, they don't have much leeway on stressing their machine to do
+ more computation.
+
+ We hope that this proposal will allow the motivated user to always connect
+ where they want to connect to, and also give more chances to the other user
+ groups to reach the destination.
+
+1.2.3. The DoS Catch-22 [CATCH22]
+
+ This proposal is not perfect and it does not cover all the use cases. Still,
+ we think that by covering some use cases and giving reachability to the
+ people who really need it, we will severely demotivate the attackers from
+ continuing the DoS attacks and hence stop the DoS threat all
+ together. Furthermore, by increasing the cost to launch a DoS attack, a big
+ class of DoS attackers will disappear from the map, since the expected ROI
+ will decrease.
+
+2. System Overview
+
+2.1. Tor protocol overview
+
+ +----------------------------------+
+ | Onion Service |
+ +-------+ INTRO1 +-----------+ INTRO2 +--------+ |
+ |Client |-------->|Intro Point|------->| PoW |-----------+ |
+ +-------+ +-----------+ |Verifier| | |
+ +--------+ | |
+ | | |
+ | | |
+ | +----------v---------+ |
+ | |Intro Priority Queue| |
+ +---------+--------------------+---+
+ | | |
+ Rendezvous | | |
+ circuits | | |
+ v v v
+
+
+
+ The proof-of-work scheme specified in this proposal takes place during the
+ introduction phase of the onion service protocol.
+
+ The system described in this proposal is not meant to be on all the time, and
+ should only be enabled by services when under duress. The percentage of
+ clients receiving puzzles can also be configured based on the load of the
+ service.
+
+ In summary, the following steps are taken for the protocol to complete:
+
+ 1) Service encodes PoW parameters in descriptor [DESC_POW]
+ 2) Client fetches descriptor and computes PoW [CLIENT_POW]
+ 3) Client completes PoW and sends results in INTRO1 cell [INTRO1_POW]
+ 4) Service verifies PoW and queues introduction based on PoW effort [SERVICE_VERIFY]
+
+2.2. Proof-of-work overview
+
+2.2.1. Primitives
+
+ For our proof-of-work function we will use the 'equix' scheme by tevador
+ [REF_EQUIX]. Equix is an assymetric PoW function based on Equihash<60,3>. It
+ features lightning fast verification speed, and also aims to minimize the
+ assymetry between CPU and GPU. Furthermore, it's designed for this particular
+ use-case and hence cryptocurrency miners are not incentivized to make
+ optimized ASICs for it.
+
+ The Equix scheme provides two functions that will be used in this proposal:
+ - equix_solve(seed, nonce, effort) which solves a puzzle instance.
+ - equix_verify(seed, nonce, effort, solution) which verifies a puzzle solution.
+
+ We tune equix in section [EQUIX_TUNING].
+
+2.2.2. Dynamic PoW
+
+ DoS is a dynamic problem where the attacker's capabilities constantly change,
+ and hence we want our proof-of-work system to be dynamic and not stuck with a
+ static difficulty setting. Hence, instead of forcing clients to go below a
+ static target like in Bitcoin to be successful, we ask clients to "bid" using
+ their PoW effort. Effectively, a client gets higher priority the higher
+ effort they put into their proof-of-work. This is similar to how
+ proof-of-stake works but instead of staking coins, you stake work.
+
+ The benefit here is that legitimate clients who really care about getting
+ access can spend a big amount of effort into their PoW computation, which
+ should guarantee access to the service given reasonable adversary models. See
+ [PARAM_TUNING] for more details about these guarantees and tradeoffs.
+
+ As a way to improve reachability and UX, the service tries to estimate the
+ effort needed for clients to get access at any given time and places it in
+ the descriptor. See [EFFORT_ESTIMATION] for more details.
+
+2.2.3. PoW effort
+
+ For our dynamic PoW system to work, we will need to be able to compare PoW
+ tokens with each other. To do so we define a function:
+ unsigned effort(uint8_t *token)
+ which takes as its argument a hash output token, interprets it as a
+ bitstring, and returns the quotient of dividing a bitstring of 1s by it.
+
+ So for example:
+ effort(00000001100010101101) = 11111111111111111111 / 00000001100010101101
+ or the same in decimal:
+ effort(6317) = 1048575 / 6317 = 165.
+
+ This definition of effort has the advantage of directly expressing the
+ expected number of hashes that the client had to calculate to reach the
+ effort. This is in contrast to the (cheaper) exponential effort definition of
+ taking the number of leading zero bits.
+
+3. Protocol specification
+
+3.1. Service encodes PoW parameters in descriptor [DESC_POW]
+
+ This whole protocol starts with the service encoding the PoW parameters in
+ the 'encrypted' (inner) part of the v3 descriptor. As follows:
+
+ "pow-params" SP type SP seed-b64 SP expiration-time NL
+
+ [At most once]
+
+ type: The type of PoW system used. We call the one specified here "v1"
+
+ seed-b64: A random seed that should be used as the input to the PoW
+ hash function. Should be 32 random bytes encoded in base64
+ without trailing padding.
+
+ suggested-effort: An unsigned integer specifying an effort value that
+ clients should aim for when contacting the service. See
+ [EFFORT_ESTIMATION] for more details here.
+
+ expiration-time: A timestamp in "YYYY-MM-DD SP HH:MM:SS" format after
+ which the above seed expires and is no longer valid as
+ the input for PoW. It's needed so that the size of our
+ replay cache does not grow infinitely. It should be
+ set to RAND_TIME(now+7200, 900) seconds.
+
+ The service should refresh its seed when expiration-time passes. The service
+ SHOULD keep its previous seed in memory and accept PoWs using it to avoid
+ race-conditions with clients that have an old seed. The service SHOULD avoid
+ generating two consequent seeds that have a common 4 bytes prefix. See
+ [INTRO1_POW] for more info.
+
+ By RAND_TIME(ts, interval) we mean a time between ts-interval and ts, chosen
+ uniformly at random.
+
+3.2. Client fetches descriptor and computes PoW [CLIENT_POW]
+
+ If a client receives a descriptor with "pow-params", it should assume that
+ the service is expecting a PoW input as part of the introduction protocol.
+
+ The client parses the descriptor and extracts the PoW parameters. It makes
+ sure that the <expiration-time> has not expired and if it has, it needs to
+ fetch a new descriptor.
+
+ The client should then extract the <suggested-effort> field to configure its
+ PoW 'target' (see [REF_TARGET]). The client SHOULD NOT accept 'target' values
+ that will cause an infinite PoW computation. {XXX: How to enforce this?}
+
+ To complete the PoW the client follows the following logic:
+
+ a) Client selects a target effort E.
+ b) Client generates a random 16-byte nonce N.
+ c) Client derives seed C by decoding 'seed-b64'.
+ d) Client calculates S = equix_solve(C || N || E)
+ e) Client calculates R = blake2b(C || N || E || S)
+ f) Client checks if R * E <= UINT32_MAX.
+ f1) If yes, success! The client can submit N, E, the first 4 bytes of C
+ and S.
+ f2) If no, fail! The client interprets N as a 16-byte little-endian
+ integer, increments it by 1 and goes back to step d).
+
+ At the end of the above procedure, the client should have S as the solution
+ of the Equix puzzle with N as the nonce, C as the seed. How quickly this
+ happens depends solely on the target effort E parameter.
+
+3.3. Client sends PoW in INTRO1 cell [INTRO1_POW]
+
+ Now that the client has an answer to the puzzle it's time to encode it into
+ an INTRODUCE1 cell. To do so the client adds an extension to the encrypted
+ portion of the INTRODUCE1 cell by using the EXTENSIONS field (see
+ [PROCESS_INTRO2] section in rend-spec-v3.txt). The encrypted portion of the
+ INTRODUCE1 cell only gets read by the onion service and is ignored by the
+ introduction point.
+
+ We propose a new EXT_FIELD_TYPE value:
+
+ [01] -- PROOF_OF_WORK
+
+ The EXT_FIELD content format is:
+
+ POW_VERSION [1 byte]
+ POW_NONCE [16 bytes]
+ POW_EFFORT [4 bytes]
+ POW_SEED [4 bytes]
+ POW_SOLUTION [16 bytes]
+
+ where:
+
+ POW_VERSION is 1 for the protocol specified in this proposal
+ POW_NONCE is the nonce 'N' from the section above
+ POW_SEED is the first 4 bytes of the seed used
+
+ This will increase the INTRODUCE1 payload size by 43 bytes since the
+ extension type and length is 2 extra bytes, the N_EXTENSIONS field is always
+ present and currently set to 0 and the EXT_FIELD is 41 bytes. According to
+ ticket #33650, INTRODUCE1 cells currently have more than 200 bytes
+ available.
+
+3.4. Service verifies PoW and handles the introduction [SERVICE_VERIFY]
+
+ When a service receives an INTRODUCE1 with the PROOF_OF_WORK extension, it
+ should check its configuration on whether proof-of-work is required to
+ complete the introduction. If it's not required, the extension SHOULD BE
+ ignored. If it is required, the service follows the procedure detailed in
+ this section.
+
+ If the service requires the PROOF_OF_WORK extension but received an
+ INTRODUCE1 cell without any embedded proof-of-work, the service SHOULD
+ consider this cell as a zero-effort introduction for the purposes of the
+ priority queue (see section [INTRO_QUEUE]).
+
+3.4.1. PoW verification [POW_VERIFY]
+
+ To verify the client's proof-of-work the service MUST do the following steps:
+
+ a) Find a valid seed C that starts with POW_SEED. Fail if no such seed
+ exists.
+ b) Fail if E = POW_EFFORT is lower than the minimum effort.
+ c) Fail if N = POW_NONCE is present in the replay cache (see [REPLAY_PROTECTION[)
+ d) Calculate R = blake2b(C || N || E || S)
+ e) Fail if R * E > UINT32_MAX
+ f) Fail if equix_verify(C || N || E, S) != EQUIX_OK
+ g) Put the request in the queue with a priority of E
+
+ If any of these steps fail the service MUST ignore this introduction request
+ and abort the protocol.
+
+ In this proposal we call the above steps the "top half" of introduction
+ handling. If all the steps of the "top half" have passed, then the circuit
+ is added to the introduction queue as detailed in section [INTRO_QUEUE].
+
+3.4.1.1. Replay protection [REPLAY_PROTECTION]
+
+ The service MUST NOT accept introduction requests with the same (seed, nonce)
+ tuple. For this reason a replay protection mechanism must be employed.
+
+ The simplest way is to use a simple hash table to check whether a (seed,
+ nonce) tuple has been used before for the actiev duration of a
+ seed. Depending on how long a seed stays active this might be a viable
+ solution with reasonable memory/time overhead.
+
+ If there is a worry that we might get too many introductions during the
+ lifetime of a seed, we can use a Bloom filter as our replay cache
+ mechanism. The probabilistic nature of Bloom filters means that sometimes we
+ will flag some connections as replays even if they are not; with this false
+ positive probability increasing as the number of entries increase. However,
+ with the right parameter tuning this probability should be negligible and
+ well handled by clients. {TODO: Figure bloom filter}
+
+3.4.2. The Introduction Queue [INTRO_QUEUE]
+
+3.4.2.1. Adding introductions to the introduction queue [ADD_QUEUE]
+
+ When PoW is enabled and a verified introduction comes through, the service
+ instead of jumping straight into rendezvous, queues it and prioritizes it
+ based on how much effort was devoted by the client to PoW. This means that
+ introduction requests with high effort should be prioritized over those with
+ low effort.
+
+ To do so, the service maintains an "introduction priority queue" data
+ structure. Each element in that priority queue is an introduction request,
+ and its priority is the effort put into its PoW:
+
+ When a verified introduction comes through, the service uses the effort()
+ function with the solution S as its input, and uses the output to place requests
+ into the right position of the priority_queue: The bigger the effort, the
+ more priority it gets in the queue. If two elements have the same effort, the
+ older one has priority over the newer one.
+
+3.4.2.2. Handling introductions from the introduction queue [HANDLE_QUEUE]
+
+ The service should handle introductions by pulling from the introduction
+ queue. We call this part of introduction handling the "bottom half" because
+ most of the computation happens in this stage. For a description of how we
+ expect such a system to work in Tor, see [TOR_SCHEDULER] section.
+
+3.4.3. PoW effort estimation [EFFORT_ESTIMATION]
+
+ The service starts with a default suggested-effort value of 5000 (see
+ [EQUIX_DIFFICULTY] section for more info).
+
+ Then during its operation the service continuously keeps track of the
+ received PoW cell efforts to inform its clients of the effort they should put
+ in their introduction to get service. The service informs the clients by
+ using the <suggested-effort> field in the descriptor.
+
+ Everytime the service handles or trims an introduction request from the
+ priority queue in [HANDLE_QUEUE], the service adds the request's effort to a
+ sorted list.
+
+ Then every HS_UPDATE_PERIOD seconds (which is controlled through a consensus
+ parameter and has a default value of 300 seconds) and while the DoS feature
+ is enabled, the service updates its <suggested-effort> value as follows:
+
+ 1. Set TOTAL_EFFORT to the sum of the effort of all valid requests that
+ have been received since the last HS descriptor update (this includes
+ all handled requests, trimmed requests and requests still in the queue)
+
+ 2. Set SUGGESTED_EFFORT = TOTAL_EFFORT / (SVC_BOTTOM_CAPACITY * HS_UPDATE_PERIOD).
+ The denominator above is the max number of requests that the service
+ could have handled during that time.
+
+ 3. Set <suggested-effort> to max(MIN_EFFORT, SUGGESTED_EFFORT).
+
+ During the above procedure we use the following default values:
+ - MIN_EFFORT = 1000, as the result of a simulation experiment [REF_TEVADOR_SIM]
+ - SVC_BOTTOM_CAPACITY = 100, which is the number of introduction requests
+ that can be handled by the service per second. This was computed in
+ [POW_DIFFICULTY_TOR] as 180, but we reduced it to 100 to account for
+ slower computers and networks.
+
+ The above algorithm is meant to balance the suggested effort based on the
+ effort of all received requests. It attempts to dynamically adjust the
+ suggested effort so that it increases when an attack is received, and tones
+ down when the attack has stopped.
+
+ It's worth noting that the suggested-effort is not a hard limit to the
+ efforts that are accepted by the service, and it's only meant to serve as a
+ guideline for clients to reduce the number of unsuccessful requests that get
+ to the service. The service still adds requests with lower effort than
+ suggested-effort to the priority queue in [ADD_QUEUE].
+
+ Finally, the above algorithm will never reset back to zero suggested-effort,
+ even if the attack is completely over. That's because in that case it would
+ be impossible to determine the total computing power of connecting
+ clients. Instead it will reset back to MIN_EFFORT, and the operator will have
+ to manually shut down the anti-DoS mechanism.
+
+ {XXX: SVC_BOTTOM_CAPACITY is static above and will not be accurate for all
+ boxes. Ideally we should calculate SVC_BOTTOM_CAPACITY dynamically based on
+ the resources of every onion service while the algorithm is running.}
+
+3.4.3.1. Updating descriptor with new suggested effort
+
+ Every HS_UPDATE_PERIOD seconds the service should upload a new descriptor
+ with a new suggested-effort value.
+
+ The service should avoid uploading descriptors too often to avoid overwheming
+ the HSDirs. The service SHOULD NOT upload descriptors more often than
+ HS_UPDATE_PERIOD. The service SHOULD NOT upload a new descriptor if the
+ suggested-effort value changes by less than 15%.
+
+ {XXX: Is this too often? Perhaps we can set different limits for when the
+ difficulty goes up and different for when it goes down. It's more important
+ to update the descriptor when the difficulty goes up.}
+
+ {XXX: What attacks are possible here? Can the attacker intentionally hit this
+ rate-limit and then influence the suggested effort so that clients do not
+ learn about the new effort?}
+
+4. Client behavior [CLIENT_BEHAVIOR]
+
+ This proposal introduces a bunch of new ways where a legitimate client can
+ fail to reach the onion service.
+
+ Furthermore, there is currently no end-to-end way for the onion service to
+ inform the client that the introduction failed. The INTRO_ACK cell is not
+ end-to-end (it's from the introduction point to the client) and hence it does
+ not allow the service to inform the client that the rendezvous is never gonna
+ occur.
+
+ For this reason we need to define some client behaviors to work around these
+ issues.
+
+4.1. Clients handling timeouts [CLIENT_TIMEOUT]
+
+ Alice can fail to reach the onion service if her introduction request gets
+ trimmed off the priority queue in [HANDLE_QUEUE], or if the service does not
+ get through its priority queue in time and the connection times out.
+
+ This section presents a heuristic method for the client getting service even
+ in such scenarios.
+
+ If the rendezvous request times out, the client SHOULD fetch a new descriptor
+ for the service to make sure that it's using the right suggested-effort for
+ the PoW and the right PoW seed. The client SHOULD NOT fetch service
+ descriptors more often than every 'hs-pow-desc-fetch-rate-limit' seconds
+ (which is controlled through a consensus parameter and has a default value of
+ 600 seconds).
+
+ {XXX: Is this too rare? Too often?}
+
+ When the client fetches a new descriptor, it should try connecting to the
+ service with the new suggested-effort and PoW seed. If that doesn't work, it
+ should double the effort and retry. The client should keep on
+ doubling-and-retrying until it manages to get service, or its able to fetch a
+ new descriptor again.
+
+ {XXX: This means that the client will keep on spinning and
+ doubling-and-retrying for a service under this situation. There will never be
+ a "Client connection timed out" page for the user. Is this good? Is this bad?
+ Should we stop doubling-and-retrying after some iterations? Or should we
+ throw a custom error page to the user, and ask the user to stop spinning
+ whenever they want?}
+
+4.3. Other descriptor issues
+
+ Another race condition here is if the service enables PoW, while a client has
+ a cached descriptor. How will the client notice that PoW is needed? Does it
+ need to fetch a new descriptor? Should there be another feedback mechanism?
+
+5. Attacker strategies [ATTACK_META]
+
+ Now that we defined our protocol we need to start tweaking the various
+ knobs. But before we can do that, we first need to understand a few
+ high-level attacker strategies to see what we are fighting against.
+
+5.1.1. Overwhelm PoW verification (aka "Overwhelm top half") [ATTACK_TOP_HALF]
+
+ A basic attack here is the adversary spamming with bogus INTRO cells so that
+ the service does not have computing capacity to even verify the
+ proof-of-work. This adversary tries to overwhelm the procedure in the
+ [POW_VERIFY] section.
+
+ That's why we need the PoW algorithm to have a cheap verification time so
+ that this attack is not possible: we tune this PoW parameter in section
+ [POW_TUNING_VERIFICATION].
+
+5.1.2. Overwhelm rendezvous capacity (aka "Overwhelm bottom half") [ATTACK_BOTTOM_HALF]
+
+ Given the way the introduction queue works (see [HANDLE_QUEUE]), a very
+ effective strategy for the attacker is to totally overwhelm the queue
+ processing by sending more high-effort introductions than the onion service
+ can handle at any given tick. This adversary tries to overwhelm the procedure
+ in the [HANDLE_QUEUE] section.
+
+ To do so, the attacker would have to send at least 20 high-effort
+ introduction cells every 100ms, where high-effort is a PoW which is above the
+ estimated level of "the motivated user" (see [USER_MODEL]).
+
+ An easier attack for the adversary, is the same strategy but with
+ introduction cells that are all above the comfortable level of "the standard
+ user" (see [USER_MODEL]). This would block out all standard users and only
+ allow motivated users to pass.
+
+5.1.3. Hybrid overwhelm strategy [ATTACK_HYBRID]
+
+ If both the top- and bottom- halves are processed by the same thread, this
+ opens up the possibility for a "hybrid" attack. Given the performance figures
+ for the bottom half (0.31 ms/req.) and the top half (5.5 ms/req.), the
+ attacker can optimally deny service by submitting 91 high-effort requests and
+ 1520 invalid requests per second. This will completely saturate the main loop
+ because:
+
+ 0.31*(1520+91) ~ 0.5 sec.
+ 5.5*91 ~ 0.5 sec.
+
+ This attack only has half the bandwidth requirement of [ATTACK_TOP_HALF] and
+ half the compute requirement of [ATTACK_BOTTOM_HALF].
+
+ Alternatively, the attacker can adjust the ratio between invalid and
+ high-effort requests depending on their bandwidth and compute capabilities.
+
+5.1.4. Gaming the effort estimation logic [ATTACK_EFFORT]
+
+ Another way to beat this system is for the attacker to game the effort
+ estimation logic (see [EFFORT_ESTIMATION]). Essentialy, there are two attacks
+ that we are trying to avoid:
+
+ - Attacker sets descriptor suggested-effort to a very high value effectively
+ making it impossible for most clients to produce a PoW token in a
+ reasonable timeframe.
+ - Attacker sets descriptor suggested-effort to a very small value so that
+ most clients aim for a small value while the attacker comfortably launches
+ an [ATTACK_BOTTOM_HALF] using medium effort PoW (see [REF_TEVADOR_1])
+
+5.1.4. Precomputed PoW attack
+
+ The attacker may precompute many valid PoW nonces and submit them all at once
+ before the current seed expires, overwhelming the service temporarily even
+ using a single computer. The current scheme gives the attackers 4 hours to
+ launch this attack since each seed lasts 2 hours and the service caches two
+ seeds.
+
+ An attacker with this attack might be aiming to DoS the service for a limited
+ amount of time, or to cause an [ATTACK_EFFORT] attack.
+
+6. Parameter tuning [POW_TUNING]
+
+ There are various parameters in this PoW system that need to be tuned:
+
+ We first start by tuning the time it takes to verify a PoW token. We do this
+ first because it's fundamental to the performance of onion services and can
+ turn into a DoS vector of its own. We will do this tuning in a way that's
+ agnostic to the chosen PoW function.
+
+ We will then move towards analyzing the default difficulty setting for our
+ PoW system. That defines the expected time for clients to succeed in our
+ system, and the expected time for attackers to overwhelm our system. Same as
+ above we will do this in a way that's agnostic to the chosen PoW function.
+
+ Finally, using those two pieces we will tune our PoW function and pick the
+ right default difficulty setting. At the end of this section we will know the
+ resources that an attacker needs to overwhelm the onion service, the
+ resources that the service needs to verify introduction requests, and the
+ resources that legitimate clients need to get to the onion service.
+
+6.1. PoW verification [POW_TUNING_VERIFICATION]
+
+ Verifying a PoW token is the first thing that a service does when it receives
+ an INTRODUCE2 cell and it's detailed in section [POW_VERIFY]. This
+ verification happens during the "top half" part of the process. Every
+ milisecond spent verifying PoW adds overhead to the already existing "top
+ half" part of handling an introduction cell. Hence we should be careful to
+ add minimal overhead here so that we don't enable attacks like [ATTACK_TOP_HALF].
+
+ During our performance measurements in [TOR_MEASUREMENTS] we learned that the
+ "top half" takes about 0.26 msecs in average, without doing any sort of PoW
+ verification. Using that value we compute the following table, that describes
+ the number of cells we can queue per second (aka times we can perform the
+ "top half" process) for different values of PoW verification time:
+
+ +---------------------+-----------------------+--------------+
+ |PoW Verification Time| Total "top half" time | Cells Queued |
+ | | | per second |
+ |---------------------|-----------------------|--------------|
+ | 0 msec | 0.26 msec | 3846 |
+ | 1 msec | 1.26 msec | 793 |
+ | 2 msec | 2.26 msec | 442 |
+ | 3 msec | 3.26 msec | 306 |
+ | 4 msec | 4.26 msec | 234 |
+ | 5 msec | 5.26 msec | 190 |
+ | 6 msec | 6.26 msec | 159 |
+ | 7 msec | 7.26 msec | 137 |
+ | 8 msec | 8.26 msec | 121 |
+ | 9 msec | 9.26 msec | 107 |
+ | 10 msec | 10.26 msec | 97 |
+ +---------------------+-----------------------+--------------+
+
+ Here is how you can read the table above:
+
+ - For a PoW function with a 1ms verification time, an attacker needs to send
+ 793 dummy introduction cells per second to succeed in a [ATTACK_TOP_HALF] attack.
+
+ - For a PoW function with a 2ms verification time, an attacker needs to send
+ 442 dummy introduction cells per second to succeed in a [ATTACK_TOP_HALF] attack.
+
+ - For a PoW function with a 10ms verification time, an attacker needs to send
+ 97 dummy introduction cells per second to succeed in a [ATTACK_TOP_HALF] attack.
+
+ Whether an attacker can succeed at that depends on the attacker's resources,
+ but also on the network's capacity.
+
+ Our purpose here is to have the smallest PoW verification overhead possible
+ that also allows us to achieve all our other goals.
+
+ [Note that the table above is simply the result of a naive multiplication and
+ does not take into account all the auxiliary overheads that happen every
+ second like the time to invoke the mainloop, the bottom-half processes, or
+ pretty much anything other than the "top-half" processing.
+
+ During our measurements the time to handle INTRODUCE2 cells dominates any
+ other action time: There might be events that require a long processing time,
+ but these are pretty infrequent (like uploading a new HS descriptor) and
+ hence over a long time they smooth out. Hence extrapolating the total cells
+ queued per second based on a single "top half" time seems like good enough to
+ get some initial intuition. That said, the values of "Cells queued per
+ second" from the table above, are likely much smaller than displayed above
+ because of all the auxiliary overheads.]
+
+6.2. PoW difficulty analysis [POW_DIFFICULTY_ANALYSIS]
+
+ The difficulty setting of our PoW basically dictates how difficult it should
+ be to get a success in our PoW system. An attacker who can get many successes
+ per second can pull a successfull [ATTACK_BOTTOM_HALF] attack against our
+ system.
+
+ In classic PoW systems, "success" is defined as getting a hash output below
+ the "target". However, since our system is dynamic, we define "success" as an
+ abstract high-effort computation.
+
+ Our system is dynamic but we still need a default difficulty settings that
+ will define the metagame and be used for bootstrapping the system. The client
+ and attacker can still aim higher or lower but for UX purposes and for
+ analysis purposes we do need to define a default difficulty.
+
+6.2.1. Analysis based on adversary power
+
+ In this section we will try to do an analysis of PoW difficulty without using
+ any sort of Tor-related or PoW-related benchmark numbers.
+
+ We created the table (see [REF_TABLE]) below which shows how much time a
+ legitimate client with a single machine should expect to burn before they get
+ a single success. The x-axis is how many successes we want the attacker to be
+ able to do per second: the more successes we allow the adversary, the more
+ they can overwhelm our introduction queue. The y-axis is how many machines
+ the adversary has in her disposal, ranging from just 5 to 1000.
+
+ ===============================================================
+ | Expected Time (in seconds) Per Success For One Machine |
+ ===========================================================================
+ | |
+ | Attacker Succeses 1 5 10 20 30 50 |
+ | per second |
+ | |
+ | 5 5 1 0 0 0 0 |
+ | 50 50 10 5 2 1 1 |
+ | 100 100 20 10 5 3 2 |
+ | Attacker 200 200 40 20 10 6 4 |
+ | Boxes 300 300 60 30 15 10 6 |
+ | 400 400 80 40 20 13 8 |
+ | 500 500 100 50 25 16 10 |
+ | 1000 1000 200 100 50 33 20 |
+ | |
+ ============================================================================
+
+ Here is how you can read the table above:
+
+ - If an adversary has a botnet with 1000 boxes, and we want to limit her to 1
+ success per second, then a legitimate client with a single box should be
+ expected to spend 1000 seconds getting a single success.
+
+ - If an adversary has a botnet with 1000 boxes, and we want to limit her to 5
+ successes per second, then a legitimate client with a single box should be
+ expected to spend 200 seconds getting a single success.
+
+ - If an adversary has a botnet with 500 boxes, and we want to limit her to 5
+ successes per second, then a legitimate client with a single box should be
+ expected to spend 100 seconds getting a single success.
+
+ - If an adversary has access to 50 boxes, and we want to limit her to 5
+ successes per second, then a legitimate client with a single box should be
+ expected to spend 10 seconds getting a single success.
+
+ - If an adversary has access to 5 boxes, and we want to limit her to 5
+ successes per second, then a legitimate client with a single box should be
+ expected to spend 1 seconds getting a single success.
+
+ With the above table we can create some profiles for default values of our
+ PoW difficulty. So for example, we can use the last case as the default
+ parameter for Tor Browser, and then create three more profiles for more
+ expensive cases, scaling up to the first case which could be hardest since
+ the client is expected to spend 15 minutes for a single introduction.
+
+6.2.2. Analysis based on Tor's performance [POW_DIFFICULTY_TOR]
+
+ To go deeper here, we can use the performance measurements from
+ [TOR_MEASUREMENTS] to get a more specific intuition on the default
+ difficulty. In particular, we learned that completely handling an
+ introduction cell takes 5.55 msecs in average. Using that value, we can
+ compute the following table, that describes the number of introduction cells
+ we can handle per second for different values of PoW verification:
+
+ +---------------------+-----------------------+--------------+
+ |PoW Verification Time| Total time to handle | Cells handled|
+ | | introduction cell | per second |
+ |---------------------|-----------------------|--------------|
+ | 0 msec | 5.55 msec | 180.18 |
+ | 1 msec | 6.55 msec | 152.67 |
+ | 2 msec | 7.55 msec | 132.45 |
+ | 3 msec | 8.55 msec | 116.96 |
+ | 4 msec | 9.55 mesc | 104.71 |
+ | 5 msec | 10.55 msec | 94.79 |
+ | 6 msec | 11.55 msec | 86.58 |
+ | 7 msec | 12.55 msec | 79.68 |
+ | 8 msec | 13.55 msec | 73.80 |
+ | 9 msec | 14.55 msec | 68.73 |
+ | 10 msec | 15.55 msec | 64.31 |
+ +---------------------+-----------------------+--------------+
+
+ Here is how you can read the table above:
+
+ - For a PoW function with a 1ms verification time, an attacker needs to send
+ 152 high-effort introduction cells per second to succeed in a
+ [ATTACK_BOTTOM_HALF] attack.
+
+ - For a PoW function with a 10ms verification time, an attacker needs to send
+ 64 high-effort introduction cells per second to succeed in a
+ [ATTACK_BOTTOM_HALF] attack.
+
+ We can use this table to specify a default difficulty that won't allow our
+ target adversary to succeed in an [ATTACK_BOTTOM_HALF] attack.
+
+ Of course, when it comes to this table, the same disclaimer as in section
+ [POW_TUNING_VERIFICATION] is valid. That is, the above table is just a
+ theoretical extrapolation and we expect the real values to be much lower
+ since they depend on auxiliary processing overheads, and on the network's
+ capacity.
+
+6.3. Tuning equix difficulty [EQUIX_DIFFICULTY]
+
+ The above two sections were not depending on a particular PoW scheme. They
+ gave us an intuition on the values we are aiming for in terms of verification
+ speed and PoW difficulty. Now we need to make things concrete:
+
+ As described in section [EFFORT_ESTIMATION] we start the service with a
+ default suggested-effort value of 5000. Given the benchmarks of EquiX
+ [REF_EQUIX] this should take about 2 to 3 seconds on a modern CPU.
+
+ With this default difficulty setting and given the table in
+ [POW_DIFFICULTY_ANALYSIS] this means that an attacker with 50 boxes will be
+ able to get about 20 successful PoWs per second, and an attacker with 100
+ boxes about 40 successful PoWs per second.
+
+ Then using the table in [POW_DIFFICULTY_TOR] we can see that the number of
+ attacker's successes is not enough to overwhelm the service through an
+ [ATTACK_BOTTOM_HALF] attack. That is, an attacker would need to do about 152
+ introductions per second to overwhelm the service, whereas they can only do
+ 40 with 100 boxes.
+
+7. Discussion
+
+7.1. UX
+
+ This proposal has user facing UX consequences.
+
+ Here is some UX improvements that don't need user-input:
+
+ - Primarily, there should be a way for Tor Browser to display to users that
+ additional time (and resources) will be needed to access a service that is
+ under attack. Depending on the design of the system, it might even be
+ possible to estimate how much time it will take.
+
+ And here are a few UX approaches that will need user-input and have an
+ increasing engineering difficulty. Ideally this proposal will not need
+ user-input and the default behavior should work for almost all cases.
+
+ a) Tor Browser needs a "range field" which the user can use to specify how
+ much effort they want to spend in PoW if this ever occurs while they are
+ browsing. The ranges could be from "Easy" to "Difficult", or we could try
+ to estimate time using an average computer. This setting is in the Tor
+ Browser settings and users need to find it.
+
+ b) We start with a default effort setting, and then we use the new onion
+ errors (see #19251) to estimate when an onion service connection has
+ failed because of DoS, and only then we present the user a "range field"
+ which they can set dynamically. Detecting when an onion service connection
+ has failed because of DoS can be hard because of the lack of feedback (see
+ [CLIENT_BEHAVIOR])
+
+ c) We start with a default effort setting, and if things fail we
+ automatically try to figure out an effort setting that will work for the
+ user by doing some trial-and-error connections with different effort
+ values. Until the connection succeeds we present a "Service is
+ overwhelmed, please wait" message to the user.
+
+7.2. Future work [FUTURE_WORK]
+
+7.2.1. Incremental improvements to this proposal
+
+ There are various improvements that can be done in this proposal, and while
+ we are trying to keep this v1 version simple, we need to keep the design
+ extensible so that we build more features into it. In particular:
+
+ - End-to-end introduction ACKs
+
+ This proposal suffers from various UX issues because there is no end-to-end
+ mechanism for an onion service to inform the client about its introduction
+ request. If we had end-to-end introduction ACKs many of the problems from
+ [CLIENT_BEHAVIOR] would be aleviated. The problem here is that end-to-end
+ ACKs require modifications on the introduction point code and a network
+ update which is a lengthy process.
+
+ - Multithreading scheduler
+
+ Our scheduler is pretty limited by the fact that Tor has a single-threaded
+ design. If we improve our multithreading support we could handle a much
+ greater amount of introduction requests per second.
+
+7.2.2. Future designs [FUTURE_DESIGNS]
+
+ This is just the beginning in DoS defences for Tor and there are various
+ futured designs and schemes that we can investigate. Here is a brief summary
+ of these:
+
+ "More advanced PoW schemes" -- We could use more advanced memory-hard PoW
+ schemes like MTP-argon2 or Itsuku to make it even harder for
+ adversaries to create successful PoWs. Unfortunately these schemes
+ have much bigger proof sizes, and they won't fit in INTRODUCE1 cells.
+ See #31223 for more details.
+
+ "Third-party anonymous credentials" -- We can use anonymous credentials and a
+ third-party token issuance server on the clearnet to issue tokens
+ based on PoW or CAPTCHA and then use those tokens to get access to the
+ service. See [REF_CREDS] for more details.
+
+ "PoW + Anonymous Credentials" -- We can make a hybrid of the above ideas
+ where we present a hard puzzle to the user when connecting to the
+ onion service, and if they solve it we then give the user a bunch of
+ anonymous tokens that can be used in the future. This can all happen
+ between the client and the service without a need for a third party.
+
+ All of the above approaches are much more complicated than this proposal, and
+ hence we want to start easy before we get into more serious projects.
+
+7.3. Environment
+
+ We love the environment! We are concerned of how PoW schemes can waste energy
+ by doing useless hash iterations. Here is a few reasons we still decided to
+ pursue a PoW approach here:
+
+ "We are not making things worse" -- DoS attacks are already happening and
+ attackers are already burning energy to carry them out both on the
+ attacker side, on the service side and on the network side. We think that
+ asking legitimate clients to carry out PoW computations is not gonna
+ affect the equation too much, since an attacker right now can very
+ quickly cause the same damage that hundreds of legitimate clients do a
+ whole day.
+
+ "We hope to make things better" -- The hope is that proposals like this will
+ make the DoS actors go away and hence the PoW system will not be used. As
+ long as DoS is happening there will be a waste of energy, but if we
+ manage to demotivate them with technical means, the network as a whole
+ will less wasteful. Also see [CATCH22] for a similar argument.
+
+8. Acknowledgements
+
+ Thanks a lot to tevador for the various improvements to the proposal and for
+ helping us understand and tweak the RandomX scheme.
+
+ Thanks to Solar Designer for the help in understanding the current PoW
+ landscape, the various approaches we could take, and teaching us a few neat
+ tricks.
+
+Appendix A. Little-t tor introduction scheduler
+
+ This section describes how we will implement this proposal in the "tor"
+ software (little-t tor).
+
+ The following should be read as if tor is an onion service and thus the end
+ point of all inbound data.
+
+A.1. The Main Loop [MAIN_LOOP]
+
+ Tor uses libevent for its mainloop. For network I/O operations, a mainloop
+ event is used to inform tor if it can read on a certain socket, or a
+ connection object in tor.
+
+ From there, this event will empty the connection input buffer (inbuf) by
+ extracting and processing a cell at a time. The mainloop is single threaded
+ and thus each cell is handled sequentially.
+
+ Processing an INTRODUCE2 cell at the onion service means a series of
+ operations (in order):
+
+ 1) Unpack cell from inbuf to local buffer.
+
+ 2) Decrypt cell (AES operations).
+
+ 3) Parse cell header and process it depending on its RELAY_COMMAND.
+
+ 4) INTRODUCE2 cell handling which means building a rendezvous circuit:
+ i) Path selection
+ ii) Launch circuit to first hop.
+
+ 5) Return to mainloop event which essentially means back to step (1).
+
+ Tor will read at most 32 cells out of the inbuf per mainloop round.
+
+A.2. Requirements for PoW
+
+ With this proposal, in order to prioritize cells by the amount of PoW work
+ it has done, cells can _not_ be processed sequentially as described above.
+
+ Thus, we need a way to queue a certain number of cells, prioritize them and
+ then process some cell(s) from the top of the queue (that is, the cells that
+ have done the most PoW effort).
+
+ We thus require a new cell processing flow that is _not_ compatible with
+ current tor design. The elements are:
+
+ - Validate PoW and place cells in a priority queue of INTRODUCE2 cells (as
+ described in section [INTRO_QUEUE]).
+
+ - Defer "bottom half" INTRO2 cell processing for after cells have been
+ queued into the priority queue.
+
+A.3. Proposed scheduler [TOR_SCHEDULER]
+
+ The intuitive way to address the A.2 requirements would be to do this
+ simple and naive approach:
+
+ 1) Mainloop: Empty inbuf INTRODUCE2 cells into priority queue
+
+ 2) Process all cells in pqueue
+
+ 3) Goto (1)
+
+ However, we are worried that handling all those cells before returning to the
+ mainloop opens possibilities of attack by an adversary since the priority
+ queue is not gonna be kept up to date while we process all those cells. This
+ means that we might spend lots of time dealing with introductions that don't
+ deserve it. See [BOTTOM_HALF_SCHEDULER] for more details.
+
+ We thus propose to split the INTRODUCE2 handling into two different steps:
+ "top half" and "bottom half" process, as also mentioned in [POW_VERIFY]
+ section above.
+
+A.3.1. Top half and bottom half scheduler
+
+ The top half process is responsible for queuing introductions into the
+ priority queue as follows:
+
+ a) Unpack cell from inbuf to local buffer.
+
+ b) Decrypt cell (AES operations).
+
+ c) Parse INTRODUCE2 cell header and validate PoW.
+
+ d) Return to mainloop event which essentially means step (1).
+
+ The top-half basically does all operations of section [MAIN_LOOP] except from (4).
+
+ An then, the bottom-half process is responsible for handling introductions
+ and doing rendezvous. To achieve this we introduce a new mainloop event to
+ process the priority queue _after_ the top-half event has completed. This new
+ event would do these operations sequentially:
+
+ a) Pop INTRODUCE2 cell from priority queue.
+
+ b) Parse and process INTRODUCE2 cell.
+
+ c) End event and yield back to mainloop.
+
+A.3.2. Scheduling the bottom half process [BOTTOM_HALF_SCHEDULER]
+
+ The question now becomes: when should the "bottom half" event get triggered
+ from the mainloop?
+
+ We propose that this event is scheduled in when the network I/O event
+ queues at least 1 cell into the priority queue. Then, as long as it has a
+ cell in the queue, it would re-schedule itself for immediate execution
+ meaning at the next mainloop round, it would execute again.
+
+ The idea is to try to empty the queue as fast as it can in order to provide a
+ fast response time to an introduction request but always leave a chance for
+ more cells to appear between cell processing by yielding back to the
+ mainloop. With this we are aiming to always have the most up-to-date version
+ of the priority queue when we are completing introductions: this way we are
+ prioritizing clients that spent a lot of time and effort completing their PoW.
+
+ If the size of the queue drops to 0, it stops scheduling itself in order to
+ not create a busy loop. The network I/O event will re-schedule it in time.
+
+ Notice that the proposed solution will make the service handle 1 single
+ introduction request at every main loop event. However, when we do
+ performance measurements we might learn that it's preferable to bump the
+ number of cells in the future from 1 to N where N <= 32.
+
+A.4 Performance measurements
+
+ This section will detail the performance measurements we've done on tor.git
+ for handling an INTRODUCE2 cell and then a discussion on how much more CPU
+ time we can add (for PoW validation) before it badly degrades our
+ performance.
+
+A.4.1 Tor measurements [TOR_MEASUREMENTS]
+
+ In this section we will derive measurement numbers for the "top half" and
+ "bottom half" parts of handling an introduction cell.
+
+ These measurements have been done on tor.git at commit
+ 80031db32abebaf4d0a91c01db258fcdbd54a471.
+
+ We've measured several set of actions of the INTRODUCE2 cell handling process
+ on Intel(R) Xeon(R) CPU E5-2650 v4. Our service was accessed by an array of
+ clients that sent introduction requests for a period of 60 seconds.
+
+ 1. Full Mainloop Event
+
+ We start by measuring the full time it takes for a mainloop event to
+ process an inbuf containing INTRODUCE2 cells. The mainloop event processed
+ 2.42 cells per invocation on average during our measurements.
+
+ Total measurements: 3279
+
+ Min: 0.30 msec - 1st Q.: 5.47 msec - Median: 5.91 msec
+ Mean: 13.43 msec - 3rd Q.: 16.20 msec - Max: 257.95 msec
+
+ 2. INTRODUCE2 cell processing (bottom-half)
+
+ We also measured how much time the "bottom half" part of the process
+ takes. That's the heavy part of processing an introduction request as seen
+ in step (4) of the [MAIN_LOOP] section:
+
+ Total measurements: 7931
+
+ Min: 0.28 msec - 1st Q.: 5.06 msec - Median: 5.33 msec
+ Mean: 5.29 msec - 3rd Q.: 5.57 msec - Max: 14.64 msec
+
+ 3. Connection data read (top half)
+
+ Now that we have the above pieces, we can use them to measure just the
+ "top half" part of the procedure. That's when bytes are taken from the
+ connection inbound buffer and parsed into an INTRODUCE2 cell where basic
+ validation is done.
+
+ There is an average of 2.42 INTRODUCE2 cells per mainloop event and so we
+ divide that by the full mainloop event mean time to get the time for one
+ cell. From that we substract the "bottom half" mean time to get how much
+ the "top half" takes:
+
+ => 13.43 / (7931 / 3279) = 5.55
+ => 5.55 - 5.29 = 0.26
+
+ Mean: 0.26 msec
+
+ To summarize, during our measurements the average number of INTRODUCE2 cells
+ a mainloop event processed is ~2.42 cells (7931 cells for 3279 mainloop
+ invocations).
+
+ This means that, taking the mean of mainloop event times, it takes ~5.55msec
+ (13.43/2.42) to completely process an INTRODUCE2 cell. Then if we look deeper
+ we see that the "top half" of INTRODUCE2 cell processing takes 0.26 msec in
+ average, whereas the "bottom half" takes around 5.33 msec.
+
+ The heavyness of the "bottom half" is to be expected since that's where 95%
+ of the total work takes place: in particular the rendezvous path selection
+ and circuit launch.
+
+A.2. References
+
+ [REF_EQUIX]: https://github.com/tevador/equix
+ https://github.com/tevador/equix/blob/master/devlog.md
+ [REF_TABLE]: The table is based on the script below plus some manual editing for readability:
+ https://gist.github.com/asn-d6/99a936b0467b0cef88a677baaf0bbd04
+ [REF_BOTNET]: https://media.kasperskycontenthub.com/wp-content/uploads/sites/43/2009/07/01121538/ynam_botnets_0907_en.pdf
+ [REF_CREDS]: https://lists.torproject.org/pipermail/tor-dev/2020-March/014198.html
+ [REF_TARGET]: https://en.bitcoin.it/wiki/Target
+ [REF_TLS]: https://www.ietf.org/archive/id/draft-nygren-tls-client-puzzles-02.txt
+ https://tools.ietf.org/id/draft-nir-tls-puzzles-00.html
+ https://tools.ietf.org/html/draft-ietf-ipsecme-ddos-protection-10
+ [REF_TLS_1]: https://www.ietf.org/archive/id/draft-nygren-tls-client-puzzles-02.txt
+ [REF_TEVADOR_1]: https://lists.torproject.org/pipermail/tor-dev/2020-May/014268.html
+ [REF_TEVADOR_2]: https://lists.torproject.org/pipermail/tor-dev/2020-June/014358.html
+ [REF_TEVADOR_SIM]: https://github.com/tevador/scratchpad/blob/master/tor-pow/effort_sim.md
diff --git a/proposals/BY_INDEX.md b/proposals/BY_INDEX.md
index 6bd1ba9..7c604fa 100644
--- a/proposals/BY_INDEX.md
+++ b/proposals/BY_INDEX.md
@@ -233,7 +233,7 @@ Below are a list of proposals sorted by their proposal number. See
* [`313-relay-ipv6-stats.txt`](/proposals/313-relay-ipv6-stats.txt): Tor Relay IPv6 Statistics [ACCEPTED]
* [`314-allow-markdown-proposals.md`](/proposals/314-allow-markdown-proposals.md): Allow Markdown for proposal format [FINISHED]
* [`315-update-dir-required-fields.txt`](/proposals/315-update-dir-required-fields.txt): Updating the list of fields required in directory documents [OPEN]
-* [`316-flashflow.txt`](/proposals/316-flashflow.txt): FlashFlow: A Secure Speed Test for Tor (Parent Proposal) [DRAFT]
+* [`316-flashflow.md`](/proposals/316-flashflow.md): FlashFlow: A Secure Speed Test for Tor (Parent Proposal) [DRAFT]
* [`317-secure-dns-name-resolution.txt`](/proposals/317-secure-dns-name-resolution.txt): Improve security aspects of DNS name resolution [NEEDS-REVISION]
* [`318-limit-protovers.md`](/proposals/318-limit-protovers.md): Limit protover values to 0-63 [ACCEPTED]
* [`319-wide-everything.md`](/proposals/319-wide-everything.md): RELAY_FRAGMENT cells [OPEN]
@@ -243,4 +243,6 @@ Below are a list of proposals sorted by their proposal number. See
* [`323-walking-onions-full.md`](/proposals/323-walking-onions-full.md): Specification for Walking Onions [OPEN]
* [`324-rtt-congestion-control.txt`](/proposals/324-rtt-congestion-control.txt): RTT-based Congestion Control for Tor [OPEN]
* [`325-packed-relay-cells.md`](/proposals/325-packed-relay-cells.md): Packed relay cells: saving space on small commands [OPEN]
+* [`326-tor-relay-well-known-uri-rfc8615.md`](/proposals/326-tor-relay-well-known-uri-rfc8615.md): The "tor-relay" Well-Known Resource Identifier [OPEN]
+* [`327-pow-over-intro.txt`](/proposals/327-pow-over-intro.txt): A First Take at PoW Over Introduction Circuits [DRAFT]
diff --git a/proposals/README.md b/proposals/README.md
index 695982c..6d302ec 100644
--- a/proposals/README.md
+++ b/proposals/README.md
@@ -38,6 +38,7 @@ for discussion.
* [`323-walking-onions-full.md`](/proposals/323-walking-onions-full.md): Specification for Walking Onions
* [`324-rtt-congestion-control.txt`](/proposals/324-rtt-congestion-control.txt): RTT-based Congestion Control for Tor
* [`325-packed-relay-cells.md`](/proposals/325-packed-relay-cells.md): Packed relay cells: saving space on small commands
+* [`326-tor-relay-well-known-uri-rfc8615.md`](/proposals/326-tor-relay-well-known-uri-rfc8615.md): The "tor-relay" Well-Known Resource Identifier
## ACCEPTED proposals: slated for implementation
@@ -106,7 +107,8 @@ discussion.
* [`273-exit-relay-pinning.txt`](/proposals/273-exit-relay-pinning.txt): Exit relay pinning for web services
* [`294-tls-1.3.txt`](/proposals/294-tls-1.3.txt): TLS 1.3 Migration
-* [`316-flashflow.txt`](/proposals/316-flashflow.txt): FlashFlow: A Secure Speed Test for Tor (Parent Proposal)
+* [`316-flashflow.md`](/proposals/316-flashflow.md): FlashFlow: A Secure Speed Test for Tor (Parent Proposal)
+* [`327-pow-over-intro.txt`](/proposals/327-pow-over-intro.txt): A First Take at PoW Over Introduction Circuits
## NEEDS-REVISION proposals: ideas that we can't implement as-is
diff --git a/pt-spec.txt b/pt-spec.txt
index bd4aec6..e43a3f7 100644
--- a/pt-spec.txt
+++ b/pt-spec.txt
@@ -217,6 +217,41 @@ Table of Contents
TOR_PT_EXIT_ON_STDIN_CLOSE=1
+ "TOR_PT_OUTBOUND_BIND_ADDRESS_V4"
+
+ Specifies an IPv4 IP address that the PT proxy SHOULD use as source address for
+ outgoing IPv4 IP packets. This feature allows people with multiple network
+ interfaces to specify explicitly which interface they prefer the PT proxy to
+ use.
+
+ If this value is unset or empty, the PT proxy MUST use the default source
+ address for outgoing connections.
+
+ This setting MUST be ignored for connections to
+ loopback addresses (127.0.0.0/8).
+
+ Example:
+
+ TOR_PT_OUTBOUND_BIND_ADDRESS_V4=203.0.113.4
+
+ "TOR_PT_OUTBOUND_BIND_ADDRESS_V6"
+
+ Specifies an IPv6 IP address that the PT proxy SHOULD use as source address for
+ outgoing IPv6 IP packets. This feature allows people with multiple network
+ interfaces to specify explicitly which interface they prefer the PT proxy to
+ use.
+
+ If this value is unset or empty, the PT proxy MUST use the default source
+ address for outgoing connections.
+
+ This setting MUST be ignored for connections to the loopback address ([::1]).
+
+ IPv6 addresses MUST always be wrapped in square brackets.
+
+ Example::
+
+ TOR_PT_OUTBOUND_BIND_ADDRESS_V6=[2001:db8::4]
+
3.2.2. Pluggable Transport Client Environment Variables
Client-side Pluggable Transport forward proxies are configured
diff --git a/tor-spec.txt b/tor-spec.txt
index af16fa4..11a991a 100644
--- a/tor-spec.txt
+++ b/tor-spec.txt
@@ -506,9 +506,11 @@ see tor-design.pdf.
Padding bytes SHOULD be set to NUL.
We recommend random padding in RELAY/RELAY_EARLY cells, so that the cell
- content is unpredictable. See proposal 289 for details. For other
- cells, TLS authenticates cell content, so randomised padding bytes are
- redundant.
+ content is unpredictable. See the format of relay cells in section 6.1
+ for detail.
+
+ For other cells, TLS authenticates cell content, so randomized padding
+ bytes are redundant.
Receivers MUST ignore padding bytes.
@@ -1030,6 +1032,10 @@ see tor-design.pdf.
Nodes MUST ignore unrecognized specifiers, and MUST accept multiple
instances of specifiers other than 'legacy identity'.
+ For purposes of indistinguishability, implementations SHOULD send
+ these link specifiers, if using them, in this order: [00], [02], [03],
+ [01].
+
The relay payload for an EXTEND relay cell consists of:
Address [4 bytes]
@@ -1574,7 +1580,8 @@ see tor-design.pdf.
StreamID [2 bytes]
Digest [4 bytes]
Length [2 bytes]
- Data [PAYLOAD_LEN-11 bytes]
+ Data [Length bytes]
+ Padding [PAYLOAD_LEN - 11 - Length bytes]
The relay commands are:
@@ -1645,6 +1652,14 @@ see tor-design.pdf.
handle padding bytes of unencrypted relay cells as they do padding
bytes for other cell types; see Section 3.
+ The 'Padding' field is used to make relay cell contents unpredictable, to
+ avoid certain attacks (see proposal 289 for rationale). Implementations
+ SHOULD fill this field with four zero-valued bytes, followed by as many
+ random bytes as will fit. (If there are fewer than 4 bytes for padding,
+ then they should all be filled with zero.
+
+ Implementations MUST NOT rely on the contents of the 'Padding' field.
+
If the RELAY cell is recognized but the relay command is not
understood, the cell must be dropped and ignored. Its contents
still count with respect to the digests and flow control windows, though.
@@ -1686,7 +1701,7 @@ see tor-design.pdf.
Upon receiving this cell, the exit node resolves the address as
necessary, and opens a new TCP connection to the target port. If the
address cannot be resolved, or a connection can't be established, the
- exit node replies with a RELAY_END cell. (See 6.4 below.)
+ exit node replies with a RELAY_END cell. (See 6.3 below.)
Otherwise, the exit node replies with a RELAY_CONNECTED cell, whose
payload is in one of the following formats:
@@ -1787,9 +1802,16 @@ see tor-design.pdf.
14 -- REASON_NOTDIRECTORY (Client sent RELAY_BEGIN_DIR to a
non-directory relay.)
- (With REASON_EXITPOLICY, the 4-byte IPv4 address or 16-byte IPv6 address
- forms the optional data, along with a 4-byte TTL; no other reason
- currently has extra data.)
+
+ For most reasons, the format is:
+
+ Reason [1 byte]
+
+ For REASON_EXITPOLICY, the format is:
+
+ Reason [1 byte]
+ IPv4 or IPv6 address [4 bytes or 16 bytes]
+ TTL [4 bytes]
OPs and ORs MUST accept reasons not on the above list, since future
versions of Tor may provide more fine-grained reasons.