aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--.gitlab-ci.yml31
-rw-r--r--attic/text_formats/param-spec.txt87
-rwxr-xr-xbin/build_html81
-rw-r--r--bin/ci-puppeteer-config.json3
-rwxr-xr-xbin/mermaid-cli-in-ci52
-rwxr-xr-xbin/mermaid_cvt_svg25
-rw-r--r--bin/puppeteer-cache-expect-listings289
-rwxr-xr-xbin/reindex2
-rwxr-xr-xbin/via-yarn-install-in-ci59
-rw-r--r--mdbook/proposals/book.toml12
-rw-r--r--mdbook/proposals/mermaid-init.js1
-rw-r--r--mdbook/spec/book.toml16
-rw-r--r--mdbook/spec/mermaid-init.js1
-rw-r--r--proposals/000-index.txt4
-rw-r--r--proposals/316-flashflow.md93
-rw-r--r--proposals/323-walking-onions-full.md39
-rw-r--r--proposals/325-packed-relay-cells.md56
-rw-r--r--proposals/326-tor-relay-well-known-uri-rfc8615.md6
-rw-r--r--proposals/327-pow-over-intro.txt4
-rw-r--r--proposals/328-relay-overload-report.md10
-rw-r--r--proposals/331-res-tokens-for-anti-dos.md53
-rw-r--r--proposals/332-ntor-v3-with-extra-data.md4
-rw-r--r--proposals/339-udp-over-tor.md2
-rw-r--r--proposals/340-packed-and-fragmented.md8
-rw-r--r--proposals/BY_INDEX.md504
-rw-r--r--proposals/BY_STATUS.md102
-rw-r--r--proposals/README.md4
-rw-r--r--proposals/SUMMARY.md2
-rw-r--r--spec/STYLE.md2
-rw-r--r--spec/SUMMARY.md10
-rw-r--r--spec/back-matter.md10
-rw-r--r--spec/dos-spec/index.md7
-rw-r--r--spec/dos-spec/memory-exhaustion.md (renamed from spec/dos-spec.md)26
-rw-r--r--spec/dos-spec/overview.md78
-rw-r--r--spec/guard-spec/algorithm.md37
-rw-r--r--spec/hspow-spec/analysis-discussion.md416
-rw-r--r--spec/hspow-spec/common-protocol.md203
-rw-r--r--spec/hspow-spec/index.md5
-rw-r--r--spec/hspow-spec/motivation.md85
-rw-r--r--spec/hspow-spec/v1-equix.md176
-rw-r--r--spec/param-spec.md86
-rw-r--r--spec/rend-spec/hsdesc-encrypt.md31
-rw-r--r--spec/rend-spec/introduction-protocol.md61
-rw-r--r--spec/rend-spec/revision-counter-mgt.md103
-rw-r--r--spec/tor-spec/create-created-cells.md25
-rw-r--r--spec/tor-spec/flow-control.md4
-rw-r--r--spec/tor-spec/negotiating-channels.md68
-rw-r--r--spec/tor-spec/relay-cells.md20
-rw-r--r--spec/tor-spec/resource-exhaustion.md31
-rw-r--r--spec/tor-spec/routing-relay-cells.md2
-rw-r--r--spec/tor-spec/subprotocol-versioning.md47
52 files changed, 2397 insertions, 691 deletions
diff --git a/.gitignore b/.gitignore
index 2f9bd0f..905198f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,7 +12,10 @@
# OS X folder cruft
.DS_Store
-# mdbook outputs
+# mdbook build dir
+/build
+
+# generated html (reorganized from the build dir)
/html
# bin/check_links output
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index bb2dec4..ddd399d 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -4,9 +4,26 @@ variables:
build:
image: rust:bookworm
+ rules:
+ # We install mermaid-cli only when we are building for the
+ # actual website, since it is pretty expensive. If we switch to
+ # faster install tool, we should revisit that.
+ - if: '$CI_PROJECT_ROOT_NAMESPACE == "tpo" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
+ variables:
+ MMDC: mmdc -p bin/ci-puppeteer-config.json
+ # ^ See note
+ # But we _do_ want to build unconditionally.
+ - when: always
script:
- - ./bin/via-cargo-install-in-ci mdbook
+ - env
- apt-get update && apt-get install -y git python3 python3-yaml
+ - ./bin/via-cargo-install-in-ci mdbook mdbook-linkcheck
+ - |
+ if test "$MMDC" != "" ; then
+ ./bin/mermaid-cli-in-ci
+ else
+ ./bin/via-cargo-install-in-ci mdbook-mermaid
+ fi
- ./bin/check_index
- ./bin/build_html
- mv html public
@@ -17,11 +34,19 @@ build:
paths:
- cache
+# Note re MMDC above:
+# https://github.com/mermaid-js/mermaid-cli/blob/HEAD/docs/linux-sandbox-issue.md
+#
+# bin/ is the wrong place for that file
+# but I don't want to rename all of bin/ to maint/ right now.
+
link-check:
image: rust:bookworm
+ rules:
+ - when: always
script:
- - ./bin/via-cargo-install-in-ci mdbook
- apt-get update && apt-get install -y git python3 python3-yaml linklint
+ - ./bin/via-cargo-install-in-ci mdbook mdbook-linkcheck
- ./bin/build_html
- ./bin/check_links
artifacts:
@@ -43,4 +68,4 @@ include:
# request.
pages:
rules:
- - if: '$CI_PROJECT_ROOT_NAMESPACE != "tpo" && $CI_PIPELINE_SOURCE == "merge_request"'
+ - if: '$CI_PROJECT_ROOT_NAMESPACE != "tpo" && $CI_PIPELINE_SOURCE == "merge_request_event"'
diff --git a/attic/text_formats/param-spec.txt b/attic/text_formats/param-spec.txt
index d8ea80b..af2da8c 100644
--- a/attic/text_formats/param-spec.txt
+++ b/attic/text_formats/param-spec.txt
@@ -1,4 +1,3 @@
-
Tor network parameters
This file lists the recognized parameters that can appear on the "params"
@@ -368,27 +367,75 @@ Table of Contents
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
+ "circpad_global_allowed_cells" -- This is the number of padding cells
+ that must be sent before the 'circpad_global_max_padding_percent'
+ parameter is applied.
+ Min: 0. Max: 65535. Default: 0
+
+ "circpad_global_max_padding_pct" -- This is the maximum ratio of
+ padding cells to total cells, specified as a percent. If the global
+ ratio of padding cells to total cells across all circuits exceeds
+ this percent value, no more padding is sent until the ratio becomes
+ lower. 0 means no limit.
+ Min: 0. Max: 100. Default: 0
+
+ "circpad_padding_disabled" -- If set to 1, no circuit padding machines
+ will negotiate, and all current padding machines will cease padding
+ immediately.
+ Min: 0. Max: 1. Default: 0
- "nf_pad_before_usage" -- DOCDOC
+ "circpad_padding_reduced" -- If set to 1, only circuit padding
+ machines marked as "reduced"/"low overhead" will be used.
+ (Currently no such machines are marked as "reduced overhead").
+ Min: 0. Max: 1. Default: 0
- "nf_pad_relays" -- DOCDOC
+ "nf_conntimeout_clients"
+ - The number of seconds to keep never-used circuits opened and
+ available for clients to use. Note that the actual client timeout is
+ randomized uniformly from this value to twice this value.
+ - The number of seconds to keep idle (not currently used) canonical
+ channels are open and available. (We do this to ensure a sufficient
+ time duration of padding, which is the ultimate goal.)
+ - This value is also used to determine how long, after a port has been
+ used, we should attempt to keep building predicted circuits for that
+ port. (See path-spec.txt section 2.1.1.) This behavior was
+ originally added to work around implementation limitations, but it
+ serves as a reasonable default regardless of implementation.
+ - For all use cases, reduced padding clients use half the consensus
+ value.
+ - Implementations MAY mark circuits held open past the reduced padding
+ quantity (half the consensus value) as "not to be used for streams",
+ to prevent their use from becoming a distinguisher.
+ Min: 60. Max: 86400. Default: 1800
+
+ "nf_conntimeout_relays" -- The number of seconds that idle
+ relay-to-relay connections are kept open.
+ Min: 60. Max: 604800. Default: 3600
+
+ "nf_ito_low" -- The low end of the range to send padding when
+ inactive, in ms.
+ Min: 0. Max: 60000. Default: 1500
+
+ "nf_ito_high" -- The high end of the range to send padding, in ms.
+ If nf_ito_low == nf_ito_high == 0, padding will be disabled.
+ Min: nf_ito_low. Max: 60000. Default: 9500
+
+ "nf_ito_low_reduced" -- For reduced padding clients: the low
+ end of the range to send padding when inactive, in ms.
+ Min: 0. Max: 60000. Default: 9000
+
+ "nf_ito_high_reduced" -- For reduced padding clients: the high
+ end of the range to send padding, in ms.
+ Min: nf_ito_low_reduced. Max: 60000. Default: 14000
+
+ "nf_pad_before_usage" -- If set to 1, OR connections are padded
+ before the client uses them for any application traffic. If 0,
+ OR connections are not padded until application data begins.
+ Min: 0. Max: 1. Default: 1
+
+ "nf_pad_relays" -- If set to 1, we also pad inactive
+ relay-to-relay connections.
+ Min: 0. Max: 1. Default: 0
"nf_pad_single_onion" -- DOCDOC
diff --git a/bin/build_html b/bin/build_html
index 026c525..069901e 100755
--- a/bin/build_html
+++ b/bin/build_html
@@ -10,8 +10,81 @@ cd "${TOPLEVEL}"
./bin/make_redirects
-cd "${TOPLEVEL}/mdbook/spec"
-$MDBOOK build
+# Now we deal with mermaid diagrams.
+#
+# This may require changes to the md files in {spec,proposals}
+# or to the mdbook.toml files in mdbook/*/.
+# We will make a copy of whatever we need to change,
+# and then make changes to that copy.
+#
+# When we are done with these changes, we will set some variables:
+# - MDBOOK_OUTPUT_DIR is "", or the location where we have put our raw mdbook output.
+# - MDBOOK_DIR is the parent directory of the possibly modified copies
+# of mdbook/{spec,proposals}.
+
+if test -n "${MMDC:-}" || command -v "mmdc" >&/dev/null; then
+ # CASE 1: mermaid-cli is installed.
+ #
+ # We will convert mermaid diagrams to svg. The mermaid_cvt_svg
+ # script does this with a temporary copy of our markdown directories,
+ # so as not to alter the original.
+ #
+ # (The conversion involves npm and a headless chrome browser,
+ # to it is understandable that not everybody would want to do it
+ # this way.)
+ echo "Using mermaid-cli to pre-render mermaid diagrams"
+
+ TMPDIR=$(mktemp -d "${TOPLEVEL}/tmp_mmdc.XXXXXXXX")
+ trap 'rm -rf "$TMPDIR"' 0
+ ./bin/mermaid_cvt_svg "$TMPDIR"
+ MDBOOK_OUTPUT_DIR="$TMPDIR/build"
+ MDBOOK_DIR="$TMPDIR/mdbook"
+elif test -n "${MDBOOK_MERMAID:-}" || command -v "mdbook-mermaid" >&/dev/null; then
+ # CASE 2: mdbook_mermaid is installed.
+ #
+ # We will make a temporary copy of the mdbook configuration directory
+ # only, and use mdbook-mermaid to alter that.
+ #
+ # This is much easier to run locally, but it requires that your
+ # browser has enough client-side javascript in order to run
+ # mermaid. It doesn't touch npm.
+ echo "Using mdbook-mermaid to set up dynamic rendering of mermaid diagrams"
+
+ MDBOOK_MERMAID=${MDBOOK_MERMAID:=mdbook-mermaid}
+ TMPDIR=$(mktemp -d "${TOPLEVEL}/tmp_mdbook_mermaid.XXXXXXXX")
+ trap 'rm -rf "$TMPDIR"' 0
+ cp -r ./mdbook/proposals ./mdbook/spec ./mdbook/theme "$TMPDIR"
+ mdbook-mermaid install "$TMPDIR/spec"
+ mdbook-mermaid install "$TMPDIR/proposals"
+ MDBOOK_OUTPUT_DIR=""
+ MDBOOK_DIR="$TMPDIR"
+else
+ # CASE 3: No mermaid support.
+ #
+ # In this case we run mdbook on our inputs unchanged.
+ # The mermaid blocks will render as code.
+ echo "No mermaid support found; mermaid diagrams will be unrendered"
+
+ MDBOOK_OUTPUT_DIR=""
+ MDBOOK_DIR="$TOPLEVEL/mdbook"
+fi
+
+# mdbook-linkcheck is a non-obvious dependency, and the mdbook output when it's
+# not found doesn't spell out how to install it.
+if ! command -v mdbook-linkcheck; then
+ echo 'ERROR: mdbook-linkcheck not found. You should probably install it with `cargo install mdbook-linkcheck`'
+ exit 1
+fi
+
+$MDBOOK build "${MDBOOK_DIR}/spec"
+$MDBOOK build "${MDBOOK_DIR}/proposals"
+
+if test -n "${MDBOOK_OUTPUT_DIR}"; then
+ rm -rf "${TOPLEVEL}/build"
+ mv "${MDBOOK_OUTPUT_DIR}" "${TOPLEVEL}/build"
+fi
+
+rm -rf "${TOPLEVEL}/html/"
+mv "${TOPLEVEL}/build/spec/html" "${TOPLEVEL}/html"
+mv "${TOPLEVEL}/build/proposals/html" "${TOPLEVEL}/html/proposals"
-cd "${TOPLEVEL}/mdbook/proposals"
-$MDBOOK build
diff --git a/bin/ci-puppeteer-config.json b/bin/ci-puppeteer-config.json
new file mode 100644
index 0000000..3201af7
--- /dev/null
+++ b/bin/ci-puppeteer-config.json
@@ -0,0 +1,3 @@
+{
+ "args": ["--no-sandbox"]
+}
diff --git a/bin/mermaid-cli-in-ci b/bin/mermaid-cli-in-ci
new file mode 100755
index 0000000..5d6d041
--- /dev/null
+++ b/bin/mermaid-cli-in-ci
@@ -0,0 +1,52 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+set -x
+
+# Bump this to "clear" the cache.
+# Actually, it just causes us to ignore previous cached results.
+cache_clear_token=2023-11-09c
+
+cache_dir=cache/"$CI_JOB_IMAGE","$cache_clear_token","puppeteer"
+local_dir="$HOME/.cache/puppeteer"
+
+if test -d "$cache_dir"; then
+ mkdir -p "$local_dir"/.
+ cp -a "$cache_dir"/. "$local_dir"/.
+fi
+
+./bin/via-yarn-install-in-ci mmdc https://github.com/mermaid-js/mermaid-cli \
+ bba0240ad87f6fbf44d8a24941e37f4bc2c8bf30
+
+(
+ cd "$local_dir"
+ find -printf '%y %p %l\n' | sort
+ find -type f | sort | xargs sha256sum --
+) >puppeteer-cache-got-listings
+
+# Empirically, the mermaid-cli locked install produced a very old
+# chromium today. So I suspect it's not fetching "latest", but a controlled
+# version. Nevertheless, we should check that what we got is actually
+# the same and hasn't been changed by Google (or something on the way).
+
+# Doing this now isn't ideal, because I don't actually know if
+# the mermaid-cli *install* process runs anything from here.
+# But I don't think it runs the main chrome binary, since at one point
+# in our tests we got as far as this and then the chrome binary
+# failed with due to a missing OS shared library.
+
+# This expected output listing shouldn't be in bin/ but the best way
+# to fix that would be to rename the whole bin directory to maint.
+diff -u bin/puppeteer-cache-expect-listings puppeteer-cache-got-listings
+
+if ! test -d "$cache_dir"; then
+ mkdir -p "$cache_dir"
+ cp -a "$local_dir"/. "$cache_dir"/.
+fi
+
+# This is the easiest way to get the shared libraries that chromium
+# depends on. Obviously, using the Debian package's dependencies
+# is totally wrong, but it works in practice, and we don't have a proper
+# dependency list from the binaries from the ad-hoc downloads.
+apt-get install -y chromium
diff --git a/bin/mermaid_cvt_svg b/bin/mermaid_cvt_svg
new file mode 100755
index 0000000..3198a00
--- /dev/null
+++ b/bin/mermaid_cvt_svg
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+
+set -e -u -o pipefail -x
+
+TOPLEVEL=$(realpath $(dirname "$0"))/..
+TMPDIR="$1"
+: ${MMDC:=mmdc}
+
+cd "$TOPLEVEL"
+
+# We make a mirror of the specs, since we will need to make changes to them.
+cp -rl spec proposals mdbook "$TMPDIR"
+
+# We use mermaid-cli to extract the mermaid from any file containing it,
+# and generate a new version that uses svg instead.
+for fname in $(find "$TMPDIR" -name "*.md") ; do
+ if grep '^```mermaid' $fname; then
+ ORIG="${fname%.md}.__orig.md"
+ mv $fname $ORIG
+ $MMDC -i $ORIG -o $fname
+ fi
+done
+
+
+
diff --git a/bin/puppeteer-cache-expect-listings b/bin/puppeteer-cache-expect-listings
new file mode 100644
index 0000000..a5d5783
--- /dev/null
+++ b/bin/puppeteer-cache-expect-listings
@@ -0,0 +1,289 @@
+d .
+d ./chrome
+d ./chrome/linux-1108766
+d ./chrome/linux-1108766/chrome-linux
+d ./chrome/linux-1108766/chrome-linux/ClearKeyCdm
+d ./chrome/linux-1108766/chrome-linux/ClearKeyCdm/_platform_specific
+d ./chrome/linux-1108766/chrome-linux/ClearKeyCdm/_platform_specific/linux_x64
+d ./chrome/linux-1108766/chrome-linux/MEIPreload
+d ./chrome/linux-1108766/chrome-linux/locales
+d ./chrome/linux-1108766/chrome-linux/resources
+d ./chrome/linux-1108766/chrome-linux/resources/inspector_overlay
+f ./chrome/linux-1108766/chrome-linux/ClearKeyCdm/_platform_specific/linux_x64/libclearkeycdm.so
+f ./chrome/linux-1108766/chrome-linux/MEIPreload/manifest.json
+f ./chrome/linux-1108766/chrome-linux/MEIPreload/preloaded_data.pb
+f ./chrome/linux-1108766/chrome-linux/chrome
+f ./chrome/linux-1108766/chrome-linux/chrome-wrapper
+f ./chrome/linux-1108766/chrome-linux/chrome_100_percent.pak
+f ./chrome/linux-1108766/chrome-linux/chrome_200_percent.pak
+f ./chrome/linux-1108766/chrome-linux/chrome_crashpad_handler
+f ./chrome/linux-1108766/chrome-linux/chrome_sandbox
+f ./chrome/linux-1108766/chrome-linux/icudtl.dat
+f ./chrome/linux-1108766/chrome-linux/libEGL.so
+f ./chrome/linux-1108766/chrome-linux/libGLESv2.so
+f ./chrome/linux-1108766/chrome-linux/libvk_swiftshader.so
+f ./chrome/linux-1108766/chrome-linux/libvulkan.so.1
+f ./chrome/linux-1108766/chrome-linux/locales/af.pak
+f ./chrome/linux-1108766/chrome-linux/locales/af.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/am.pak
+f ./chrome/linux-1108766/chrome-linux/locales/am.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/ar-XB.pak
+f ./chrome/linux-1108766/chrome-linux/locales/ar-XB.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/ar.pak
+f ./chrome/linux-1108766/chrome-linux/locales/ar.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/bg.pak
+f ./chrome/linux-1108766/chrome-linux/locales/bg.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/bn.pak
+f ./chrome/linux-1108766/chrome-linux/locales/bn.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/ca.pak
+f ./chrome/linux-1108766/chrome-linux/locales/ca.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/cs.pak
+f ./chrome/linux-1108766/chrome-linux/locales/cs.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/da.pak
+f ./chrome/linux-1108766/chrome-linux/locales/da.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/de.pak
+f ./chrome/linux-1108766/chrome-linux/locales/de.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/el.pak
+f ./chrome/linux-1108766/chrome-linux/locales/el.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/en-GB.pak
+f ./chrome/linux-1108766/chrome-linux/locales/en-GB.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/en-US.pak
+f ./chrome/linux-1108766/chrome-linux/locales/en-US.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/en-XA.pak
+f ./chrome/linux-1108766/chrome-linux/locales/en-XA.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/es-419.pak
+f ./chrome/linux-1108766/chrome-linux/locales/es-419.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/es.pak
+f ./chrome/linux-1108766/chrome-linux/locales/es.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/et.pak
+f ./chrome/linux-1108766/chrome-linux/locales/et.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/fa.pak
+f ./chrome/linux-1108766/chrome-linux/locales/fa.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/fi.pak
+f ./chrome/linux-1108766/chrome-linux/locales/fi.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/fil.pak
+f ./chrome/linux-1108766/chrome-linux/locales/fil.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/fr.pak
+f ./chrome/linux-1108766/chrome-linux/locales/fr.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/gu.pak
+f ./chrome/linux-1108766/chrome-linux/locales/gu.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/he.pak
+f ./chrome/linux-1108766/chrome-linux/locales/he.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/hi.pak
+f ./chrome/linux-1108766/chrome-linux/locales/hi.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/hr.pak
+f ./chrome/linux-1108766/chrome-linux/locales/hr.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/hu.pak
+f ./chrome/linux-1108766/chrome-linux/locales/hu.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/id.pak
+f ./chrome/linux-1108766/chrome-linux/locales/id.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/it.pak
+f ./chrome/linux-1108766/chrome-linux/locales/it.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/ja.pak
+f ./chrome/linux-1108766/chrome-linux/locales/ja.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/kn.pak
+f ./chrome/linux-1108766/chrome-linux/locales/kn.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/ko.pak
+f ./chrome/linux-1108766/chrome-linux/locales/ko.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/lt.pak
+f ./chrome/linux-1108766/chrome-linux/locales/lt.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/lv.pak
+f ./chrome/linux-1108766/chrome-linux/locales/lv.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/ml.pak
+f ./chrome/linux-1108766/chrome-linux/locales/ml.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/mr.pak
+f ./chrome/linux-1108766/chrome-linux/locales/mr.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/ms.pak
+f ./chrome/linux-1108766/chrome-linux/locales/ms.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/nb.pak
+f ./chrome/linux-1108766/chrome-linux/locales/nb.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/nl.pak
+f ./chrome/linux-1108766/chrome-linux/locales/nl.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/pl.pak
+f ./chrome/linux-1108766/chrome-linux/locales/pl.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/pt-BR.pak
+f ./chrome/linux-1108766/chrome-linux/locales/pt-BR.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/pt-PT.pak
+f ./chrome/linux-1108766/chrome-linux/locales/pt-PT.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/ro.pak
+f ./chrome/linux-1108766/chrome-linux/locales/ro.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/ru.pak
+f ./chrome/linux-1108766/chrome-linux/locales/ru.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/sk.pak
+f ./chrome/linux-1108766/chrome-linux/locales/sk.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/sl.pak
+f ./chrome/linux-1108766/chrome-linux/locales/sl.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/sr.pak
+f ./chrome/linux-1108766/chrome-linux/locales/sr.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/sv.pak
+f ./chrome/linux-1108766/chrome-linux/locales/sv.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/sw.pak
+f ./chrome/linux-1108766/chrome-linux/locales/sw.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/ta.pak
+f ./chrome/linux-1108766/chrome-linux/locales/ta.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/te.pak
+f ./chrome/linux-1108766/chrome-linux/locales/te.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/th.pak
+f ./chrome/linux-1108766/chrome-linux/locales/th.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/tr.pak
+f ./chrome/linux-1108766/chrome-linux/locales/tr.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/uk.pak
+f ./chrome/linux-1108766/chrome-linux/locales/uk.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/ur.pak
+f ./chrome/linux-1108766/chrome-linux/locales/ur.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/vi.pak
+f ./chrome/linux-1108766/chrome-linux/locales/vi.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/zh-CN.pak
+f ./chrome/linux-1108766/chrome-linux/locales/zh-CN.pak.info
+f ./chrome/linux-1108766/chrome-linux/locales/zh-TW.pak
+f ./chrome/linux-1108766/chrome-linux/locales/zh-TW.pak.info
+f ./chrome/linux-1108766/chrome-linux/nacl_helper
+f ./chrome/linux-1108766/chrome-linux/nacl_helper_bootstrap
+f ./chrome/linux-1108766/chrome-linux/nacl_irt_x86_64.nexe
+f ./chrome/linux-1108766/chrome-linux/product_logo_48.png
+f ./chrome/linux-1108766/chrome-linux/resources.pak
+f ./chrome/linux-1108766/chrome-linux/resources/inspector_overlay/inspector_overlay_resources.grd
+f ./chrome/linux-1108766/chrome-linux/resources/inspector_overlay/main.js
+f ./chrome/linux-1108766/chrome-linux/v8_context_snapshot.bin
+f ./chrome/linux-1108766/chrome-linux/vk_swiftshader_icd.json
+f ./chrome/linux-1108766/chrome-linux/xdg-mime
+f ./chrome/linux-1108766/chrome-linux/xdg-settings
+c0b731f77524b864f90bd6ba538880169a1ae2a8ece21a849a752e1c8809ef1d ./chrome/linux-1108766/chrome-linux/ClearKeyCdm/_platform_specific/linux_x64/libclearkeycdm.so
+44844cf3dde6e80087ae0e6bf0d9326d7ef7d23326d24ac83af0850be26923d2 ./chrome/linux-1108766/chrome-linux/MEIPreload/manifest.json
+c6070a157b4e28d16fbccbd233e93846ddb070c85e1a1bc64469b7a5f1424fad ./chrome/linux-1108766/chrome-linux/MEIPreload/preloaded_data.pb
+9fb6757b5c61b28cbdd23a6c17a9acc61da856f812c02dae0b5156c0ee168a48 ./chrome/linux-1108766/chrome-linux/chrome
+17b0432a26e628287789f1efa53056384a46b6265939e8bf819b1b6cf8472ada ./chrome/linux-1108766/chrome-linux/chrome-wrapper
+7ab09e1609f2dd97cfbfa8988c71575d6abbe329d9c5a0d555b75504d5c4b980 ./chrome/linux-1108766/chrome-linux/chrome_100_percent.pak
+2e3fe3b1da0944d3704d1593c73e6ce3e286f8733829138d60a49766b69c03ff ./chrome/linux-1108766/chrome-linux/chrome_200_percent.pak
+f429e74163d634d37253d07730adc7651ce68fa16ebf794c1640193f94156392 ./chrome/linux-1108766/chrome-linux/chrome_crashpad_handler
+c97779a42a6edebdb6e94ff4836b87444380e4fcb6df007f715cbc3b362231bb ./chrome/linux-1108766/chrome-linux/chrome_sandbox
+e185ba581543fe286f1640a579d6f2219c181d95fa76e64f66c5a706f308860a ./chrome/linux-1108766/chrome-linux/icudtl.dat
+1647b2a56c450d02dc735f334ee12a6e442e6b2f6dae5ff0f6e4b05efedc9465 ./chrome/linux-1108766/chrome-linux/libEGL.so
+2af932a8f93999a0a32b87be6002fe83ca0e4579fc8ddba72a1a150323c38b58 ./chrome/linux-1108766/chrome-linux/libGLESv2.so
+fd7894d32ccbaed94672b63e9ff76f970e995f193716271005c581a4a2f3c947 ./chrome/linux-1108766/chrome-linux/libvk_swiftshader.so
+a94387cd9baf120b97fce4dcf8569c1a83e99ce85dd41978291b7fff25541aad ./chrome/linux-1108766/chrome-linux/libvulkan.so.1
+323c7a7ca326e7ef582b7034d10f4e81deaf630722cf43d5466b1deb419ec801 ./chrome/linux-1108766/chrome-linux/locales/af.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/af.pak.info
+f087f1f2bb83c48016b647799190f0f7f172df2fb5577ae9597ec17071caab90 ./chrome/linux-1108766/chrome-linux/locales/am.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/am.pak.info
+5dae1653f48a41abe2869245fd4fbc8a8e415dbfa125942706a6ff039e9a7f0c ./chrome/linux-1108766/chrome-linux/locales/ar-XB.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/ar-XB.pak.info
+5e22492cd14f8d739d2b14c7c5b0c10ed4f8585b5dddb402f36652d2c990b170 ./chrome/linux-1108766/chrome-linux/locales/ar.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/ar.pak.info
+dde3b5d59f81d593045518a40be3d9236d3f66a678f5823e342f3f379056858f ./chrome/linux-1108766/chrome-linux/locales/bg.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/bg.pak.info
+afb37a07a9fae9cf5d278f0426c047334f24a08c5f52aac76f75f3bfc1957bf6 ./chrome/linux-1108766/chrome-linux/locales/bn.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/bn.pak.info
+628c2f24f00ef37ba42af1ecf74136b5620a4f304a1bba9358129ba52f1124b2 ./chrome/linux-1108766/chrome-linux/locales/ca.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/ca.pak.info
+b5e95d9d94bfdef932f6fcaadf828b000e2f5a3b6d4a7c3a1b8ff1e55f2809aa ./chrome/linux-1108766/chrome-linux/locales/cs.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/cs.pak.info
+e5ea8dc83b39971db4bc62616d90c574311ad111ef38269befeff04c76b5a3bb ./chrome/linux-1108766/chrome-linux/locales/da.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/da.pak.info
+6983d893c1005c5a91718870b24c9444164427b901dd788435fcc78357a140b2 ./chrome/linux-1108766/chrome-linux/locales/de.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/de.pak.info
+e20982ee140a95bd8d440b645b593faab16ddc5a3c41fe40ca3b77243bfbacf8 ./chrome/linux-1108766/chrome-linux/locales/el.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/el.pak.info
+0918c68b0c5cd09f0ef1e9cc984fecb8ce79c0d0a509cdac2b77f9c0c29ce143 ./chrome/linux-1108766/chrome-linux/locales/en-GB.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/en-GB.pak.info
+b090180d5cd6ebfc25cb245c44156a4b945b52f581725b4184b0e0e5d78ff381 ./chrome/linux-1108766/chrome-linux/locales/en-US.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/en-US.pak.info
+7376d5f7cdbb0763efff84f2d8fa546be589577af5291cc629387425ca4e207e ./chrome/linux-1108766/chrome-linux/locales/en-XA.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/en-XA.pak.info
+290017770c41c26844032b8a2a1b97f7674653083411e23c12b72cc9ed8f49ea ./chrome/linux-1108766/chrome-linux/locales/es-419.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/es-419.pak.info
+a6d11beb2cf80c222d1a62133a6243776d4c379c18392794027ec0e64489af1b ./chrome/linux-1108766/chrome-linux/locales/es.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/es.pak.info
+42a74c9af1d7eee8c912c0b06b0439b0082ac453bf247ab044a2dccf8abbe7a5 ./chrome/linux-1108766/chrome-linux/locales/et.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/et.pak.info
+5ac624214ee7eded46e70368653f42b15ede5348621d0a57e7e615a56d8c9c05 ./chrome/linux-1108766/chrome-linux/locales/fa.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/fa.pak.info
+13c852eb058b37b736df5d87a81ed5370404cdb0c9a5f35d64d6d6ca03eaf013 ./chrome/linux-1108766/chrome-linux/locales/fi.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/fi.pak.info
+34572afd7489460793ea95b65e4bd68cb2f70a4873f74f2230fc71865bd514fa ./chrome/linux-1108766/chrome-linux/locales/fil.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/fil.pak.info
+4f3760d38ae95943ff8f2b79aa7c7d41b4143cad9ac81fe34080fc0aff66838b ./chrome/linux-1108766/chrome-linux/locales/fr.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/fr.pak.info
+01732e407c1ef2ffb678f2e1d8ba47e64b4d7583ba6fc2e3cfa4d40e89b325d9 ./chrome/linux-1108766/chrome-linux/locales/gu.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/gu.pak.info
+c191ec5dfc7eee295fe784e529bdf87878dec24d9705ae87a23a0a7be2daf742 ./chrome/linux-1108766/chrome-linux/locales/he.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/he.pak.info
+518729e2d63e92b36b146a6017eda1f36d5a1b93c4733509a8d8ed30ad8a2abe ./chrome/linux-1108766/chrome-linux/locales/hi.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/hi.pak.info
+7faa324f5deb95621f19401bab3b616bc8f4fc99b1864d8dd02b53f64ff13972 ./chrome/linux-1108766/chrome-linux/locales/hr.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/hr.pak.info
+eb99d8d7345da980371850ee26d74b1f98bebf5227a3e2b42fc55621c4ecb826 ./chrome/linux-1108766/chrome-linux/locales/hu.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/hu.pak.info
+cd5f6af3d83e9b49b66057b5de4defef8c925c2eea29171d336846c4f1b8c0e2 ./chrome/linux-1108766/chrome-linux/locales/id.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/id.pak.info
+aba599aef83877ec43647f17381b5ea677b115573f829fee19b5e95a106d82d2 ./chrome/linux-1108766/chrome-linux/locales/it.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/it.pak.info
+77a6f638d6e20c57335b1a419abbd5419a45b996f20a8b247f8323f95d8b8a7d ./chrome/linux-1108766/chrome-linux/locales/ja.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/ja.pak.info
+4251e497322a09eb9d11fcdeb79eacbd1d5ca738824b6efa41c20742bf05e041 ./chrome/linux-1108766/chrome-linux/locales/kn.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/kn.pak.info
+9cbf60872e4853badc62264af46de01f3700049f72d40412b805c1f2f0fc1c1d ./chrome/linux-1108766/chrome-linux/locales/ko.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/ko.pak.info
+a54f4825d04fef04066c88e3a1cfe2e014551cbfb19d4de3df71e38b118aec54 ./chrome/linux-1108766/chrome-linux/locales/lt.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/lt.pak.info
+f23f05077da21b8c811b60181389c15fddffd41327c36fe0c6e7a691fa9433d2 ./chrome/linux-1108766/chrome-linux/locales/lv.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/lv.pak.info
+6b1f3aad63a2152ae7343c6c20fe4f77f1eeb973ba957893feece942ba88e54a ./chrome/linux-1108766/chrome-linux/locales/ml.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/ml.pak.info
+c55c1e54776346c536abd431e289c467a01ba963a93ee2ff1845a150b207c744 ./chrome/linux-1108766/chrome-linux/locales/mr.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/mr.pak.info
+2a7f4e67717d25e9ccc74d16cfb1bab5dd18eaf16d8771d80fe38b226ec2ad5a ./chrome/linux-1108766/chrome-linux/locales/ms.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/ms.pak.info
+2971e09f96b9249b74ad8be35d777516fe1e49ae8ee8099935a40280105ff759 ./chrome/linux-1108766/chrome-linux/locales/nb.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/nb.pak.info
+c6df365597b3dd966ba84e6cd0d7fc4027a520ff85b36a47da9ed61e2b3a994a ./chrome/linux-1108766/chrome-linux/locales/nl.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/nl.pak.info
+ce50ebb59577f58a81444d074bb3602badf7df026c8a778333870647e9b54b52 ./chrome/linux-1108766/chrome-linux/locales/pl.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/pl.pak.info
+30d3eae85ccb68a513f49981c5dd8b67d4a42ea4c330016cbe30e37ee38e0a1d ./chrome/linux-1108766/chrome-linux/locales/pt-BR.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/pt-BR.pak.info
+bdcfdb657a204904faef4c2f627954dab097702e1dfd2e3e15971bb4d959c843 ./chrome/linux-1108766/chrome-linux/locales/pt-PT.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/pt-PT.pak.info
+d67a006273ce46f0c5ba724efe2c1bdf7943e88a9d88c7563421c31d14ba42a9 ./chrome/linux-1108766/chrome-linux/locales/ro.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/ro.pak.info
+723a919b66af7e2c428e4724376237fce747a47a9a0128810132f9f0b07d64ba ./chrome/linux-1108766/chrome-linux/locales/ru.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/ru.pak.info
+de81e6beb671141293605e396ba0992cc040ad8d2b4a9a019f60a2e40c954562 ./chrome/linux-1108766/chrome-linux/locales/sk.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/sk.pak.info
+16eee255672f7803ae9b282ce9d3aab6a29797a8ce1c787f949ab208a1f35352 ./chrome/linux-1108766/chrome-linux/locales/sl.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/sl.pak.info
+01b9a0a613d1d7504e90f9a523a90102d245f999ee8ff93d284c4186e6c2f463 ./chrome/linux-1108766/chrome-linux/locales/sr.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/sr.pak.info
+b8f738b3b5f334230f7ac8849a4eef3d77862e54202728e0c5608426b4add140 ./chrome/linux-1108766/chrome-linux/locales/sv.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/sv.pak.info
+4d7a3154fa0dbafefb96ef1fff1f60563a16de55deccfd11f2c5d3f733e29d0a ./chrome/linux-1108766/chrome-linux/locales/sw.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/sw.pak.info
+2dde4957d13101ade6f393a88332f8fc774f0565c73ece361f2f1ad12be235a2 ./chrome/linux-1108766/chrome-linux/locales/ta.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/ta.pak.info
+331489c0918c2b105b1112cdd620eba4af78bc80284730ed0c5691685be622fe ./chrome/linux-1108766/chrome-linux/locales/te.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/te.pak.info
+e04402b90dd5bbae71b68f85c834247c46eead0bcf0ac1996f4cc191f204d0c0 ./chrome/linux-1108766/chrome-linux/locales/th.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/th.pak.info
+fef2df11ed39c4f0f1687d49ff60b97d07513e03f9ff56ebe09ef088d7918473 ./chrome/linux-1108766/chrome-linux/locales/tr.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/tr.pak.info
+7a90a56c50fdc2a9add8c2399c18cc97f4af00d6ad067990f5758158987af6f2 ./chrome/linux-1108766/chrome-linux/locales/uk.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/uk.pak.info
+599d28b9b15b4a7e49a6747899310b919a5a05c428e7fb8e62fd67498ce46cdb ./chrome/linux-1108766/chrome-linux/locales/ur.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/ur.pak.info
+858a3ace87bff36cd4dc1532ad95626b061fa2af07dff40d896f266facc46ca7 ./chrome/linux-1108766/chrome-linux/locales/vi.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/vi.pak.info
+27d1f81e8302bd24bdaaf39ec9734e732f812644cf24cf282c86851bd1a4ee1a ./chrome/linux-1108766/chrome-linux/locales/zh-CN.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/zh-CN.pak.info
+72fa334fe28ab855115c32d9005c34620115960c0fc1e3709c2fb6e9e53d6976 ./chrome/linux-1108766/chrome-linux/locales/zh-TW.pak
+cb87a868d66f88bb0479c20536bf22ec93dd0bd775a88c57777d27dd9a128add ./chrome/linux-1108766/chrome-linux/locales/zh-TW.pak.info
+a20f2ff7a775859e2493c9fc4118080b5d31c2b28c4e79c08255f7d0e411a12b ./chrome/linux-1108766/chrome-linux/nacl_helper
+2bb2fa72fab83a34dfa6690973177d3537a3a946300d66ede276c8b6de2cbec7 ./chrome/linux-1108766/chrome-linux/nacl_helper_bootstrap
+17dcbaeb7337547b75884c44bd38377dccf36b444c6cab9a740cf0aef1b7abf5 ./chrome/linux-1108766/chrome-linux/nacl_irt_x86_64.nexe
+21b2927bb47d305bbda718b9c08c6b51fbc0597454587978ea0046bc595393fb ./chrome/linux-1108766/chrome-linux/product_logo_48.png
+64b6feb043f51c13b25b5b72290bf30ec48c4181ed9716b1b4bee76a7c0f55ba ./chrome/linux-1108766/chrome-linux/resources.pak
+68760fc7002c3999d3b2ac6eb80febe28182134a0dd1d53829f660b3d96bc9ef ./chrome/linux-1108766/chrome-linux/resources/inspector_overlay/inspector_overlay_resources.grd
+cd1db1a3000b7397c4232bcc2c05b9fa436c25f0c00aaab683d448b325588256 ./chrome/linux-1108766/chrome-linux/resources/inspector_overlay/main.js
+46639e627710cf843878115db26b97da94678782a8a0d109a5c29ac04b6b0d9e ./chrome/linux-1108766/chrome-linux/v8_context_snapshot.bin
+c9eef28b6b984fec220ef0abfecc40b502d46946706e47bfe97707027cb818bd ./chrome/linux-1108766/chrome-linux/vk_swiftshader_icd.json
+ad2d5802bb3604daa849ce5ac86a81acf7548c8ffd10ab4ecae1d56a5f10d63b ./chrome/linux-1108766/chrome-linux/xdg-mime
+442777b1f7d206c5ff661fea00dc1a8319df6256feccc54f186f6edacf235801 ./chrome/linux-1108766/chrome-linux/xdg-settings
diff --git a/bin/reindex b/bin/reindex
index 57ac403..24e76eb 100755
--- a/bin/reindex
+++ b/bin/reindex
@@ -151,7 +151,7 @@ def writeTextIndexFile(proposals):
def formatMarkdownEntry(prop, withStatus=False):
if withStatus:
- fmt = "* [`{Filename}`](/proposals/{Filename}): {Title} [{Status}]\n"
+ fmt = "* [`{Filename}`](/proposals/{Filename}): {Title} \\[{Status}\\]\n"
else:
fmt = "* [`{Filename}`](/proposals/{Filename}): {Title}\n"
return fmt.format(**prop)
diff --git a/bin/via-yarn-install-in-ci b/bin/via-yarn-install-in-ci
new file mode 100755
index 0000000..5aa9fcb
--- /dev/null
+++ b/bin/via-yarn-install-in-ci
@@ -0,0 +1,59 @@
+#!/usr/bin/env bash
+
+set -euo pipefail
+
+set -x
+
+# usage:
+# bin/via-yarn-install-in-ci COMMAND GIT-URL-FOR-PACKAGE COMMITID
+#
+# We demand a commitid to mitigate the security risks of npm
+
+command="$1"
+git_url="$2"
+commitid="$3"
+
+# Bump this to "clear" the cache.
+# Actually, it just causes us to ignore previous cached results.
+cache_clear_token=2023-11-09c
+
+cache_dir=cache/"$CI_JOB_IMAGE","$cache_clear_token","$command","$commitid"
+local_dir="yarn-build,$command"
+
+mkdir -p "$local_dir"
+
+if test -d "$cache_dir"/; then
+ cp -al "$cache_dir"/. "$local_dir"/.
+
+ type -p node || apt-get install -y nodejs
+else
+
+ if [ -z "${YARN-}" ]; then
+ type -p yarnpkg || apt-get install -y yarnpkg
+ YARN=yarnpkg
+ fi
+
+ cd "$local_dir"
+ git clone "$git_url" "$command".git
+ cd "$command".git
+ git config advice.detachedHead false
+ git checkout "$commitid"
+
+ : ----- invoke yarn to build "$command": running -----
+ $YARN install --frozen-lockfile --non-interactive
+ : ----- invoke yarn to build "$command": complete -----
+
+ cd ../..
+ ls -al "$PWD"/"$local_dir"/"$command".git/src/cli.js
+
+ mkdir -p "$cache_dir"
+ cp -al "$local_dir"/. "$cache_dir"/.
+fi
+
+# We abuse $CARGO_HOME/bin.
+# The rust: CI images we're using have that on PATH.
+# If one were to run this outside CI, putting a symlink
+# to some NPM thing in ~/.cargo/bin doesn't seem terrible.
+
+ln -s "$PWD"/"$local_dir"/"$command".git/src/cli.js \
+ "$CARGO_HOME"/bin/"$command"
diff --git a/mdbook/proposals/book.toml b/mdbook/proposals/book.toml
index fdbe64a..e466b1b 100644
--- a/mdbook/proposals/book.toml
+++ b/mdbook/proposals/book.toml
@@ -7,7 +7,7 @@ title = "Tor design proposals"
use-default-preprocessors = false
[build]
-build-dir = "../../html/proposals"
+build-dir = "../../build/proposals"
[preprocessor.links]
@@ -19,6 +19,16 @@ theme = "../theme"
# additional-js = ["theme/pagetoc.js"]
no-section-label = true
+[output.linkcheck]
+warning-policy = "error"
+# We effectively disable checking link destinations by excluding
+# all links (`.*`).
+#
+# We're only using linkcheck to validate that reference-style links have *some*
+# definition in the markdown, ensuring that *some* link will be generated. We
+# validate that those links are correct using a separate tool (`bin/check_links`)
+exclude = [ '.*' ]
+
[output.html.search]
enable = false
diff --git a/mdbook/proposals/mermaid-init.js b/mdbook/proposals/mermaid-init.js
new file mode 100644
index 0000000..313a6e8
--- /dev/null
+++ b/mdbook/proposals/mermaid-init.js
@@ -0,0 +1 @@
+mermaid.initialize({startOnLoad:true});
diff --git a/mdbook/spec/book.toml b/mdbook/spec/book.toml
index 48b9aef..16668c9 100644
--- a/mdbook/spec/book.toml
+++ b/mdbook/spec/book.toml
@@ -6,14 +6,12 @@ src = "../../spec"
title = "Tor Specifications"
[build]
-build-dir = "../../html"
+build-dir = "../../build/spec"
-# [preprocessor.pagetoc]
+[preprocessor]
[output.html]
theme = "../theme"
-# additional-css = ["theme/pagetoc.css"]
-# additional-js = ["theme/pagetoc.js"]
[output.html.redirect]
@@ -27,3 +25,13 @@ theme = "../theme"
"/tor-design.html" = "https://svn.torproject.org/svn/projects/design-paper/tor-design.pdf"
"/walking-onions.html" = "https://spec.torproject.org/proposals/323-walking-onions-full.html"
# END AUTO-GENERATED REDIRECTS
+
+[output.linkcheck]
+warning-policy = "error"
+# We effectively disable checking link destinations by excluding
+# all links (`.*`).
+#
+# We're only using linkcheck to validate that reference-style links have *some*
+# definition in the markdown, ensuring that *some* link will be generated. We
+# validate that those links are correct using a separate tool (`bin/check_links`)
+exclude = [ '.*' ]
diff --git a/mdbook/spec/mermaid-init.js b/mdbook/spec/mermaid-init.js
new file mode 100644
index 0000000..313a6e8
--- /dev/null
+++ b/mdbook/spec/mermaid-init.js
@@ -0,0 +1 @@
+mermaid.initialize({startOnLoad:true});
diff --git a/proposals/000-index.txt b/proposals/000-index.txt
index 0329640..a71b35d 100644
--- a/proposals/000-index.txt
+++ b/proposals/000-index.txt
@@ -248,7 +248,7 @@ Proposals by number:
324 RTT-based Congestion Control for Tor [FINISHED]
325 Packed relay cells: saving space on small commands [OBSOLETE]
326 The "tor-relay" Well-Known Resource Identifier [OPEN]
-327 A First Take at PoW Over Introduction Circuits [FINISHED]
+327 A First Take at PoW Over Introduction Circuits [CLOSED]
328 Make Relays Report When They Are Overloaded [CLOSED]
329 Overcoming Tor's Bottlenecks with Traffic Splitting [FINISHED]
330 Modernizing authority contact entries [OPEN]
@@ -326,7 +326,6 @@ Proposals by status:
260 Rendezvous Single Onion Services [in 0.2.9.3-alpha]
291 The move to two guard nodes
324 RTT-based Congestion Control for Tor
- 327 A First Take at PoW Over Introduction Circuits
329 Overcoming Tor's Bottlenecks with Traffic Splitting
CLOSED:
101 Voting on the Tor Directory System [in 0.2.0.x]
@@ -431,6 +430,7 @@ Proposals by status:
314 Allow Markdown for proposal format
315 Updating the list of fields required in directory documents [in 0.4.5.1-alpha]
318 Limit protover values to 0-63 [in 0.4.5.1-alpha]
+ 327 A First Take at PoW Over Introduction Circuits
328 Make Relays Report When They Are Overloaded
332 Ntor protocol with extra data, version 3
333 Vanguards lite [in 0.4.7.1-alpha]
diff --git a/proposals/316-flashflow.md b/proposals/316-flashflow.md
index 8258d76..6755913 100644
--- a/proposals/316-flashflow.md
+++ b/proposals/316-flashflow.md
@@ -56,7 +56,7 @@ time while Torflow takes days/weeks to assign them their full fair share
of bandwidth (especially for non-exits). FlashFlow is more secure than
Torflow: FlashFlow allows a relay to inflate its measured capacity by up
to 1.33x (configured by a parameter) while Torflow allows weight
-inflation by a factor of 89x [0] or even 177x [1].
+inflation by a factor of 89x [\[0\]] or even 177x [\[1\]].
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
@@ -133,7 +133,7 @@ allow itself to be measured more than twice by a FlashFlow deployment in
any time window of this length. Relays should not change this option
unless they really know what they're doing. Changing it at the relay
will not change how often FlashFlow will attempt to measure the relay.
-Possible values are in the range [1 hour, 1 month] inclusive. Default: 1
+Possible values are in the range \[1 hour, 1 month\] inclusive. Default: 1
day.
FFBackgroundTrafficPercent: The maximum amount of regular
@@ -142,7 +142,7 @@ percent of total traffic (measurement + non-measurement). This
parameter is a trade off between having to limit background traffic and
limiting how much a relay can inflate its result by handling no
background traffic but reporting that it has done so. Possible values
-are in the range [0, 99] inclusive. Default: 25 (a maximum inflation
+are in the range \[0, 99\] inclusive. Default: 25 (a maximum inflation
factor of 1.33).
FFMaxMeasurementDuration: The maximum amount of time, in seconds, that
@@ -151,7 +151,7 @@ measurement will begin soon and the end of the measurement. If this
amount of time passes, the relay shall close all measurement connections
and exit its measurement mode. Note this duration includes handshake
time, thus it necessarily is larger than the expected actual measurement
-duration. Possible values are in the range [10, 120] inclusive.
+duration. Possible values are in the range \[10, 120\] inclusive.
Default: 45.
### 3.1.2 New Cell Types
@@ -219,7 +219,7 @@ 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 MEAS_PARAMS cells [XXX more may need to be added]:
+The payload of MEAS_PARAMS cells \[XXX more may need to be added\]:
```
- meas_duration [2 bytes] [1, 600]
@@ -231,10 +231,10 @@ 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
+\[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?]
+suggests\]
+\[XXX want to specify number of conns to expect from each measurer here?\]
MEAS_PARAMS_OK has no payload: it's just padding bytes to make the cell
PAYLOAD_LEN (509) bytes long.
@@ -245,7 +245,7 @@ The payload of MEAS_ECHO cells:
- arbitrary bytes [PAYLOAD_LEN bytes]
```
-The payload of MEAS_BG cells [XXX more for extra info? like CPU usage]:
+The payload of MEAS_BG cells \[XXX more for extra info? like CPU usage\]:
```
- second [2 byte] [1, 600]
@@ -260,7 +260,7 @@ 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 MEAS_BG
cell). recv_bg_bytes is the same but for received bytes.
-The payload of MEAS_ERR cells [XXX need field for more info]:
+The payload of MEAS_ERR cells \[XXX need field for more info\]:
```
- err_code [1 byte] [0, 255]
@@ -302,8 +302,8 @@ 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]
+\[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
@@ -317,7 +317,7 @@ values. They are:
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.
+ 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.
@@ -419,7 +419,7 @@ slot for it. It picks slot 3. The coordinator takes the next largest,
```
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);
+Slot 2 already has 600 Mbit/s of measurer capacity reserved (300\*m);
given just 1000 Mbit/s of total measurer capacity, there is just 400
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
@@ -473,11 +473,11 @@ 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
+\[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]
+fill up their disk\]
-[XXX What's the approxmiate disk usage for, say, a few years of these?]
+\[XXX What's the approxmiate disk usage for, say, a few years of these?\]
### 3.2.2 FlashFlow Measurer
@@ -532,7 +532,7 @@ report more than ~33 Mbit/s, FlashFlow limits it to just ~33 Mbit/s.)
With r=25%, FlashFlow only allows 1.33x weight inflation.
Prior work shows that Torflow allows weight inflation by a factor of 89x
-[0] or even 177x [1].
+[\[0\]] or even 177x [\[1\]].
The ratio chosen is a trade-off between impact on background traffic and
security: r=50% allows a relay to double its weight but won't impact
@@ -578,7 +578,7 @@ 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].
+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
@@ -652,7 +652,7 @@ 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.
-[XXX Teor leaves good ideas in his tor-dev@ post [5],
+\[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]
@@ -665,7 +665,7 @@ time. What specifically to do here is left for medium/long term work.
## 5.3 Experiments
- [XXX todo]
+\[XXX todo\]
## 5.4 Other Changes/Investigations/Ideas
@@ -694,28 +694,32 @@ time. What specifically to do here is left for medium/long term work.
background traffic.
- What to do about co-located relays. Can they be detected reliably?
Should we just add a torrc option a la MyFamily for co-located relays?
-- What is the explanation for dennis.jackson's scary graphs in this [2]
+- What is the explanation for dennis.jackson's scary graphs in this [\[2\]]
ticket? Was it because of the speed test? Why? Will FlashFlow produce
the same behavior?
-# 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
-[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
+<!-- # Citations -->
+
+[\[0\]]: <https://www.cryptolux.org/images/b/bc/Tor_Issues_Thesis_Thill_Fabrice.pdf>
+"F. Thill. Hidden Service Tracking Detection and Bandwidth Cheating
+in Tor Anonymity Network. Master’s thesis, Univ. Luxembourg, 2014."
+
+[\[1\]]: <https://ohmygodel.com/publications/peerflow-popets2017.pdf>
+"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."
+
+[\[2\]]: <https://trac.torproject.org/projects/tor/ticket/33076>
+"Mike Perry: Graph onionperf and consensus information from Rob's experiments"
+
+[\[3\]]: ../tor-spec/subprotocol-versioning.md#relay
+"Tor Specification: \"Relay\" Subprotocol versioning"
+
+[\[4\]]: <https://lists.torproject.org/pipermail/tor-dev/2020-April/014251.html>
+"Teor's second response to FlashFlow proposal"
+
+[\[5\]]: <https://lists.torproject.org/pipermail/tor-dev/2020-April/014246.html>
+"Teor's first response to FlashFlow proposal"
# Appendix A: Save CPU at measurer by not encrypting all MEAS_ECHO cells
@@ -745,10 +749,10 @@ measurement.
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,
+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.
+we choose a new idx in \[2000, 3000). Etc.
There's 2000+ cells in flight and the measurer has recorded two items:
@@ -821,7 +825,7 @@ 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
+- 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
@@ -830,4 +834,3 @@ results in a bucket size of approximately 125:
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/323-walking-onions-full.md b/proposals/323-walking-onions-full.md
index 86d57b2..192ae48 100644
--- a/proposals/323-walking-onions-full.md
+++ b/proposals/323-walking-onions-full.md
@@ -1572,9 +1572,9 @@ even, take the lower of the two center votes (the one at position
N/2) if `BREAK_EVEN_LOW` is true. Otherwise, take the higher of the
two center votes (the one at position N/2 + 1).
-For example, the Median(…, even_low: True, type: "uint") of the votes
-["String", 2, 111, 6] is 6. The Median(…, even_low: True, type: "uint")
-of the votes ["String", 77, 9, 22, "String", 3] is 9.
+For example, the `Median(…, even_low: True, type: "uint")` of the votes
+`["String", 2, 111, 6]` is 6. The `Median(…, even_low: True, type: "uint")`
+of the votes `["String", 77, 9, 22, "String", 3]` is 9.
<!-- Section 3.3.4.2 --> <a id='S3.3.4.2'></a>
@@ -1681,7 +1681,7 @@ elements that appears in at least `MIN_COUNT` votes.
(Note that the input votes may contain duplicate elements. These
must be treated as if there were no duplicates: the vote
-[1, 1, 1, 1] is the same as the vote [1]. Implementations may want
+`[1, 1, 1, 1]` is the same as the vote `[1]`. Implementations may want
to preprocess votes by discarding all but one instance of each
member.)
@@ -1827,10 +1827,12 @@ computed so far), and on the entirety of the set of votes.
> our current behavior.
Parameters:
+
`FIELDS` (one or more other locations in the vote)
`RULE` (the rule used to combine values)
-Encoding
+Encoding:
+
; This item is "derived from" some other field.
DerivedItemOp = {
op: "DerivedFrom",
@@ -2646,7 +2648,7 @@ corresponding ENDIVERouterData.
Because SNIPLocation objects are signed, they must be encoded as "canonical"
cbor, according to section 3.9 of RFC 7049.
-If R[idx] is {} (the empty map) for any given idx, then no SNIP will be
+If `R[idx]` is `{}` (the empty map) for any given idx, then no SNIP will be
generated for the SNIPRouterData at that routing index for this index group.
<!-- Section 4.2 --> <a id='S4.2'></a>
@@ -2839,6 +2841,7 @@ The CREATE2, CREATED2, and EXTENDED2 cells change as follows:
These extensions are defined by this proposal:
+```text
[01] -- `Partial_SNIPRouterData` -- Sent from an extending relay
to a target relay. This extension holds one or more fields
from the SNIPRouterData that the extending relay is using,
@@ -2861,6 +2864,7 @@ These extensions are defined by this proposal:
originator does not want a SNIP. Otherwise, the
originator does want a SNIP containing the router and the
specified index. Other values are unspecified.
+```
By default, EXTENDED2 cells are sent with a SNIP iff the EXTENDED2
cell used a `snip_index_pos` link specifier, and CREATED2 cells are
@@ -2923,14 +2927,14 @@ following main changes.
So the client's message is now:
- CLIENT_PK [32 bytes]
+ CLIENT_PK [32 bytes]
And the relay's reply is now:
- NODEID [32 bytes]
- KEYID [32 bytes]
- SERVER_PK [32 bytes]
- AUTH [32 bytes]
+ NODEID [32 bytes]
+ KEYID [32 bytes]
+ SERVER_PK [32 bytes]
+ AUTH [32 bytes]
otherwise, all fields are computed as described in tor-spec.
@@ -3330,10 +3334,10 @@ relay cells.)
> that the relay might not understand.
To include the SNIP, the client places it in an extension in the
-INTRODUCE cell. The onion key can now be omitted[*], along with
+INTRODUCE cell. The onion key can now be omitted\[\*\], along with
the link specifiers.
-> [*] Technically, we use a zero-length onion key, with a new type
+> \[\*\] Technically, we use a zero-length onion key, with a new type
> "implicit in SNIP".
To know whether the service can recognize this kind of cell, the
@@ -3445,10 +3449,10 @@ between updating ENDIVEs under ideal circumstances.
# Migrating to Walking Onions
This proposal is a major change in the Tor network that will
-eventually require the participation of all relays [*], and will make
+eventually require the participation of all relays \[\*\], and will make
clients who support it distinguishable from clients that don't.
-> [*] Technically, the last relay in the path doesn't need support.
+> \[\*\] Technically, the last relay in the path doesn't need support.
To keep the compatibility issues under control, here is the order in which it
should be deployed on the network.
@@ -3903,6 +3907,7 @@ guards and/or exits depending on overall balance of resources on the
network.
Formula:
+
type: 'weighted',
source: {
type:'bw', require_flags: ['Valid'], 'bwfield' : ["RM", "mbw"]
@@ -3978,10 +3983,10 @@ Formula:
## Appendix H: Choosing good clusters of exit policies
With Walking Onions, we cannot easily support all the port
-combinations [*] that we currently allow in the "policy summaries"
+combinations \[\*\] that we currently allow in the "policy summaries"
that we support in microdescriptors.
-> [*] How many "short policy summaries" are there? The number would be
+> \[\*\] How many "short policy summaries" are there? The number would be
> 2^65535, except for the fact today's Tor doesn't permit exit policies to
> get maximally long.
diff --git a/proposals/325-packed-relay-cells.md b/proposals/325-packed-relay-cells.md
index 7a88840..7d0ffca 100644
--- a/proposals/325-packed-relay-cells.md
+++ b/proposals/325-packed-relay-cells.md
@@ -57,23 +57,27 @@ concatenated one after another following this format of a relay cell. The
first command is the same header format as a normal relay cell detailed in
section 6.1 of tor-spec.txt
- Relay Command [1 byte]
- 'Recognized' [2 bytes]
- StreamID [2 bytes]
- Digest [4 bytes]
- Length [2 bytes]
- Data [Length bytes]
- RELAY\_MESSAGE
- Padding [up to end of cell]
+```text
+Relay Command [1 byte]
+'Recognized' [2 bytes]
+StreamID [2 bytes]
+Digest [4 bytes]
+Length [2 bytes]
+Data [Length bytes]
+RELAY\_MESSAGE
+Padding [up to end of cell]
+```
The `RELAY_MESSAGE` can be empty as in no bytes indicating no other messages
or set to the following:
- Relay Command [1 byte]
- StreamID [2 bytes]
- Length [2 bytes]
- Data [Length bytes]
- RELAY\_MESSAGE
+```text
+Relay Command [1 byte]
+StreamID [2 bytes]
+Length [2 bytes]
+Data [Length bytes]
+RELAY\_MESSAGE
+```
Note that the Recognized and Digest field are not added to a second relay
message, they are solely used for the whole relay cell thus how we
@@ -123,10 +127,12 @@ with the default set to use a consensus parameter.
The parameter is:
- "relay-cell-packing"
+```text
+"relay-cell-packing"
- Boolean: if 1, clients should send packed relay cells.
- (Min: 0, Max 1, Default: 0)
+Boolean: if 1, clients should send packed relay cells.
+(Min: 0, Max 1, Default: 0)
+```
To handle migration, first the parameter should be set to 0 and the
configuration setting should be "auto". To test the feature, individual
@@ -150,17 +156,21 @@ I propose a new relay message format, described here (with `ux`
denoting an x-bit bitfield). This format is 2 bytes or 4 bytes,
depending on its first bit.
- struct relay_header {
- u1 stream_id_included; // Is the stream_id included?
- u6 relay_command; // as before
- u9 relay_data_len; // as before
- u8 optional_stream_id[]; // 0 bytes or two bytes.
- }
+```C
+struct relay_header {
+ u1 stream_id_included; // Is the stream_id included?
+ u6 relay_command; // as before
+ u9 relay_data_len; // as before
+ u8 optional_stream_id[]; // 0 bytes or two bytes.
+}
+```
Alternatively, you can view the first three fields as a 16-bit
value, computed as:
- (stream_id_included<<15) | (relay_command << 9) | (relay_data_len).
+```C
+(stream_id_included<<15) | (relay_command << 9) | (relay_data_len).
+```
If the `optional_stream_id` field is not present, then the default
value for the `stream_id` is computed as follows. We use stream_id 0
diff --git a/proposals/326-tor-relay-well-known-uri-rfc8615.md b/proposals/326-tor-relay-well-known-uri-rfc8615.md
index 075aa6d..8bc705a 100644
--- a/proposals/326-tor-relay-well-known-uri-rfc8615.md
+++ b/proposals/326-tor-relay-well-known-uri-rfc8615.md
@@ -38,7 +38,7 @@ The verification of listed Tor relay/bridge IDs only succeeds if the claim can b
* Each line contains one relay fingerprint.
* The file MUST NOT contain fingerprints of Tor bridges (or hashes of bridge fingerprints). For bridges see the file `hashed-bridge-rsa-fingerprint.txt`.
* 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].
+* 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.
@@ -59,7 +59,7 @@ The RSA SHA1 relay fingerprint can be found in the file named "fingerprint" loca
* This file is not relevant for bridges.
* Each line contains one public ed25519 master key in its base64 encoded form.
* The file may contain comments (starting with #).
-* Non-comment lines must be exactly 43 characters long and consist of the following characters [a-zA-z0-9/+].
+* Non-comment lines must be exactly 43 characters long and consist of the following characters `[a-zA-z0-9/+]`.
* Each key MUST appear at most once.
* The file MUST not be larger than one MByte.
* The content MUST be a media type of "text/plain".
@@ -80,7 +80,7 @@ The base64 encoded ed25519 public master key can be found in the file named "fin
* The file contains one or more SHA1 hashed Tor bridge SHA1 fingerprints operated by the entity in control of this website.
* Each line contains one hashed bridge 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].
+* Non-comment lines must be exactly 40 characters long and consist of the following characters `[a-fA-F0-9]`.
* Hashed fingerprints are not case-sensitive.
* Each hashed fingerprint MUST appear at most once.
* The file MUST not be larger than one MByte.
diff --git a/proposals/327-pow-over-intro.txt b/proposals/327-pow-over-intro.txt
index 3abffc4..d267d3c 100644
--- a/proposals/327-pow-over-intro.txt
+++ b/proposals/327-pow-over-intro.txt
@@ -3,7 +3,7 @@ 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: Finished
+Status: Closed
0. Abstract
@@ -1208,7 +1208,7 @@ A.2. References
[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://datatracker.ietf.org/doc/html/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
diff --git a/proposals/328-relay-overload-report.md b/proposals/328-relay-overload-report.md
index 5901b93..bdb4fec 100644
--- a/proposals/328-relay-overload-report.md
+++ b/proposals/328-relay-overload-report.md
@@ -41,16 +41,16 @@ state" which can be one or many of the following load metrics:
- Any OOM invocation due to memory pressure
- Any ntor onionskins are dropped
- [Removed in tor-0.4.6.11 and 0.4.7.5-alpha]
+ \[Removed in tor-0.4.6.11 and 0.4.7.5-alpha\]
- A certain ratio of ntor onionskins dropped.
- [Added in tor-0.4.6.11 and 0.4.7.5-alpha]
+ \[Added in tor-0.4.6.11 and 0.4.7.5-alpha\]
- TCP port exhaustion
- DNS timeout reached (X% of timeouts over Y seconds).
- [Removed in tor-0.4.7.3-alpha]
+ \[Removed in tor-0.4.7.3-alpha\]
- CPU utilization of Tor's mainloop CPU core above 90% for 60 sec
- [Never implemented]
+ \[Never implemented\]
- Control port overload (too many messages queued)
- [Never implemented]
+ \[Never implemented\]
For DNS timeouts, the X and Y are consensus parameters
(overload_dns_timeout_scale_percent and overload_dns_timeout_period_secs)
diff --git a/proposals/331-res-tokens-for-anti-dos.md b/proposals/331-res-tokens-for-anti-dos.md
index a7293e8..448ebe4 100644
--- a/proposals/331-res-tokens-for-anti-dos.md
+++ b/proposals/331-res-tokens-for-anti-dos.md
@@ -56,20 +56,20 @@ Status: Draft
from various types of Token Issuers and then redeem them at the onion service
to gain access even when under DoS conditions.
- In section [TOKEN_DESIGN], we list our requirements from an anonymous
+ In section [TOKEN_DESIGN](#token-design), we list our requirements from an anonymous
credential scheme and provide a high-level overview of how the Res token
scheme works.
- In section [PROTOCOL_SPEC], we specify the token issuance and redemption protocols,
+ In section [PROTOCOL_SPEC](#protocol-spec), we specify the token issuance and redemption protocols,
as well as the mathematical operations that need to be conducted for these to work.
- In section [TOKEN_ISSUERS], we provide a few examples and guidelines for
+ In section [TOKEN_ISSUERS](#token-issuers), we provide a few examples and guidelines for
various token issuer services that could exist.
- In section [DISCUSSION], we provide more use cases for Res tokens as well as
+ In section [DISCUSSION](#discussion), we provide more use cases for Res tokens as well as
future improvements we can conduct to the scheme.
-# 3. Design [TOKEN_DESIGN]
+# 3. Design \[TOKEN_DESIGN\] {#token-design}
In this section we will go over the high-level design of the system, and in
the next section we will delve into the lower-level details of the protocol.
@@ -109,13 +109,13 @@ Status: Draft
- Quick Verification: Onions are already experiencing resource starvation
because of the DoS attacks so it's important that the process of
- verifying a token should be as quick as possible. In section [TOKEN_PERF]
+ verifying a token should be as quick as possible. In section [TOKEN_PERF](#token-perf)
we will go deeper into this requirement.
After careful consideration of the above requirements, we have leaned towards
using Blind RSA as the primitive for our tokens, since it's the fastest
- scheme by far that also allows public verifiability. See also Appendix B
- [BLIND_RSA_PROOF] for a security proof sketch of Blind RSA perfect unlinkability.
+ scheme by far that also allows public verifiability. See also [Appendix A](#blind-rsa-proof)
+ for a security proof sketch of Blind RSA perfect unlinkability.
## 3.3. Other security considerations
@@ -128,7 +128,7 @@ Status: Draft
- Metadata: We want to encode metadata/attributes in the tokens. In
particular, we want to encode the destination onion service and an
- expiration date. For more information see section [DEST_DIGEST]. For
+ expiration date. For more information see section [DEST_DIGEST](#dest-digest). For
blind RSA tokens this is usually done using "partially blind signatures"
but to keep it simple we instead encode the destination directly in the
message to be blind-signed and the expiration date using a set of
@@ -162,9 +162,9 @@ Status: Draft
an adversary breaks an issuance key, she will be able to forge tokens for
just a few hours before that key expires.
- For more ideas on future schemes and improvements see section [FUTURE_RES].
+ For more ideas on future schemes and improvements see section [FUTURE_RES](#future-res).
-## 3.5. Token performance requirements [TOKEN_PERF]
+## 3.5. Token performance requirements \[TOKEN_PERF\] {#token-perf}
As discussed above, verification performance is extremely important in the
anti-DoS use case. In this section we provide some concrete numbers on what
@@ -188,14 +188,14 @@ Status: Draft
For this reason we implemented a basic version of the Res token scheme in
Rust and benchmarked the verification and issuance procedure [REF_RES_BENCH].
- We measured that the verification procedure from section [RES_VERIFY] takes
+ We measured that the verification procedure from section [RES_VERIFY](#res-verify) takes
about 0.104 ms, which we believe is a reasonable verification overhead for
the purposes of this proposal.
- We also measured that the issuance procedure from [RES_ISSUANCE] takes about
+ We also measured that the issuance procedure from [RES_ISSUANCE](#res-issuance) takes about
0.614 ms.
-# 4. Specification [PROTOCOL_SPEC]
+# 4. Specification \[PROTOCOL_SPEC\] {#protocol-spec}
+--------------+ +------------------+
| Token Issuer | | Onion Service |
@@ -270,7 +270,7 @@ Status: Draft
onion service in its token store. If not, it needs to acquire some and hence
the token issuance protocol commences.
-### 4.3.1. Client preparation [DEST_DIGEST]
+### 4.3.1. Client preparation \[DEST_DIGEST\] {#dest-digest}
Alice first chooses an issuer supported by the onion service depending on her
preferences by looking at the consensus and her Tor configuration file for
@@ -289,7 +289,7 @@ Status: Draft
- 'destination' is the 32-byte ed25519 public identity key of the destination onion
- 'salt' is a random 32-byte value,
- 3) Alice samples a blinding factor 'r' uniformly at random from [1, N)
+ 3) Alice samples a blinding factor 'r' uniformly at random from \[1, N)
4) Alice computes:
blinded_message = dest_digest * r^e (mod N)
@@ -301,7 +301,7 @@ Status: Draft
XXX Is the salt needed? Reevaluate.
-### 4.3.3. Token Issuance [RES_ISSUANCE]
+### 4.3.3. Token Issuance \[RES_ISSUANCE\] {#res-issuance}
Alice now initiates contact with the Token Issuer and spends the resources
required to get issued a token (e.g. solve a CAPTCHA or a PoW, create an
@@ -348,8 +348,9 @@ Status: Draft
onion service.
To do so, Alice 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
+ cell by using the EXTENSIONS field (see [PROCESS_INTRO2 section in
+ rend-spec-v3.txt](../rend-spec/introduction-protocol.md#PROCESS_INTRO2)).
+ 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:
@@ -365,7 +366,7 @@ Status: Draft
SALT [32 bytes]
where:
- - TOKEN_VERSION is the version of the token ([0x01] for Res tokens)
+ - TOKEN_VERSION is the version of the token (\[0x01\] for Res tokens)
- ISSUER_KEY is the public key of the chosen issuer (truncated to 4 bytes)
- DEST_DIGEST is the 'dest_digest' from above
- TOKEN is the 'token' from above
@@ -381,7 +382,7 @@ Status: Draft
XXX maybe with a bit of tweaking we can even use a 1536-bit RSA signature here...
-### 4.4.2. Onion service verifies token [RES_VERIFY]
+### 4.4.2. Onion service verifies token \[RES_VERIFY\] {#res-verify}
Upon receiving an INTRODUCE1 cell with the above extension the service
verifies the token. It does so as follows:
@@ -408,7 +409,7 @@ Status: Draft
considers the token valid and the rest of the onion service protocol carries
out as normal.
-# 5. Token issuers [TOKEN_ISSUERS]
+# 5. Token issuers \[TOKEN_ISSUERS\]{#token-issuers}
In this section we go over some example token issuers. While we can have
official token issuers that are supported by the Tor directory authorities,
@@ -472,7 +473,7 @@ Status: Draft
one-show, so the onion service cannot provide a single token that will work
for multiple "logins". In the future we can design multi-show credential
systems that also have revocation to further facilitate this use case (see
- [FUTURE_RES] for more info).
+ [FUTURE_RES](#future-res) for more info).
# 6. User Experience
@@ -506,7 +507,7 @@ Status: Draft
XXX Actually analyze the above if we think there is merit to listing them
-# 8. Discussion [DISCUSSION]
+# 8. Discussion \[DISCUSSION\] {#discussion}
## 8.1. Using Res tokens on Exit relays
@@ -525,7 +526,7 @@ Status: Draft
websites and web services on the public Internet. We hope that this way we
will see less websites blocking Tor.
-## 8.2. Future improvements to this proposal [FUTURE_RES]
+## 8.2. Future improvements to this proposal \[FUTURE_RES\] {#future-res}
The Res token scheme is a pragmatic scheme that works for the space/time
constraints of this use case but it's far from ideal for the greater future
@@ -579,7 +580,7 @@ Status: Draft
---
-# Appendix A: RSA Blinding Security Proof [BLIND_RSA_PROOF]
+# Appendix A: RSA Blinding Security Proof \[BLIND_RSA_PROOF\] {#blind-rsa-proof}
This proof sketch was provided by Michele Orrù:
diff --git a/proposals/332-ntor-v3-with-extra-data.md b/proposals/332-ntor-v3-with-extra-data.md
index 58a3bf3..10f0dd4 100644
--- a/proposals/332-ntor-v3-with-extra-data.md
+++ b/proposals/332-ntor-v3-with-extra-data.md
@@ -47,7 +47,7 @@ The client knows:
* An optional "verification" string.
The relay knows:
- * A set of [(b,B)...] "onion key" keypairs. One of them is
+ * A set of \[(b,B)...\] "onion key" keypairs. One of them is
"current", the others are outdated, but still valid.
* ID: Its own identity.
* A function for computing a server message SM, based on a given
@@ -398,7 +398,7 @@ client sends a message, with type `CIRCWINDOW_INC`, containing a
two-byte integer equal to `circwindow_inc_dflt`.
The relay rejects the message if the value given is outside of the
-[`circwindow_inc_min`, `circwindow_inc_max`] range. Otherwise, it
+\[`circwindow_inc_min`, `circwindow_inc_max`\] range. Otherwise, it
accepts it, and replies with the same message that the client sent.
# X.2: Test vectors
diff --git a/proposals/339-udp-over-tor.md b/proposals/339-udp-over-tor.md
index 5993bdc..12de0c6 100644
--- a/proposals/339-udp-over-tor.md
+++ b/proposals/339-udp-over-tor.md
@@ -264,7 +264,7 @@ I'd suggest we do it.
1. We would add a new "`FLAG_UNCONNECTED`" flag for `CONNECT_UDP` messages.
-2. We would designate the ANY addresses 0.0.0.0:0 and [::]:0 as permitted in
+2. We would designate the ANY addresses 0.0.0.0:0 and \[::\]:0 as permitted in
`CONNECT_UDP` messages, and as indicating unconnected sockets. These would
be only permitted along with the `FLAG_UNCONNECTED` flag, and not
permitted otherwise.
diff --git a/proposals/340-packed-and-fragmented.md b/proposals/340-packed-and-fragmented.md
index 82adb8e..6c27fcd 100644
--- a/proposals/340-packed-and-fragmented.md
+++ b/proposals/340-packed-and-fragmented.md
@@ -51,9 +51,11 @@ formats going on at the same time.
The new format for a decrypted relay _cell_ will be:
- recognized [2 bytes]
- digest [14 bytes]
- body [509 - 16 = 493 bytes]
+```text
+recognized [2 bytes]
+digest [14 bytes]
+body [509 - 16 = 493 bytes]
+```
The `recognized` and `digest` fields are computed as before; the only
difference is that they occur _before_ the rest of the cell, and that `digest`
diff --git a/proposals/BY_INDEX.md b/proposals/BY_INDEX.md
index b60a656..7c318fa 100644
--- a/proposals/BY_INDEX.md
+++ b/proposals/BY_INDEX.md
@@ -13,256 +13,256 @@ will never be implemented.
Below are a list of proposals sorted by their proposal number. See
[BY_STATUS.md](/proposals/BY_STATUS.md) for a list of proposals sorted by status.
-* [`000-index.txt`](/proposals/000-index.txt): Index of Tor Proposals [META]
-* [`001-process.txt`](/proposals/001-process.txt): The Tor Proposal Process [META]
-* [`098-todo.txt`](/proposals/098-todo.txt): Proposals that should be written [OBSOLETE]
-* [`099-misc.txt`](/proposals/099-misc.txt): Miscellaneous proposals [OBSOLETE]
-* [`100-tor-spec-udp.txt`](/proposals/100-tor-spec-udp.txt): Tor Unreliable Datagram Extension Proposal [DEAD]
-* [`101-dir-voting.txt`](/proposals/101-dir-voting.txt): Voting on the Tor Directory System [CLOSED]
-* [`102-drop-opt.txt`](/proposals/102-drop-opt.txt): Dropping "opt" from the directory format [CLOSED]
-* [`103-multilevel-keys.txt`](/proposals/103-multilevel-keys.txt): Splitting identity key from regularly used signing key [CLOSED]
-* [`104-short-descriptors.txt`](/proposals/104-short-descriptors.txt): Long and Short Router Descriptors [CLOSED]
-* [`105-handshake-revision.txt`](/proposals/105-handshake-revision.txt): Version negotiation for the Tor protocol [CLOSED]
-* [`106-less-tls-constraint.txt`](/proposals/106-less-tls-constraint.txt): Checking fewer things during TLS handshakes [CLOSED]
-* [`107-uptime-sanity-checking.txt`](/proposals/107-uptime-sanity-checking.txt): Uptime Sanity Checking [CLOSED]
-* [`108-mtbf-based-stability.txt`](/proposals/108-mtbf-based-stability.txt): Base "Stable" Flag on Mean Time Between Failures [CLOSED]
-* [`109-no-sharing-ips.txt`](/proposals/109-no-sharing-ips.txt): No more than one server per IP address [CLOSED]
-* [`110-avoid-infinite-circuits.txt`](/proposals/110-avoid-infinite-circuits.txt): Avoiding infinite length circuits [CLOSED]
-* [`111-local-traffic-priority.txt`](/proposals/111-local-traffic-priority.txt): Prioritizing local traffic over relayed traffic [CLOSED]
-* [`112-bring-back-pathlencoinweight.txt`](/proposals/112-bring-back-pathlencoinweight.txt): Bring Back Pathlen Coin Weight [SUPERSEDED]
-* [`113-fast-authority-interface.txt`](/proposals/113-fast-authority-interface.txt): Simplifying directory authority administration [SUPERSEDED]
-* [`114-distributed-storage.txt`](/proposals/114-distributed-storage.txt): Distributed Storage for Tor Hidden Service Descriptors [CLOSED]
-* [`115-two-hop-paths.txt`](/proposals/115-two-hop-paths.txt): Two Hop Paths [DEAD]
-* [`116-two-hop-paths-from-guard.txt`](/proposals/116-two-hop-paths-from-guard.txt): Two hop paths from entry guards [DEAD]
-* [`117-ipv6-exits.txt`](/proposals/117-ipv6-exits.txt): IPv6 exits [CLOSED]
-* [`118-multiple-orports.txt`](/proposals/118-multiple-orports.txt): Advertising multiple ORPorts at once [SUPERSEDED]
-* [`119-controlport-auth.txt`](/proposals/119-controlport-auth.txt): New PROTOCOLINFO command for controllers [CLOSED]
-* [`120-shutdown-descriptors.txt`](/proposals/120-shutdown-descriptors.txt): Shutdown descriptors when Tor servers stop [DEAD]
-* [`121-hidden-service-authentication.txt`](/proposals/121-hidden-service-authentication.txt): Hidden Service Authentication [CLOSED]
-* [`122-unnamed-flag.txt`](/proposals/122-unnamed-flag.txt): Network status entries need a new Unnamed flag [CLOSED]
-* [`123-autonaming.txt`](/proposals/123-autonaming.txt): Naming authorities automatically create bindings [CLOSED]
-* [`124-tls-certificates.txt`](/proposals/124-tls-certificates.txt): Blocking resistant TLS certificate usage [SUPERSEDED]
-* [`125-bridges.txt`](/proposals/125-bridges.txt): Behavior for bridge users, bridge relays, and bridge authorities [CLOSED]
-* [`126-geoip-reporting.txt`](/proposals/126-geoip-reporting.txt): Getting GeoIP data and publishing usage summaries [CLOSED]
-* [`127-dirport-mirrors-downloads.txt`](/proposals/127-dirport-mirrors-downloads.txt): Relaying dirport requests to Tor download site / website [OBSOLETE]
-* [`128-bridge-families.txt`](/proposals/128-bridge-families.txt): Families of private bridges [DEAD]
-* [`129-reject-plaintext-ports.txt`](/proposals/129-reject-plaintext-ports.txt): Block Insecure Protocols by Default [CLOSED]
-* [`130-v2-conn-protocol.txt`](/proposals/130-v2-conn-protocol.txt): Version 2 Tor connection protocol [CLOSED]
-* [`131-verify-tor-usage.txt`](/proposals/131-verify-tor-usage.txt): Help users to verify they are using Tor [OBSOLETE]
-* [`132-browser-check-tor-service.txt`](/proposals/132-browser-check-tor-service.txt): A Tor Web Service For Verifying Correct Browser Configuration [OBSOLETE]
-* [`133-unreachable-ors.txt`](/proposals/133-unreachable-ors.txt): Incorporate Unreachable ORs into the Tor Network [RESERVE]
-* [`134-robust-voting.txt`](/proposals/134-robust-voting.txt): More robust consensus voting with diverse authority sets [REJECTED]
-* [`135-private-tor-networks.txt`](/proposals/135-private-tor-networks.txt): Simplify Configuration of Private Tor Networks [CLOSED]
-* [`136-legacy-keys.txt`](/proposals/136-legacy-keys.txt): Mass authority migration with legacy keys [CLOSED]
-* [`137-bootstrap-phases.txt`](/proposals/137-bootstrap-phases.txt): Keep controllers informed as Tor bootstraps [CLOSED]
-* [`138-remove-down-routers-from-consensus.txt`](/proposals/138-remove-down-routers-from-consensus.txt): Remove routers that are not Running from consensus documents [CLOSED]
-* [`139-conditional-consensus-download.txt`](/proposals/139-conditional-consensus-download.txt): Download consensus documents only when it will be trusted [CLOSED]
-* [`140-consensus-diffs.txt`](/proposals/140-consensus-diffs.txt): Provide diffs between consensuses [CLOSED]
-* [`141-jit-sd-downloads.txt`](/proposals/141-jit-sd-downloads.txt): Download server descriptors on demand [OBSOLETE]
-* [`142-combine-intro-and-rend-points.txt`](/proposals/142-combine-intro-and-rend-points.txt): Combine Introduction and Rendezvous Points [DEAD]
-* [`143-distributed-storage-improvements.txt`](/proposals/143-distributed-storage-improvements.txt): Improvements of Distributed Storage for Tor Hidden Service Descriptors [SUPERSEDED]
-* [`144-enforce-distinct-providers.txt`](/proposals/144-enforce-distinct-providers.txt): Increase the diversity of circuits by detecting nodes belonging the same provider [OBSOLETE]
-* [`145-newguard-flag.txt`](/proposals/145-newguard-flag.txt): Separate "suitable as a guard" from "suitable as a new guard" [SUPERSEDED]
-* [`146-long-term-stability.txt`](/proposals/146-long-term-stability.txt): Add new flag to reflect long-term stability [SUPERSEDED]
-* [`147-prevoting-opinions.txt`](/proposals/147-prevoting-opinions.txt): Eliminate the need for v2 directories in generating v3 directories [REJECTED]
-* [`148-uniform-client-end-reason.txt`](/proposals/148-uniform-client-end-reason.txt): Stream end reasons from the client side should be uniform [CLOSED]
-* [`149-using-netinfo-data.txt`](/proposals/149-using-netinfo-data.txt): Using data from NETINFO cells [SUPERSEDED]
-* [`150-exclude-exit-nodes.txt`](/proposals/150-exclude-exit-nodes.txt): Exclude Exit Nodes from a circuit [CLOSED]
-* [`151-path-selection-improvements.txt`](/proposals/151-path-selection-improvements.txt): Improving Tor Path Selection [CLOSED]
-* [`152-single-hop-circuits.txt`](/proposals/152-single-hop-circuits.txt): Optionally allow exit from single-hop circuits [CLOSED]
-* [`153-automatic-software-update-protocol.txt`](/proposals/153-automatic-software-update-protocol.txt): Automatic software update protocol [SUPERSEDED]
-* [`154-automatic-updates.txt`](/proposals/154-automatic-updates.txt): Automatic Software Update Protocol [SUPERSEDED]
-* [`155-four-hidden-service-improvements.txt`](/proposals/155-four-hidden-service-improvements.txt): Four Improvements of Hidden Service Performance [CLOSED]
-* [`156-tracking-blocked-ports.txt`](/proposals/156-tracking-blocked-ports.txt): Tracking blocked ports on the client side [SUPERSEDED]
-* [`157-specific-cert-download.txt`](/proposals/157-specific-cert-download.txt): Make certificate downloads specific [CLOSED]
-* [`158-microdescriptors.txt`](/proposals/158-microdescriptors.txt): Clients download consensus + microdescriptors [CLOSED]
-* [`159-exit-scanning.txt`](/proposals/159-exit-scanning.txt): Exit Scanning [INFORMATIONAL]
-* [`160-bandwidth-offset.txt`](/proposals/160-bandwidth-offset.txt): Authorities vote for bandwidth offsets in consensus [CLOSED]
-* [`161-computing-bandwidth-adjustments.txt`](/proposals/161-computing-bandwidth-adjustments.txt): Computing Bandwidth Adjustments [CLOSED]
-* [`162-consensus-flavors.txt`](/proposals/162-consensus-flavors.txt): Publish the consensus in multiple flavors [CLOSED]
-* [`163-detecting-clients.txt`](/proposals/163-detecting-clients.txt): Detecting whether a connection comes from a client [SUPERSEDED]
-* [`164-reporting-server-status.txt`](/proposals/164-reporting-server-status.txt): Reporting the status of server votes [OBSOLETE]
-* [`165-simple-robust-voting.txt`](/proposals/165-simple-robust-voting.txt): Easy migration for voting authority sets [REJECTED]
-* [`166-statistics-extra-info-docs.txt`](/proposals/166-statistics-extra-info-docs.txt): Including Network Statistics in Extra-Info Documents [CLOSED]
-* [`167-params-in-consensus.txt`](/proposals/167-params-in-consensus.txt): Vote on network parameters in consensus [CLOSED]
-* [`168-reduce-circwindow.txt`](/proposals/168-reduce-circwindow.txt): Reduce default circuit window [REJECTED]
-* [`169-eliminating-renegotiation.txt`](/proposals/169-eliminating-renegotiation.txt): Eliminate TLS renegotiation for the Tor connection handshake [SUPERSEDED]
-* [`170-user-path-config.txt`](/proposals/170-user-path-config.txt): Configuration options regarding circuit building [SUPERSEDED]
-* [`171-separate-streams.txt`](/proposals/171-separate-streams.txt): Separate streams across circuits by connection metadata [CLOSED]
-* [`172-circ-getinfo-option.txt`](/proposals/172-circ-getinfo-option.txt): GETINFO controller option for circuit information [RESERVE]
-* [`173-getinfo-option-expansion.txt`](/proposals/173-getinfo-option-expansion.txt): GETINFO Option Expansion [OBSOLETE]
-* [`174-optimistic-data-server.txt`](/proposals/174-optimistic-data-server.txt): Optimistic Data for Tor: Server Side [CLOSED]
-* [`175-automatic-node-promotion.txt`](/proposals/175-automatic-node-promotion.txt): Automatically promoting Tor clients to nodes [REJECTED]
-* [`176-revising-handshake.txt`](/proposals/176-revising-handshake.txt): Proposed version-3 link handshake for Tor [CLOSED]
-* [`177-flag-abstention.txt`](/proposals/177-flag-abstention.txt): Abstaining from votes on individual flags [RESERVE]
-* [`178-param-voting.txt`](/proposals/178-param-voting.txt): Require majority of authorities to vote for consensus parameters [CLOSED]
-* [`179-TLS-cert-and-parameter-normalization.txt`](/proposals/179-TLS-cert-and-parameter-normalization.txt): TLS certificate and parameter normalization [CLOSED]
-* [`180-pluggable-transport.txt`](/proposals/180-pluggable-transport.txt): Pluggable transports for circumvention [CLOSED]
-* [`181-optimistic-data-client.txt`](/proposals/181-optimistic-data-client.txt): Optimistic Data for Tor: Client Side [CLOSED]
-* [`182-creditbucket.txt`](/proposals/182-creditbucket.txt): Credit Bucket [OBSOLETE]
-* [`183-refillintervals.txt`](/proposals/183-refillintervals.txt): Refill Intervals [CLOSED]
-* [`184-v3-link-protocol.txt`](/proposals/184-v3-link-protocol.txt): Miscellaneous changes for a v3 Tor link protocol [CLOSED]
-* [`185-dir-without-dirport.txt`](/proposals/185-dir-without-dirport.txt): Directory caches without DirPort [SUPERSEDED]
-* [`186-multiple-orports.txt`](/proposals/186-multiple-orports.txt): Multiple addresses for one OR or bridge [CLOSED]
-* [`187-allow-client-auth.txt`](/proposals/187-allow-client-auth.txt): Reserve a cell type to allow client authorization [CLOSED]
-* [`188-bridge-guards.txt`](/proposals/188-bridge-guards.txt): Bridge Guards and other anti-enumeration defenses [RESERVE]
-* [`189-authorize-cell.txt`](/proposals/189-authorize-cell.txt): AUTHORIZE and AUTHORIZED cells [OBSOLETE]
-* [`190-shared-secret-bridge-authorization.txt`](/proposals/190-shared-secret-bridge-authorization.txt): Bridge Client Authorization Based on a Shared Secret [OBSOLETE]
-* [`191-mitm-bridge-detection-resistance.txt`](/proposals/191-mitm-bridge-detection-resistance.txt): Bridge Detection Resistance against MITM-capable Adversaries [OBSOLETE]
-* [`192-store-bridge-information.txt`](/proposals/192-store-bridge-information.txt): Automatically retrieve and store information about bridges [OBSOLETE]
-* [`193-safe-cookie-authentication.txt`](/proposals/193-safe-cookie-authentication.txt): Safe cookie authentication for Tor controllers [CLOSED]
-* [`194-mnemonic-urls.txt`](/proposals/194-mnemonic-urls.txt): Mnemonic .onion URLs [SUPERSEDED]
-* [`195-TLS-normalization-for-024.txt`](/proposals/195-TLS-normalization-for-024.txt): TLS certificate normalization for Tor 0.2.4.x [DEAD]
-* [`196-transport-control-ports.txt`](/proposals/196-transport-control-ports.txt): Extended ORPort and TransportControlPort [CLOSED]
-* [`197-postmessage-ipc.txt`](/proposals/197-postmessage-ipc.txt): Message-based Inter-Controller IPC Channel [REJECTED]
-* [`198-restore-clienthello-semantics.txt`](/proposals/198-restore-clienthello-semantics.txt): Restore semantics of TLS ClientHello [CLOSED]
-* [`199-bridgefinder-integration.txt`](/proposals/199-bridgefinder-integration.txt): Integration of BridgeFinder and BridgeFinderHelper [OBSOLETE]
-* [`200-new-create-and-extend-cells.txt`](/proposals/200-new-create-and-extend-cells.txt): Adding new, extensible CREATE, EXTEND, and related cells [CLOSED]
-* [`201-bridge-v3-reqs-stats.txt`](/proposals/201-bridge-v3-reqs-stats.txt): Make bridges report statistics on daily v3 network status requests [RESERVE]
-* [`202-improved-relay-crypto.txt`](/proposals/202-improved-relay-crypto.txt): Two improved relay encryption protocols for Tor cells [META]
-* [`203-https-frontend.txt`](/proposals/203-https-frontend.txt): Avoiding censorship by impersonating an HTTPS server [OBSOLETE]
-* [`204-hidserv-subdomains.txt`](/proposals/204-hidserv-subdomains.txt): Subdomain support for Hidden Service addresses [CLOSED]
-* [`205-local-dnscache.txt`](/proposals/205-local-dnscache.txt): Remove global client-side DNS caching [CLOSED]
-* [`206-directory-sources.txt`](/proposals/206-directory-sources.txt): Preconfigured directory sources for bootstrapping [CLOSED]
-* [`207-directory-guards.txt`](/proposals/207-directory-guards.txt): Directory guards [CLOSED]
-* [`208-ipv6-exits-redux.txt`](/proposals/208-ipv6-exits-redux.txt): IPv6 Exits Redux [CLOSED]
-* [`209-path-bias-tuning.txt`](/proposals/209-path-bias-tuning.txt): Tuning the Parameters for the Path Bias Defense [OBSOLETE]
-* [`210-faster-headless-consensus-bootstrap.txt`](/proposals/210-faster-headless-consensus-bootstrap.txt): Faster Headless Consensus Bootstrapping [SUPERSEDED]
-* [`211-mapaddress-tor-status.txt`](/proposals/211-mapaddress-tor-status.txt): Internal Mapaddress for Tor Configuration Testing [RESERVE]
-* [`212-using-old-consensus.txt`](/proposals/212-using-old-consensus.txt): Increase Acceptable Consensus Age [NEEDS-REVISION]
-* [`213-remove-stream-sendmes.txt`](/proposals/213-remove-stream-sendmes.txt): Remove stream-level sendmes from the design [DEAD]
-* [`214-longer-circids.txt`](/proposals/214-longer-circids.txt): Allow 4-byte circuit IDs in a new link protocol [CLOSED]
-* [`215-update-min-consensus-ver.txt`](/proposals/215-update-min-consensus-ver.txt): Let the minimum consensus method change with time [CLOSED]
-* [`216-ntor-handshake.txt`](/proposals/216-ntor-handshake.txt): Improved circuit-creation key exchange [CLOSED]
-* [`217-ext-orport-auth.txt`](/proposals/217-ext-orport-auth.txt): Tor Extended ORPort Authentication [CLOSED]
-* [`218-usage-controller-events.txt`](/proposals/218-usage-controller-events.txt): Controller events to better understand connection/circuit usage [CLOSED]
-* [`219-expanded-dns.txt`](/proposals/219-expanded-dns.txt): Support for full DNS and DNSSEC resolution in Tor [NEEDS-REVISION]
-* [`220-ecc-id-keys.txt`](/proposals/220-ecc-id-keys.txt): Migrate server identity keys to Ed25519 [CLOSED]
-* [`221-stop-using-create-fast.txt`](/proposals/221-stop-using-create-fast.txt): Stop using CREATE_FAST [CLOSED]
-* [`222-remove-client-timestamps.txt`](/proposals/222-remove-client-timestamps.txt): Stop sending client timestamps [CLOSED]
-* [`223-ace-handshake.txt`](/proposals/223-ace-handshake.txt): Ace: Improved circuit-creation key exchange [RESERVE]
-* [`224-rend-spec-ng.txt`](/proposals/224-rend-spec-ng.txt): Next-Generation Hidden Services in Tor [CLOSED]
-* [`225-strawman-shared-rand.txt`](/proposals/225-strawman-shared-rand.txt): Strawman proposal: commit-and-reveal shared rng [SUPERSEDED]
-* [`226-bridgedb-database-improvements.txt`](/proposals/226-bridgedb-database-improvements.txt): "Scalability and Stability Improvements to BridgeDB: Switching to a Distributed Database System and RDBMS" [RESERVE]
-* [`227-vote-on-package-fingerprints.txt`](/proposals/227-vote-on-package-fingerprints.txt): Include package fingerprints in consensus documents [CLOSED]
-* [`228-cross-certification-onionkeys.txt`](/proposals/228-cross-certification-onionkeys.txt): Cross-certifying identity keys with onion keys [CLOSED]
-* [`229-further-socks5-extensions.txt`](/proposals/229-further-socks5-extensions.txt): Further SOCKS5 extensions [REJECTED]
-* [`230-rsa1024-relay-id-migration.txt`](/proposals/230-rsa1024-relay-id-migration.txt): How to change RSA1024 relay identity keys [OBSOLETE]
-* [`231-migrate-authority-rsa1024-ids.txt`](/proposals/231-migrate-authority-rsa1024-ids.txt): Migrating authority RSA1024 identity keys [OBSOLETE]
-* [`232-pluggable-transports-through-proxy.txt`](/proposals/232-pluggable-transports-through-proxy.txt): Pluggable Transport through SOCKS proxy [CLOSED]
-* [`233-quicken-tor2web-mode.txt`](/proposals/233-quicken-tor2web-mode.txt): Making Tor2Web mode faster [REJECTED]
-* [`234-remittance-addresses.txt`](/proposals/234-remittance-addresses.txt): Adding remittance field to directory specification [REJECTED]
-* [`235-kill-named-flag.txt`](/proposals/235-kill-named-flag.txt): Stop assigning (and eventually supporting) the Named flag [CLOSED]
-* [`236-single-guard-node.txt`](/proposals/236-single-guard-node.txt): The move to a single guard node [CLOSED]
-* [`237-directory-servers-for-all.txt`](/proposals/237-directory-servers-for-all.txt): All relays are directory servers [CLOSED]
-* [`238-hs-relay-stats.txt`](/proposals/238-hs-relay-stats.txt): Better hidden service stats from Tor relays [CLOSED]
-* [`239-consensus-hash-chaining.txt`](/proposals/239-consensus-hash-chaining.txt): Consensus Hash Chaining [OPEN]
-* [`240-auth-cert-revocation.txt`](/proposals/240-auth-cert-revocation.txt): Early signing key revocation for directory authorities [OPEN]
-* [`241-suspicious-guard-turnover.txt`](/proposals/241-suspicious-guard-turnover.txt): Resisting guard-turnover attacks [REJECTED]
-* [`242-better-families.txt`](/proposals/242-better-families.txt): Better performance and usability for the MyFamily option [SUPERSEDED]
-* [`243-hsdir-flag-need-stable.txt`](/proposals/243-hsdir-flag-need-stable.txt): Give out HSDir flag only to relays with Stable flag [CLOSED]
-* [`244-use-rfc5705-for-tls-binding.txt`](/proposals/244-use-rfc5705-for-tls-binding.txt): Use RFC5705 Key Exporting in our AUTHENTICATE calls [CLOSED]
-* [`245-tap-out.txt`](/proposals/245-tap-out.txt): Deprecating and removing the TAP circuit extension protocol [NEEDS-REVISION]
-* [`246-merge-hsdir-and-intro.txt`](/proposals/246-merge-hsdir-and-intro.txt): Merging Hidden Service Directories and Introduction Points [REJECTED]
-* [`247-hs-guard-discovery.txt`](/proposals/247-hs-guard-discovery.txt): Defending Against Guard Discovery Attacks using Vanguards [SUPERSEDED]
-* [`248-removing-rsa-identities.txt`](/proposals/248-removing-rsa-identities.txt): Remove all RSA identity keys [NEEDS-REVISION]
-* [`249-large-create-cells.txt`](/proposals/249-large-create-cells.txt): Allow CREATE cells with >505 bytes of handshake data [SUPERSEDED]
-* [`250-commit-reveal-consensus.txt`](/proposals/250-commit-reveal-consensus.txt): Random Number Generation During Tor Voting [CLOSED]
-* [`251-netflow-padding.txt`](/proposals/251-netflow-padding.txt): Padding for netflow record resolution reduction [CLOSED]
-* [`252-single-onion.txt`](/proposals/252-single-onion.txt): Single Onion Services [SUPERSEDED]
-* [`253-oob-hmac.txt`](/proposals/253-oob-hmac.txt): Out of Band Circuit HMACs [DEAD]
-* [`254-padding-negotiation.txt`](/proposals/254-padding-negotiation.txt): Padding Negotiation [CLOSED]
-* [`255-hs-load-balancing.txt`](/proposals/255-hs-load-balancing.txt): Controller features to allow for load-balancing hidden services [RESERVE]
-* [`256-key-revocation.txt`](/proposals/256-key-revocation.txt): Key revocation for relays and authorities [RESERVE]
-* [`257-hiding-authorities.txt`](/proposals/257-hiding-authorities.txt): Refactoring authorities and making them more isolated from the net [META]
-* [`258-dirauth-dos.txt`](/proposals/258-dirauth-dos.txt): Denial-of-service resistance for directory authorities [DEAD]
-* [`259-guard-selection.txt`](/proposals/259-guard-selection.txt): New Guard Selection Behaviour [OBSOLETE]
-* [`260-rend-single-onion.txt`](/proposals/260-rend-single-onion.txt): Rendezvous Single Onion Services [FINISHED]
-* [`261-aez-crypto.txt`](/proposals/261-aez-crypto.txt): AEZ for relay cryptography [OBSOLETE]
-* [`262-rekey-circuits.txt`](/proposals/262-rekey-circuits.txt): Re-keying live circuits with new cryptographic material [RESERVE]
-* [`263-ntru-for-pq-handshake.txt`](/proposals/263-ntru-for-pq-handshake.txt): Request to change key exchange protocol for handshake v1.2 [OBSOLETE]
-* [`264-subprotocol-versions.txt`](/proposals/264-subprotocol-versions.txt): Putting version numbers on the Tor subprotocols [CLOSED]
-* [`265-load-balancing-with-overhead.txt`](/proposals/265-load-balancing-with-overhead.txt): Load Balancing with Overhead Parameters [OPEN]
-* [`266-removing-current-obsolete-clients.txt`](/proposals/266-removing-current-obsolete-clients.txt): Removing current obsolete clients from the Tor network [SUPERSEDED]
-* [`267-tor-consensus-transparency.txt`](/proposals/267-tor-consensus-transparency.txt): Tor Consensus Transparency [OPEN]
-* [`268-guard-selection.txt`](/proposals/268-guard-selection.txt): New Guard Selection Behaviour [OBSOLETE]
-* [`269-hybrid-handshake.txt`](/proposals/269-hybrid-handshake.txt): Transitionally secure hybrid handshakes [NEEDS-REVISION]
-* [`270-newhope-hybrid-handshake.txt`](/proposals/270-newhope-hybrid-handshake.txt): RebelAlliance: A Post-Quantum Secure Hybrid Handshake Based on NewHope [OBSOLETE]
-* [`271-another-guard-selection.txt`](/proposals/271-another-guard-selection.txt): Another algorithm for guard selection [CLOSED]
-* [`272-valid-and-running-by-default.txt`](/proposals/272-valid-and-running-by-default.txt): Listed routers should be Valid, Running, and treated as such [CLOSED]
-* [`273-exit-relay-pinning.txt`](/proposals/273-exit-relay-pinning.txt): Exit relay pinning for web services [RESERVE]
-* [`274-rotate-onion-keys-less.txt`](/proposals/274-rotate-onion-keys-less.txt): Rotate onion keys less frequently [CLOSED]
-* [`275-md-published-time-is-silly.txt`](/proposals/275-md-published-time-is-silly.txt): Stop including meaningful "published" time in microdescriptor consensus [CLOSED]
-* [`276-lower-bw-granularity.txt`](/proposals/276-lower-bw-granularity.txt): Report bandwidth with lower granularity in consensus documents [DEAD]
-* [`277-detect-id-sharing.txt`](/proposals/277-detect-id-sharing.txt): Detect multiple relay instances running with same ID [OPEN]
-* [`278-directory-compression-scheme-negotiation.txt`](/proposals/278-directory-compression-scheme-negotiation.txt): Directory Compression Scheme Negotiation [CLOSED]
-* [`279-naming-layer-api.txt`](/proposals/279-naming-layer-api.txt): A Name System API for Tor Onion Services [NEEDS-REVISION]
-* [`280-privcount-in-tor.txt`](/proposals/280-privcount-in-tor.txt): Privacy-Preserving Statistics with Privcount in Tor [SUPERSEDED]
-* [`281-bulk-md-download.txt`](/proposals/281-bulk-md-download.txt): Downloading microdescriptors in bulk [RESERVE]
-* [`282-remove-named-from-consensus.txt`](/proposals/282-remove-named-from-consensus.txt): Remove "Named" and "Unnamed" handling from consensus voting [ACCEPTED]
-* [`283-ipv6-in-micro-consensus.txt`](/proposals/283-ipv6-in-micro-consensus.txt): Move IPv6 ORPorts from microdescriptors to the microdesc consensus [CLOSED]
-* [`284-hsv3-control-port.txt`](/proposals/284-hsv3-control-port.txt): Hidden Service v3 Control Port [CLOSED]
-* [`285-utf-8.txt`](/proposals/285-utf-8.txt): Directory documents should be standardized as UTF-8 [ACCEPTED]
-* [`286-hibernation-api.txt`](/proposals/286-hibernation-api.txt): Controller APIs for hibernation access on mobile [REJECTED]
-* [`287-reduce-lifetime.txt`](/proposals/287-reduce-lifetime.txt): Reduce circuit lifetime without overloading the network [OPEN]
-* [`288-privcount-with-shamir.txt`](/proposals/288-privcount-with-shamir.txt): Privacy-Preserving Statistics with Privcount in Tor (Shamir version) [RESERVE]
-* [`289-authenticated-sendmes.txt`](/proposals/289-authenticated-sendmes.txt): Authenticating sendme cells to mitigate bandwidth attacks [CLOSED]
-* [`290-deprecate-consensus-methods.txt`](/proposals/290-deprecate-consensus-methods.txt): Continuously update consensus methods [META]
-* [`291-two-guard-nodes.txt`](/proposals/291-two-guard-nodes.txt): The move to two guard nodes [FINISHED]
-* [`292-mesh-vanguards.txt`](/proposals/292-mesh-vanguards.txt): Mesh-based vanguards [CLOSED]
-* [`293-know-when-to-publish.txt`](/proposals/293-know-when-to-publish.txt): Other ways for relays to know when to publish [CLOSED]
-* [`294-tls-1.3.txt`](/proposals/294-tls-1.3.txt): TLS 1.3 Migration [DRAFT]
-* [`295-relay-crypto-with-adl.txt`](/proposals/295-relay-crypto-with-adl.txt): Using ADL for relay cryptography (solving the crypto-tagging attack) [OPEN]
-* [`296-expose-bandwidth-files.txt`](/proposals/296-expose-bandwidth-files.txt): Have Directory Authorities expose raw bandwidth list files [CLOSED]
-* [`297-safer-protover-shutdowns.txt`](/proposals/297-safer-protover-shutdowns.txt): Relaxing the protover-based shutdown rules [CLOSED]
-* [`298-canonical-families.txt`](/proposals/298-canonical-families.txt): Putting family lines in canonical form [CLOSED]
-* [`299-ip-failure-count.txt`](/proposals/299-ip-failure-count.txt): Preferring IPv4 or IPv6 based on IP Version Failure Count [SUPERSEDED]
-* [`300-walking-onions.txt`](/proposals/300-walking-onions.txt): Walking Onions: Scaling and Saving Bandwidth [INFORMATIONAL]
-* [`301-dont-vote-on-package-fingerprints.txt`](/proposals/301-dont-vote-on-package-fingerprints.txt): Don't include package fingerprints in consensus documents [CLOSED]
-* [`302-padding-machines-for-onion-clients.txt`](/proposals/302-padding-machines-for-onion-clients.txt): Hiding onion service clients using padding [CLOSED]
-* [`303-protover-removal-policy.txt`](/proposals/303-protover-removal-policy.txt): When and how to remove support for protocol versions [OPEN]
-* [`304-socks5-extending-hs-error-codes.txt`](/proposals/304-socks5-extending-hs-error-codes.txt): Extending SOCKS5 Onion Service Error Codes [CLOSED]
-* [`305-establish-intro-dos-defense-extention.txt`](/proposals/305-establish-intro-dos-defense-extention.txt): ESTABLISH_INTRO Cell DoS Defense Extension [CLOSED]
-* [`306-ipv6-happy-eyeballs.txt`](/proposals/306-ipv6-happy-eyeballs.txt): A Tor Implementation of IPv6 Happy Eyeballs [OPEN]
-* [`307-onionbalance-v3.txt`](/proposals/307-onionbalance-v3.txt): Onion Balance Support for Onion Service v3 [RESERVE]
-* [`308-counter-galois-onion.txt`](/proposals/308-counter-galois-onion.txt): Counter Galois Onion: A New Proposal for Forward-Secure Relay Cryptography [SUPERSEDED]
-* [`309-optimistic-socks-in-tor.txt`](/proposals/309-optimistic-socks-in-tor.txt): Optimistic SOCKS Data [OPEN]
-* [`310-bandaid-on-guard-selection.txt`](/proposals/310-bandaid-on-guard-selection.txt): Towards load-balancing in Prop 271 [CLOSED]
-* [`311-relay-ipv6-reachability.txt`](/proposals/311-relay-ipv6-reachability.txt): Tor Relay IPv6 Reachability [ACCEPTED]
-* [`312-relay-auto-ipv6-addr.txt`](/proposals/312-relay-auto-ipv6-addr.txt): Tor Relay Automatic IPv6 Address Discovery [ACCEPTED]
-* [`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 [CLOSED]
-* [`315-update-dir-required-fields.txt`](/proposals/315-update-dir-required-fields.txt): Updating the list of fields required in directory documents [CLOSED]
-* [`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 [CLOSED]
-* [`319-wide-everything.md`](/proposals/319-wide-everything.md): RELAY_FRAGMENT cells [OBSOLETE]
-* [`320-tap-out-again.md`](/proposals/320-tap-out-again.md): Removing TAP usage from v2 onion services [REJECTED]
-* [`321-happy-families.md`](/proposals/321-happy-families.md): Better performance and usability for the MyFamily option (v2) [ACCEPTED]
-* [`322-dirport-linkspec.md`](/proposals/322-dirport-linkspec.md): Extending link specifiers to include the directory port [OPEN]
-* [`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 [FINISHED]
-* [`325-packed-relay-cells.md`](/proposals/325-packed-relay-cells.md): Packed relay cells: saving space on small commands [OBSOLETE]
-* [`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 [FINISHED]
-* [`328-relay-overload-report.md`](/proposals/328-relay-overload-report.md): Make Relays Report When They Are Overloaded [CLOSED]
-* [`329-traffic-splitting.txt`](/proposals/329-traffic-splitting.txt): Overcoming Tor's Bottlenecks with Traffic Splitting [FINISHED]
-* [`330-authority-contact.md`](/proposals/330-authority-contact.md): Modernizing authority contact entries [OPEN]
-* [`331-res-tokens-for-anti-dos.md`](/proposals/331-res-tokens-for-anti-dos.md): Res tokens: Anonymous Credentials for Onion Service DoS Resilience [DRAFT]
-* [`332-ntor-v3-with-extra-data.md`](/proposals/332-ntor-v3-with-extra-data.md): Ntor protocol with extra data, version 3 [CLOSED]
-* [`333-vanguards-lite.md`](/proposals/333-vanguards-lite.md): Vanguards lite [CLOSED]
-* [`334-middle-only-flag.txt`](/proposals/334-middle-only-flag.txt): A Directory Authority Flag To Mark Relays As Middle-only [SUPERSEDED]
-* [`335-middle-only-redux.md`](/proposals/335-middle-only-redux.md): An authority-only design for MiddleOnly [CLOSED]
-* [`336-randomize-guard-retries.md`](/proposals/336-randomize-guard-retries.md): Randomized schedule for guard retries [CLOSED]
-* [`337-simpler-guard-usability.md`](/proposals/337-simpler-guard-usability.md): A simpler way to decide, "Is this guard usable?" [CLOSED]
-* [`338-netinfo-y2038.md`](/proposals/338-netinfo-y2038.md): Use an 8-byte timestamp in NETINFO cells [ACCEPTED]
-* [`339-udp-over-tor.md`](/proposals/339-udp-over-tor.md): UDP traffic over Tor [ACCEPTED]
-* [`340-packed-and-fragmented.md`](/proposals/340-packed-and-fragmented.md): Packed and fragmented relay messages [OPEN]
-* [`341-better-oos.md`](/proposals/341-better-oos.md): A better algorithm for out-of-sockets eviction [OPEN]
-* [`342-decouple-hs-interval.md`](/proposals/342-decouple-hs-interval.md): Decoupling hs_interval and SRV lifetime [DRAFT]
-* [`343-rend-caa.txt`](/proposals/343-rend-caa.txt): CAA Extensions for the Tor Rendezvous Specification [OPEN]
-* [`344-protocol-info-leaks.txt`](/proposals/344-protocol-info-leaks.txt): Prioritizing Protocol Information Leaks in Tor [OPEN]
-* [`345-specs-in-mdbook.md`](/proposals/345-specs-in-mdbook.md): Migrating the tor specifications to mdbook [CLOSED]
-* [`346-protovers-again.md`](/proposals/346-protovers-again.md): Clarifying and extending the use of protocol versioning [OPEN]
-* [`347-domain-separation.md`](/proposals/347-domain-separation.md): Domain separation for certificate signing keys [OPEN]
+* [`000-index.txt`](/proposals/000-index.txt): Index of Tor Proposals \[META\]
+* [`001-process.txt`](/proposals/001-process.txt): The Tor Proposal Process \[META\]
+* [`098-todo.txt`](/proposals/098-todo.txt): Proposals that should be written \[OBSOLETE\]
+* [`099-misc.txt`](/proposals/099-misc.txt): Miscellaneous proposals \[OBSOLETE\]
+* [`100-tor-spec-udp.txt`](/proposals/100-tor-spec-udp.txt): Tor Unreliable Datagram Extension Proposal \[DEAD\]
+* [`101-dir-voting.txt`](/proposals/101-dir-voting.txt): Voting on the Tor Directory System \[CLOSED\]
+* [`102-drop-opt.txt`](/proposals/102-drop-opt.txt): Dropping "opt" from the directory format \[CLOSED\]
+* [`103-multilevel-keys.txt`](/proposals/103-multilevel-keys.txt): Splitting identity key from regularly used signing key \[CLOSED\]
+* [`104-short-descriptors.txt`](/proposals/104-short-descriptors.txt): Long and Short Router Descriptors \[CLOSED\]
+* [`105-handshake-revision.txt`](/proposals/105-handshake-revision.txt): Version negotiation for the Tor protocol \[CLOSED\]
+* [`106-less-tls-constraint.txt`](/proposals/106-less-tls-constraint.txt): Checking fewer things during TLS handshakes \[CLOSED\]
+* [`107-uptime-sanity-checking.txt`](/proposals/107-uptime-sanity-checking.txt): Uptime Sanity Checking \[CLOSED\]
+* [`108-mtbf-based-stability.txt`](/proposals/108-mtbf-based-stability.txt): Base "Stable" Flag on Mean Time Between Failures \[CLOSED\]
+* [`109-no-sharing-ips.txt`](/proposals/109-no-sharing-ips.txt): No more than one server per IP address \[CLOSED\]
+* [`110-avoid-infinite-circuits.txt`](/proposals/110-avoid-infinite-circuits.txt): Avoiding infinite length circuits \[CLOSED\]
+* [`111-local-traffic-priority.txt`](/proposals/111-local-traffic-priority.txt): Prioritizing local traffic over relayed traffic \[CLOSED\]
+* [`112-bring-back-pathlencoinweight.txt`](/proposals/112-bring-back-pathlencoinweight.txt): Bring Back Pathlen Coin Weight \[SUPERSEDED\]
+* [`113-fast-authority-interface.txt`](/proposals/113-fast-authority-interface.txt): Simplifying directory authority administration \[SUPERSEDED\]
+* [`114-distributed-storage.txt`](/proposals/114-distributed-storage.txt): Distributed Storage for Tor Hidden Service Descriptors \[CLOSED\]
+* [`115-two-hop-paths.txt`](/proposals/115-two-hop-paths.txt): Two Hop Paths \[DEAD\]
+* [`116-two-hop-paths-from-guard.txt`](/proposals/116-two-hop-paths-from-guard.txt): Two hop paths from entry guards \[DEAD\]
+* [`117-ipv6-exits.txt`](/proposals/117-ipv6-exits.txt): IPv6 exits \[CLOSED\]
+* [`118-multiple-orports.txt`](/proposals/118-multiple-orports.txt): Advertising multiple ORPorts at once \[SUPERSEDED\]
+* [`119-controlport-auth.txt`](/proposals/119-controlport-auth.txt): New PROTOCOLINFO command for controllers \[CLOSED\]
+* [`120-shutdown-descriptors.txt`](/proposals/120-shutdown-descriptors.txt): Shutdown descriptors when Tor servers stop \[DEAD\]
+* [`121-hidden-service-authentication.txt`](/proposals/121-hidden-service-authentication.txt): Hidden Service Authentication \[CLOSED\]
+* [`122-unnamed-flag.txt`](/proposals/122-unnamed-flag.txt): Network status entries need a new Unnamed flag \[CLOSED\]
+* [`123-autonaming.txt`](/proposals/123-autonaming.txt): Naming authorities automatically create bindings \[CLOSED\]
+* [`124-tls-certificates.txt`](/proposals/124-tls-certificates.txt): Blocking resistant TLS certificate usage \[SUPERSEDED\]
+* [`125-bridges.txt`](/proposals/125-bridges.txt): Behavior for bridge users, bridge relays, and bridge authorities \[CLOSED\]
+* [`126-geoip-reporting.txt`](/proposals/126-geoip-reporting.txt): Getting GeoIP data and publishing usage summaries \[CLOSED\]
+* [`127-dirport-mirrors-downloads.txt`](/proposals/127-dirport-mirrors-downloads.txt): Relaying dirport requests to Tor download site / website \[OBSOLETE\]
+* [`128-bridge-families.txt`](/proposals/128-bridge-families.txt): Families of private bridges \[DEAD\]
+* [`129-reject-plaintext-ports.txt`](/proposals/129-reject-plaintext-ports.txt): Block Insecure Protocols by Default \[CLOSED\]
+* [`130-v2-conn-protocol.txt`](/proposals/130-v2-conn-protocol.txt): Version 2 Tor connection protocol \[CLOSED\]
+* [`131-verify-tor-usage.txt`](/proposals/131-verify-tor-usage.txt): Help users to verify they are using Tor \[OBSOLETE\]
+* [`132-browser-check-tor-service.txt`](/proposals/132-browser-check-tor-service.txt): A Tor Web Service For Verifying Correct Browser Configuration \[OBSOLETE\]
+* [`133-unreachable-ors.txt`](/proposals/133-unreachable-ors.txt): Incorporate Unreachable ORs into the Tor Network \[RESERVE\]
+* [`134-robust-voting.txt`](/proposals/134-robust-voting.txt): More robust consensus voting with diverse authority sets \[REJECTED\]
+* [`135-private-tor-networks.txt`](/proposals/135-private-tor-networks.txt): Simplify Configuration of Private Tor Networks \[CLOSED\]
+* [`136-legacy-keys.txt`](/proposals/136-legacy-keys.txt): Mass authority migration with legacy keys \[CLOSED\]
+* [`137-bootstrap-phases.txt`](/proposals/137-bootstrap-phases.txt): Keep controllers informed as Tor bootstraps \[CLOSED\]
+* [`138-remove-down-routers-from-consensus.txt`](/proposals/138-remove-down-routers-from-consensus.txt): Remove routers that are not Running from consensus documents \[CLOSED\]
+* [`139-conditional-consensus-download.txt`](/proposals/139-conditional-consensus-download.txt): Download consensus documents only when it will be trusted \[CLOSED\]
+* [`140-consensus-diffs.txt`](/proposals/140-consensus-diffs.txt): Provide diffs between consensuses \[CLOSED\]
+* [`141-jit-sd-downloads.txt`](/proposals/141-jit-sd-downloads.txt): Download server descriptors on demand \[OBSOLETE\]
+* [`142-combine-intro-and-rend-points.txt`](/proposals/142-combine-intro-and-rend-points.txt): Combine Introduction and Rendezvous Points \[DEAD\]
+* [`143-distributed-storage-improvements.txt`](/proposals/143-distributed-storage-improvements.txt): Improvements of Distributed Storage for Tor Hidden Service Descriptors \[SUPERSEDED\]
+* [`144-enforce-distinct-providers.txt`](/proposals/144-enforce-distinct-providers.txt): Increase the diversity of circuits by detecting nodes belonging the same provider \[OBSOLETE\]
+* [`145-newguard-flag.txt`](/proposals/145-newguard-flag.txt): Separate "suitable as a guard" from "suitable as a new guard" \[SUPERSEDED\]
+* [`146-long-term-stability.txt`](/proposals/146-long-term-stability.txt): Add new flag to reflect long-term stability \[SUPERSEDED\]
+* [`147-prevoting-opinions.txt`](/proposals/147-prevoting-opinions.txt): Eliminate the need for v2 directories in generating v3 directories \[REJECTED\]
+* [`148-uniform-client-end-reason.txt`](/proposals/148-uniform-client-end-reason.txt): Stream end reasons from the client side should be uniform \[CLOSED\]
+* [`149-using-netinfo-data.txt`](/proposals/149-using-netinfo-data.txt): Using data from NETINFO cells \[SUPERSEDED\]
+* [`150-exclude-exit-nodes.txt`](/proposals/150-exclude-exit-nodes.txt): Exclude Exit Nodes from a circuit \[CLOSED\]
+* [`151-path-selection-improvements.txt`](/proposals/151-path-selection-improvements.txt): Improving Tor Path Selection \[CLOSED\]
+* [`152-single-hop-circuits.txt`](/proposals/152-single-hop-circuits.txt): Optionally allow exit from single-hop circuits \[CLOSED\]
+* [`153-automatic-software-update-protocol.txt`](/proposals/153-automatic-software-update-protocol.txt): Automatic software update protocol \[SUPERSEDED\]
+* [`154-automatic-updates.txt`](/proposals/154-automatic-updates.txt): Automatic Software Update Protocol \[SUPERSEDED\]
+* [`155-four-hidden-service-improvements.txt`](/proposals/155-four-hidden-service-improvements.txt): Four Improvements of Hidden Service Performance \[CLOSED\]
+* [`156-tracking-blocked-ports.txt`](/proposals/156-tracking-blocked-ports.txt): Tracking blocked ports on the client side \[SUPERSEDED\]
+* [`157-specific-cert-download.txt`](/proposals/157-specific-cert-download.txt): Make certificate downloads specific \[CLOSED\]
+* [`158-microdescriptors.txt`](/proposals/158-microdescriptors.txt): Clients download consensus + microdescriptors \[CLOSED\]
+* [`159-exit-scanning.txt`](/proposals/159-exit-scanning.txt): Exit Scanning \[INFORMATIONAL\]
+* [`160-bandwidth-offset.txt`](/proposals/160-bandwidth-offset.txt): Authorities vote for bandwidth offsets in consensus \[CLOSED\]
+* [`161-computing-bandwidth-adjustments.txt`](/proposals/161-computing-bandwidth-adjustments.txt): Computing Bandwidth Adjustments \[CLOSED\]
+* [`162-consensus-flavors.txt`](/proposals/162-consensus-flavors.txt): Publish the consensus in multiple flavors \[CLOSED\]
+* [`163-detecting-clients.txt`](/proposals/163-detecting-clients.txt): Detecting whether a connection comes from a client \[SUPERSEDED\]
+* [`164-reporting-server-status.txt`](/proposals/164-reporting-server-status.txt): Reporting the status of server votes \[OBSOLETE\]
+* [`165-simple-robust-voting.txt`](/proposals/165-simple-robust-voting.txt): Easy migration for voting authority sets \[REJECTED\]
+* [`166-statistics-extra-info-docs.txt`](/proposals/166-statistics-extra-info-docs.txt): Including Network Statistics in Extra-Info Documents \[CLOSED\]
+* [`167-params-in-consensus.txt`](/proposals/167-params-in-consensus.txt): Vote on network parameters in consensus \[CLOSED\]
+* [`168-reduce-circwindow.txt`](/proposals/168-reduce-circwindow.txt): Reduce default circuit window \[REJECTED\]
+* [`169-eliminating-renegotiation.txt`](/proposals/169-eliminating-renegotiation.txt): Eliminate TLS renegotiation for the Tor connection handshake \[SUPERSEDED\]
+* [`170-user-path-config.txt`](/proposals/170-user-path-config.txt): Configuration options regarding circuit building \[SUPERSEDED\]
+* [`171-separate-streams.txt`](/proposals/171-separate-streams.txt): Separate streams across circuits by connection metadata \[CLOSED\]
+* [`172-circ-getinfo-option.txt`](/proposals/172-circ-getinfo-option.txt): GETINFO controller option for circuit information \[RESERVE\]
+* [`173-getinfo-option-expansion.txt`](/proposals/173-getinfo-option-expansion.txt): GETINFO Option Expansion \[OBSOLETE\]
+* [`174-optimistic-data-server.txt`](/proposals/174-optimistic-data-server.txt): Optimistic Data for Tor: Server Side \[CLOSED\]
+* [`175-automatic-node-promotion.txt`](/proposals/175-automatic-node-promotion.txt): Automatically promoting Tor clients to nodes \[REJECTED\]
+* [`176-revising-handshake.txt`](/proposals/176-revising-handshake.txt): Proposed version-3 link handshake for Tor \[CLOSED\]
+* [`177-flag-abstention.txt`](/proposals/177-flag-abstention.txt): Abstaining from votes on individual flags \[RESERVE\]
+* [`178-param-voting.txt`](/proposals/178-param-voting.txt): Require majority of authorities to vote for consensus parameters \[CLOSED\]
+* [`179-TLS-cert-and-parameter-normalization.txt`](/proposals/179-TLS-cert-and-parameter-normalization.txt): TLS certificate and parameter normalization \[CLOSED\]
+* [`180-pluggable-transport.txt`](/proposals/180-pluggable-transport.txt): Pluggable transports for circumvention \[CLOSED\]
+* [`181-optimistic-data-client.txt`](/proposals/181-optimistic-data-client.txt): Optimistic Data for Tor: Client Side \[CLOSED\]
+* [`182-creditbucket.txt`](/proposals/182-creditbucket.txt): Credit Bucket \[OBSOLETE\]
+* [`183-refillintervals.txt`](/proposals/183-refillintervals.txt): Refill Intervals \[CLOSED\]
+* [`184-v3-link-protocol.txt`](/proposals/184-v3-link-protocol.txt): Miscellaneous changes for a v3 Tor link protocol \[CLOSED\]
+* [`185-dir-without-dirport.txt`](/proposals/185-dir-without-dirport.txt): Directory caches without DirPort \[SUPERSEDED\]
+* [`186-multiple-orports.txt`](/proposals/186-multiple-orports.txt): Multiple addresses for one OR or bridge \[CLOSED\]
+* [`187-allow-client-auth.txt`](/proposals/187-allow-client-auth.txt): Reserve a cell type to allow client authorization \[CLOSED\]
+* [`188-bridge-guards.txt`](/proposals/188-bridge-guards.txt): Bridge Guards and other anti-enumeration defenses \[RESERVE\]
+* [`189-authorize-cell.txt`](/proposals/189-authorize-cell.txt): AUTHORIZE and AUTHORIZED cells \[OBSOLETE\]
+* [`190-shared-secret-bridge-authorization.txt`](/proposals/190-shared-secret-bridge-authorization.txt): Bridge Client Authorization Based on a Shared Secret \[OBSOLETE\]
+* [`191-mitm-bridge-detection-resistance.txt`](/proposals/191-mitm-bridge-detection-resistance.txt): Bridge Detection Resistance against MITM-capable Adversaries \[OBSOLETE\]
+* [`192-store-bridge-information.txt`](/proposals/192-store-bridge-information.txt): Automatically retrieve and store information about bridges \[OBSOLETE\]
+* [`193-safe-cookie-authentication.txt`](/proposals/193-safe-cookie-authentication.txt): Safe cookie authentication for Tor controllers \[CLOSED\]
+* [`194-mnemonic-urls.txt`](/proposals/194-mnemonic-urls.txt): Mnemonic .onion URLs \[SUPERSEDED\]
+* [`195-TLS-normalization-for-024.txt`](/proposals/195-TLS-normalization-for-024.txt): TLS certificate normalization for Tor 0.2.4.x \[DEAD\]
+* [`196-transport-control-ports.txt`](/proposals/196-transport-control-ports.txt): Extended ORPort and TransportControlPort \[CLOSED\]
+* [`197-postmessage-ipc.txt`](/proposals/197-postmessage-ipc.txt): Message-based Inter-Controller IPC Channel \[REJECTED\]
+* [`198-restore-clienthello-semantics.txt`](/proposals/198-restore-clienthello-semantics.txt): Restore semantics of TLS ClientHello \[CLOSED\]
+* [`199-bridgefinder-integration.txt`](/proposals/199-bridgefinder-integration.txt): Integration of BridgeFinder and BridgeFinderHelper \[OBSOLETE\]
+* [`200-new-create-and-extend-cells.txt`](/proposals/200-new-create-and-extend-cells.txt): Adding new, extensible CREATE, EXTEND, and related cells \[CLOSED\]
+* [`201-bridge-v3-reqs-stats.txt`](/proposals/201-bridge-v3-reqs-stats.txt): Make bridges report statistics on daily v3 network status requests \[RESERVE\]
+* [`202-improved-relay-crypto.txt`](/proposals/202-improved-relay-crypto.txt): Two improved relay encryption protocols for Tor cells \[META\]
+* [`203-https-frontend.txt`](/proposals/203-https-frontend.txt): Avoiding censorship by impersonating an HTTPS server \[OBSOLETE\]
+* [`204-hidserv-subdomains.txt`](/proposals/204-hidserv-subdomains.txt): Subdomain support for Hidden Service addresses \[CLOSED\]
+* [`205-local-dnscache.txt`](/proposals/205-local-dnscache.txt): Remove global client-side DNS caching \[CLOSED\]
+* [`206-directory-sources.txt`](/proposals/206-directory-sources.txt): Preconfigured directory sources for bootstrapping \[CLOSED\]
+* [`207-directory-guards.txt`](/proposals/207-directory-guards.txt): Directory guards \[CLOSED\]
+* [`208-ipv6-exits-redux.txt`](/proposals/208-ipv6-exits-redux.txt): IPv6 Exits Redux \[CLOSED\]
+* [`209-path-bias-tuning.txt`](/proposals/209-path-bias-tuning.txt): Tuning the Parameters for the Path Bias Defense \[OBSOLETE\]
+* [`210-faster-headless-consensus-bootstrap.txt`](/proposals/210-faster-headless-consensus-bootstrap.txt): Faster Headless Consensus Bootstrapping \[SUPERSEDED\]
+* [`211-mapaddress-tor-status.txt`](/proposals/211-mapaddress-tor-status.txt): Internal Mapaddress for Tor Configuration Testing \[RESERVE\]
+* [`212-using-old-consensus.txt`](/proposals/212-using-old-consensus.txt): Increase Acceptable Consensus Age \[NEEDS-REVISION\]
+* [`213-remove-stream-sendmes.txt`](/proposals/213-remove-stream-sendmes.txt): Remove stream-level sendmes from the design \[DEAD\]
+* [`214-longer-circids.txt`](/proposals/214-longer-circids.txt): Allow 4-byte circuit IDs in a new link protocol \[CLOSED\]
+* [`215-update-min-consensus-ver.txt`](/proposals/215-update-min-consensus-ver.txt): Let the minimum consensus method change with time \[CLOSED\]
+* [`216-ntor-handshake.txt`](/proposals/216-ntor-handshake.txt): Improved circuit-creation key exchange \[CLOSED\]
+* [`217-ext-orport-auth.txt`](/proposals/217-ext-orport-auth.txt): Tor Extended ORPort Authentication \[CLOSED\]
+* [`218-usage-controller-events.txt`](/proposals/218-usage-controller-events.txt): Controller events to better understand connection/circuit usage \[CLOSED\]
+* [`219-expanded-dns.txt`](/proposals/219-expanded-dns.txt): Support for full DNS and DNSSEC resolution in Tor \[NEEDS-REVISION\]
+* [`220-ecc-id-keys.txt`](/proposals/220-ecc-id-keys.txt): Migrate server identity keys to Ed25519 \[CLOSED\]
+* [`221-stop-using-create-fast.txt`](/proposals/221-stop-using-create-fast.txt): Stop using CREATE_FAST \[CLOSED\]
+* [`222-remove-client-timestamps.txt`](/proposals/222-remove-client-timestamps.txt): Stop sending client timestamps \[CLOSED\]
+* [`223-ace-handshake.txt`](/proposals/223-ace-handshake.txt): Ace: Improved circuit-creation key exchange \[RESERVE\]
+* [`224-rend-spec-ng.txt`](/proposals/224-rend-spec-ng.txt): Next-Generation Hidden Services in Tor \[CLOSED\]
+* [`225-strawman-shared-rand.txt`](/proposals/225-strawman-shared-rand.txt): Strawman proposal: commit-and-reveal shared rng \[SUPERSEDED\]
+* [`226-bridgedb-database-improvements.txt`](/proposals/226-bridgedb-database-improvements.txt): "Scalability and Stability Improvements to BridgeDB: Switching to a Distributed Database System and RDBMS" \[RESERVE\]
+* [`227-vote-on-package-fingerprints.txt`](/proposals/227-vote-on-package-fingerprints.txt): Include package fingerprints in consensus documents \[CLOSED\]
+* [`228-cross-certification-onionkeys.txt`](/proposals/228-cross-certification-onionkeys.txt): Cross-certifying identity keys with onion keys \[CLOSED\]
+* [`229-further-socks5-extensions.txt`](/proposals/229-further-socks5-extensions.txt): Further SOCKS5 extensions \[REJECTED\]
+* [`230-rsa1024-relay-id-migration.txt`](/proposals/230-rsa1024-relay-id-migration.txt): How to change RSA1024 relay identity keys \[OBSOLETE\]
+* [`231-migrate-authority-rsa1024-ids.txt`](/proposals/231-migrate-authority-rsa1024-ids.txt): Migrating authority RSA1024 identity keys \[OBSOLETE\]
+* [`232-pluggable-transports-through-proxy.txt`](/proposals/232-pluggable-transports-through-proxy.txt): Pluggable Transport through SOCKS proxy \[CLOSED\]
+* [`233-quicken-tor2web-mode.txt`](/proposals/233-quicken-tor2web-mode.txt): Making Tor2Web mode faster \[REJECTED\]
+* [`234-remittance-addresses.txt`](/proposals/234-remittance-addresses.txt): Adding remittance field to directory specification \[REJECTED\]
+* [`235-kill-named-flag.txt`](/proposals/235-kill-named-flag.txt): Stop assigning (and eventually supporting) the Named flag \[CLOSED\]
+* [`236-single-guard-node.txt`](/proposals/236-single-guard-node.txt): The move to a single guard node \[CLOSED\]
+* [`237-directory-servers-for-all.txt`](/proposals/237-directory-servers-for-all.txt): All relays are directory servers \[CLOSED\]
+* [`238-hs-relay-stats.txt`](/proposals/238-hs-relay-stats.txt): Better hidden service stats from Tor relays \[CLOSED\]
+* [`239-consensus-hash-chaining.txt`](/proposals/239-consensus-hash-chaining.txt): Consensus Hash Chaining \[OPEN\]
+* [`240-auth-cert-revocation.txt`](/proposals/240-auth-cert-revocation.txt): Early signing key revocation for directory authorities \[OPEN\]
+* [`241-suspicious-guard-turnover.txt`](/proposals/241-suspicious-guard-turnover.txt): Resisting guard-turnover attacks \[REJECTED\]
+* [`242-better-families.txt`](/proposals/242-better-families.txt): Better performance and usability for the MyFamily option \[SUPERSEDED\]
+* [`243-hsdir-flag-need-stable.txt`](/proposals/243-hsdir-flag-need-stable.txt): Give out HSDir flag only to relays with Stable flag \[CLOSED\]
+* [`244-use-rfc5705-for-tls-binding.txt`](/proposals/244-use-rfc5705-for-tls-binding.txt): Use RFC5705 Key Exporting in our AUTHENTICATE calls \[CLOSED\]
+* [`245-tap-out.txt`](/proposals/245-tap-out.txt): Deprecating and removing the TAP circuit extension protocol \[NEEDS-REVISION\]
+* [`246-merge-hsdir-and-intro.txt`](/proposals/246-merge-hsdir-and-intro.txt): Merging Hidden Service Directories and Introduction Points \[REJECTED\]
+* [`247-hs-guard-discovery.txt`](/proposals/247-hs-guard-discovery.txt): Defending Against Guard Discovery Attacks using Vanguards \[SUPERSEDED\]
+* [`248-removing-rsa-identities.txt`](/proposals/248-removing-rsa-identities.txt): Remove all RSA identity keys \[NEEDS-REVISION\]
+* [`249-large-create-cells.txt`](/proposals/249-large-create-cells.txt): Allow CREATE cells with >505 bytes of handshake data \[SUPERSEDED\]
+* [`250-commit-reveal-consensus.txt`](/proposals/250-commit-reveal-consensus.txt): Random Number Generation During Tor Voting \[CLOSED\]
+* [`251-netflow-padding.txt`](/proposals/251-netflow-padding.txt): Padding for netflow record resolution reduction \[CLOSED\]
+* [`252-single-onion.txt`](/proposals/252-single-onion.txt): Single Onion Services \[SUPERSEDED\]
+* [`253-oob-hmac.txt`](/proposals/253-oob-hmac.txt): Out of Band Circuit HMACs \[DEAD\]
+* [`254-padding-negotiation.txt`](/proposals/254-padding-negotiation.txt): Padding Negotiation \[CLOSED\]
+* [`255-hs-load-balancing.txt`](/proposals/255-hs-load-balancing.txt): Controller features to allow for load-balancing hidden services \[RESERVE\]
+* [`256-key-revocation.txt`](/proposals/256-key-revocation.txt): Key revocation for relays and authorities \[RESERVE\]
+* [`257-hiding-authorities.txt`](/proposals/257-hiding-authorities.txt): Refactoring authorities and making them more isolated from the net \[META\]
+* [`258-dirauth-dos.txt`](/proposals/258-dirauth-dos.txt): Denial-of-service resistance for directory authorities \[DEAD\]
+* [`259-guard-selection.txt`](/proposals/259-guard-selection.txt): New Guard Selection Behaviour \[OBSOLETE\]
+* [`260-rend-single-onion.txt`](/proposals/260-rend-single-onion.txt): Rendezvous Single Onion Services \[FINISHED\]
+* [`261-aez-crypto.txt`](/proposals/261-aez-crypto.txt): AEZ for relay cryptography \[OBSOLETE\]
+* [`262-rekey-circuits.txt`](/proposals/262-rekey-circuits.txt): Re-keying live circuits with new cryptographic material \[RESERVE\]
+* [`263-ntru-for-pq-handshake.txt`](/proposals/263-ntru-for-pq-handshake.txt): Request to change key exchange protocol for handshake v1.2 \[OBSOLETE\]
+* [`264-subprotocol-versions.txt`](/proposals/264-subprotocol-versions.txt): Putting version numbers on the Tor subprotocols \[CLOSED\]
+* [`265-load-balancing-with-overhead.txt`](/proposals/265-load-balancing-with-overhead.txt): Load Balancing with Overhead Parameters \[OPEN\]
+* [`266-removing-current-obsolete-clients.txt`](/proposals/266-removing-current-obsolete-clients.txt): Removing current obsolete clients from the Tor network \[SUPERSEDED\]
+* [`267-tor-consensus-transparency.txt`](/proposals/267-tor-consensus-transparency.txt): Tor Consensus Transparency \[OPEN\]
+* [`268-guard-selection.txt`](/proposals/268-guard-selection.txt): New Guard Selection Behaviour \[OBSOLETE\]
+* [`269-hybrid-handshake.txt`](/proposals/269-hybrid-handshake.txt): Transitionally secure hybrid handshakes \[NEEDS-REVISION\]
+* [`270-newhope-hybrid-handshake.txt`](/proposals/270-newhope-hybrid-handshake.txt): RebelAlliance: A Post-Quantum Secure Hybrid Handshake Based on NewHope \[OBSOLETE\]
+* [`271-another-guard-selection.txt`](/proposals/271-another-guard-selection.txt): Another algorithm for guard selection \[CLOSED\]
+* [`272-valid-and-running-by-default.txt`](/proposals/272-valid-and-running-by-default.txt): Listed routers should be Valid, Running, and treated as such \[CLOSED\]
+* [`273-exit-relay-pinning.txt`](/proposals/273-exit-relay-pinning.txt): Exit relay pinning for web services \[RESERVE\]
+* [`274-rotate-onion-keys-less.txt`](/proposals/274-rotate-onion-keys-less.txt): Rotate onion keys less frequently \[CLOSED\]
+* [`275-md-published-time-is-silly.txt`](/proposals/275-md-published-time-is-silly.txt): Stop including meaningful "published" time in microdescriptor consensus \[CLOSED\]
+* [`276-lower-bw-granularity.txt`](/proposals/276-lower-bw-granularity.txt): Report bandwidth with lower granularity in consensus documents \[DEAD\]
+* [`277-detect-id-sharing.txt`](/proposals/277-detect-id-sharing.txt): Detect multiple relay instances running with same ID \[OPEN\]
+* [`278-directory-compression-scheme-negotiation.txt`](/proposals/278-directory-compression-scheme-negotiation.txt): Directory Compression Scheme Negotiation \[CLOSED\]
+* [`279-naming-layer-api.txt`](/proposals/279-naming-layer-api.txt): A Name System API for Tor Onion Services \[NEEDS-REVISION\]
+* [`280-privcount-in-tor.txt`](/proposals/280-privcount-in-tor.txt): Privacy-Preserving Statistics with Privcount in Tor \[SUPERSEDED\]
+* [`281-bulk-md-download.txt`](/proposals/281-bulk-md-download.txt): Downloading microdescriptors in bulk \[RESERVE\]
+* [`282-remove-named-from-consensus.txt`](/proposals/282-remove-named-from-consensus.txt): Remove "Named" and "Unnamed" handling from consensus voting \[ACCEPTED\]
+* [`283-ipv6-in-micro-consensus.txt`](/proposals/283-ipv6-in-micro-consensus.txt): Move IPv6 ORPorts from microdescriptors to the microdesc consensus \[CLOSED\]
+* [`284-hsv3-control-port.txt`](/proposals/284-hsv3-control-port.txt): Hidden Service v3 Control Port \[CLOSED\]
+* [`285-utf-8.txt`](/proposals/285-utf-8.txt): Directory documents should be standardized as UTF-8 \[ACCEPTED\]
+* [`286-hibernation-api.txt`](/proposals/286-hibernation-api.txt): Controller APIs for hibernation access on mobile \[REJECTED\]
+* [`287-reduce-lifetime.txt`](/proposals/287-reduce-lifetime.txt): Reduce circuit lifetime without overloading the network \[OPEN\]
+* [`288-privcount-with-shamir.txt`](/proposals/288-privcount-with-shamir.txt): Privacy-Preserving Statistics with Privcount in Tor (Shamir version) \[RESERVE\]
+* [`289-authenticated-sendmes.txt`](/proposals/289-authenticated-sendmes.txt): Authenticating sendme cells to mitigate bandwidth attacks \[CLOSED\]
+* [`290-deprecate-consensus-methods.txt`](/proposals/290-deprecate-consensus-methods.txt): Continuously update consensus methods \[META\]
+* [`291-two-guard-nodes.txt`](/proposals/291-two-guard-nodes.txt): The move to two guard nodes \[FINISHED\]
+* [`292-mesh-vanguards.txt`](/proposals/292-mesh-vanguards.txt): Mesh-based vanguards \[CLOSED\]
+* [`293-know-when-to-publish.txt`](/proposals/293-know-when-to-publish.txt): Other ways for relays to know when to publish \[CLOSED\]
+* [`294-tls-1.3.txt`](/proposals/294-tls-1.3.txt): TLS 1.3 Migration \[DRAFT\]
+* [`295-relay-crypto-with-adl.txt`](/proposals/295-relay-crypto-with-adl.txt): Using ADL for relay cryptography (solving the crypto-tagging attack) \[OPEN\]
+* [`296-expose-bandwidth-files.txt`](/proposals/296-expose-bandwidth-files.txt): Have Directory Authorities expose raw bandwidth list files \[CLOSED\]
+* [`297-safer-protover-shutdowns.txt`](/proposals/297-safer-protover-shutdowns.txt): Relaxing the protover-based shutdown rules \[CLOSED\]
+* [`298-canonical-families.txt`](/proposals/298-canonical-families.txt): Putting family lines in canonical form \[CLOSED\]
+* [`299-ip-failure-count.txt`](/proposals/299-ip-failure-count.txt): Preferring IPv4 or IPv6 based on IP Version Failure Count \[SUPERSEDED\]
+* [`300-walking-onions.txt`](/proposals/300-walking-onions.txt): Walking Onions: Scaling and Saving Bandwidth \[INFORMATIONAL\]
+* [`301-dont-vote-on-package-fingerprints.txt`](/proposals/301-dont-vote-on-package-fingerprints.txt): Don't include package fingerprints in consensus documents \[CLOSED\]
+* [`302-padding-machines-for-onion-clients.txt`](/proposals/302-padding-machines-for-onion-clients.txt): Hiding onion service clients using padding \[CLOSED\]
+* [`303-protover-removal-policy.txt`](/proposals/303-protover-removal-policy.txt): When and how to remove support for protocol versions \[OPEN\]
+* [`304-socks5-extending-hs-error-codes.txt`](/proposals/304-socks5-extending-hs-error-codes.txt): Extending SOCKS5 Onion Service Error Codes \[CLOSED\]
+* [`305-establish-intro-dos-defense-extention.txt`](/proposals/305-establish-intro-dos-defense-extention.txt): ESTABLISH_INTRO Cell DoS Defense Extension \[CLOSED\]
+* [`306-ipv6-happy-eyeballs.txt`](/proposals/306-ipv6-happy-eyeballs.txt): A Tor Implementation of IPv6 Happy Eyeballs \[OPEN\]
+* [`307-onionbalance-v3.txt`](/proposals/307-onionbalance-v3.txt): Onion Balance Support for Onion Service v3 \[RESERVE\]
+* [`308-counter-galois-onion.txt`](/proposals/308-counter-galois-onion.txt): Counter Galois Onion: A New Proposal for Forward-Secure Relay Cryptography \[SUPERSEDED\]
+* [`309-optimistic-socks-in-tor.txt`](/proposals/309-optimistic-socks-in-tor.txt): Optimistic SOCKS Data \[OPEN\]
+* [`310-bandaid-on-guard-selection.txt`](/proposals/310-bandaid-on-guard-selection.txt): Towards load-balancing in Prop 271 \[CLOSED\]
+* [`311-relay-ipv6-reachability.txt`](/proposals/311-relay-ipv6-reachability.txt): Tor Relay IPv6 Reachability \[ACCEPTED\]
+* [`312-relay-auto-ipv6-addr.txt`](/proposals/312-relay-auto-ipv6-addr.txt): Tor Relay Automatic IPv6 Address Discovery \[ACCEPTED\]
+* [`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 \[CLOSED\]
+* [`315-update-dir-required-fields.txt`](/proposals/315-update-dir-required-fields.txt): Updating the list of fields required in directory documents \[CLOSED\]
+* [`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 \[CLOSED\]
+* [`319-wide-everything.md`](/proposals/319-wide-everything.md): RELAY_FRAGMENT cells \[OBSOLETE\]
+* [`320-tap-out-again.md`](/proposals/320-tap-out-again.md): Removing TAP usage from v2 onion services \[REJECTED\]
+* [`321-happy-families.md`](/proposals/321-happy-families.md): Better performance and usability for the MyFamily option (v2) \[ACCEPTED\]
+* [`322-dirport-linkspec.md`](/proposals/322-dirport-linkspec.md): Extending link specifiers to include the directory port \[OPEN\]
+* [`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 \[FINISHED\]
+* [`325-packed-relay-cells.md`](/proposals/325-packed-relay-cells.md): Packed relay cells: saving space on small commands \[OBSOLETE\]
+* [`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 \[CLOSED\]
+* [`328-relay-overload-report.md`](/proposals/328-relay-overload-report.md): Make Relays Report When They Are Overloaded \[CLOSED\]
+* [`329-traffic-splitting.txt`](/proposals/329-traffic-splitting.txt): Overcoming Tor's Bottlenecks with Traffic Splitting \[FINISHED\]
+* [`330-authority-contact.md`](/proposals/330-authority-contact.md): Modernizing authority contact entries \[OPEN\]
+* [`331-res-tokens-for-anti-dos.md`](/proposals/331-res-tokens-for-anti-dos.md): Res tokens: Anonymous Credentials for Onion Service DoS Resilience \[DRAFT\]
+* [`332-ntor-v3-with-extra-data.md`](/proposals/332-ntor-v3-with-extra-data.md): Ntor protocol with extra data, version 3 \[CLOSED\]
+* [`333-vanguards-lite.md`](/proposals/333-vanguards-lite.md): Vanguards lite \[CLOSED\]
+* [`334-middle-only-flag.txt`](/proposals/334-middle-only-flag.txt): A Directory Authority Flag To Mark Relays As Middle-only \[SUPERSEDED\]
+* [`335-middle-only-redux.md`](/proposals/335-middle-only-redux.md): An authority-only design for MiddleOnly \[CLOSED\]
+* [`336-randomize-guard-retries.md`](/proposals/336-randomize-guard-retries.md): Randomized schedule for guard retries \[CLOSED\]
+* [`337-simpler-guard-usability.md`](/proposals/337-simpler-guard-usability.md): A simpler way to decide, "Is this guard usable?" \[CLOSED\]
+* [`338-netinfo-y2038.md`](/proposals/338-netinfo-y2038.md): Use an 8-byte timestamp in NETINFO cells \[ACCEPTED\]
+* [`339-udp-over-tor.md`](/proposals/339-udp-over-tor.md): UDP traffic over Tor \[ACCEPTED\]
+* [`340-packed-and-fragmented.md`](/proposals/340-packed-and-fragmented.md): Packed and fragmented relay messages \[OPEN\]
+* [`341-better-oos.md`](/proposals/341-better-oos.md): A better algorithm for out-of-sockets eviction \[OPEN\]
+* [`342-decouple-hs-interval.md`](/proposals/342-decouple-hs-interval.md): Decoupling hs_interval and SRV lifetime \[DRAFT\]
+* [`343-rend-caa.txt`](/proposals/343-rend-caa.txt): CAA Extensions for the Tor Rendezvous Specification \[OPEN\]
+* [`344-protocol-info-leaks.txt`](/proposals/344-protocol-info-leaks.txt): Prioritizing Protocol Information Leaks in Tor \[OPEN\]
+* [`345-specs-in-mdbook.md`](/proposals/345-specs-in-mdbook.md): Migrating the tor specifications to mdbook \[CLOSED\]
+* [`346-protovers-again.md`](/proposals/346-protovers-again.md): Clarifying and extending the use of protocol versioning \[OPEN\]
+* [`347-domain-separation.md`](/proposals/347-domain-separation.md): Domain separation for certificate signing keys \[OPEN\]
diff --git a/proposals/BY_STATUS.md b/proposals/BY_STATUS.md
index 865fac0..5a103ac 100644
--- a/proposals/BY_STATUS.md
+++ b/proposals/BY_STATUS.md
@@ -66,7 +66,6 @@ themselves still need to be merged into the specifications proper.
* [`260-rend-single-onion.txt`](/proposals/260-rend-single-onion.txt): Rendezvous Single Onion Services
* [`291-two-guard-nodes.txt`](/proposals/291-two-guard-nodes.txt): The move to two guard nodes
* [`324-rtt-congestion-control.txt`](/proposals/324-rtt-congestion-control.txt): RTT-based Congestion Control for Tor
-* [`327-pow-over-intro.txt`](/proposals/327-pow-over-intro.txt): A First Take at PoW Over Introduction Circuits
* [`329-traffic-splitting.txt`](/proposals/329-traffic-splitting.txt): Overcoming Tor's Bottlenecks with Traffic Splitting
@@ -238,6 +237,7 @@ necessary.
* [`314-allow-markdown-proposals.md`](/proposals/314-allow-markdown-proposals.md): Allow Markdown for proposal format
* [`315-update-dir-required-fields.txt`](/proposals/315-update-dir-required-fields.txt): Updating the list of fields required in directory documents
* [`318-limit-protovers.md`](/proposals/318-limit-protovers.md): Limit protover values to 0-63
+* [`327-pow-over-intro.txt`](/proposals/327-pow-over-intro.txt): A First Take at PoW Over Introduction Circuits
* [`328-relay-overload-report.md`](/proposals/328-relay-overload-report.md): Make Relays Report When They Are Overloaded
* [`332-ntor-v3-with-extra-data.md`](/proposals/332-ntor-v3-with-extra-data.md): Ntor protocol with extra data, version 3
* [`333-vanguards-lite.md`](/proposals/333-vanguards-lite.md): Vanguards lite
@@ -313,56 +313,56 @@ DEAD), the proposal has been considered and not adopted (the proposal is
REJECTED), or the proposal addresses an issue or a solution that is no
longer relevant (the proposal is OBSOLETE).
-* [`098-todo.txt`](/proposals/098-todo.txt): Proposals that should be written [OBSOLETE]
-* [`099-misc.txt`](/proposals/099-misc.txt): Miscellaneous proposals [OBSOLETE]
-* [`100-tor-spec-udp.txt`](/proposals/100-tor-spec-udp.txt): Tor Unreliable Datagram Extension Proposal [DEAD]
-* [`115-two-hop-paths.txt`](/proposals/115-two-hop-paths.txt): Two Hop Paths [DEAD]
-* [`116-two-hop-paths-from-guard.txt`](/proposals/116-two-hop-paths-from-guard.txt): Two hop paths from entry guards [DEAD]
-* [`120-shutdown-descriptors.txt`](/proposals/120-shutdown-descriptors.txt): Shutdown descriptors when Tor servers stop [DEAD]
-* [`127-dirport-mirrors-downloads.txt`](/proposals/127-dirport-mirrors-downloads.txt): Relaying dirport requests to Tor download site / website [OBSOLETE]
-* [`128-bridge-families.txt`](/proposals/128-bridge-families.txt): Families of private bridges [DEAD]
-* [`131-verify-tor-usage.txt`](/proposals/131-verify-tor-usage.txt): Help users to verify they are using Tor [OBSOLETE]
-* [`132-browser-check-tor-service.txt`](/proposals/132-browser-check-tor-service.txt): A Tor Web Service For Verifying Correct Browser Configuration [OBSOLETE]
-* [`134-robust-voting.txt`](/proposals/134-robust-voting.txt): More robust consensus voting with diverse authority sets [REJECTED]
-* [`141-jit-sd-downloads.txt`](/proposals/141-jit-sd-downloads.txt): Download server descriptors on demand [OBSOLETE]
-* [`142-combine-intro-and-rend-points.txt`](/proposals/142-combine-intro-and-rend-points.txt): Combine Introduction and Rendezvous Points [DEAD]
-* [`144-enforce-distinct-providers.txt`](/proposals/144-enforce-distinct-providers.txt): Increase the diversity of circuits by detecting nodes belonging the same provider [OBSOLETE]
-* [`147-prevoting-opinions.txt`](/proposals/147-prevoting-opinions.txt): Eliminate the need for v2 directories in generating v3 directories [REJECTED]
-* [`164-reporting-server-status.txt`](/proposals/164-reporting-server-status.txt): Reporting the status of server votes [OBSOLETE]
-* [`165-simple-robust-voting.txt`](/proposals/165-simple-robust-voting.txt): Easy migration for voting authority sets [REJECTED]
-* [`168-reduce-circwindow.txt`](/proposals/168-reduce-circwindow.txt): Reduce default circuit window [REJECTED]
-* [`173-getinfo-option-expansion.txt`](/proposals/173-getinfo-option-expansion.txt): GETINFO Option Expansion [OBSOLETE]
-* [`175-automatic-node-promotion.txt`](/proposals/175-automatic-node-promotion.txt): Automatically promoting Tor clients to nodes [REJECTED]
-* [`182-creditbucket.txt`](/proposals/182-creditbucket.txt): Credit Bucket [OBSOLETE]
-* [`189-authorize-cell.txt`](/proposals/189-authorize-cell.txt): AUTHORIZE and AUTHORIZED cells [OBSOLETE]
-* [`190-shared-secret-bridge-authorization.txt`](/proposals/190-shared-secret-bridge-authorization.txt): Bridge Client Authorization Based on a Shared Secret [OBSOLETE]
-* [`191-mitm-bridge-detection-resistance.txt`](/proposals/191-mitm-bridge-detection-resistance.txt): Bridge Detection Resistance against MITM-capable Adversaries [OBSOLETE]
-* [`192-store-bridge-information.txt`](/proposals/192-store-bridge-information.txt): Automatically retrieve and store information about bridges [OBSOLETE]
-* [`195-TLS-normalization-for-024.txt`](/proposals/195-TLS-normalization-for-024.txt): TLS certificate normalization for Tor 0.2.4.x [DEAD]
-* [`197-postmessage-ipc.txt`](/proposals/197-postmessage-ipc.txt): Message-based Inter-Controller IPC Channel [REJECTED]
-* [`199-bridgefinder-integration.txt`](/proposals/199-bridgefinder-integration.txt): Integration of BridgeFinder and BridgeFinderHelper [OBSOLETE]
-* [`203-https-frontend.txt`](/proposals/203-https-frontend.txt): Avoiding censorship by impersonating an HTTPS server [OBSOLETE]
-* [`209-path-bias-tuning.txt`](/proposals/209-path-bias-tuning.txt): Tuning the Parameters for the Path Bias Defense [OBSOLETE]
-* [`213-remove-stream-sendmes.txt`](/proposals/213-remove-stream-sendmes.txt): Remove stream-level sendmes from the design [DEAD]
-* [`229-further-socks5-extensions.txt`](/proposals/229-further-socks5-extensions.txt): Further SOCKS5 extensions [REJECTED]
-* [`230-rsa1024-relay-id-migration.txt`](/proposals/230-rsa1024-relay-id-migration.txt): How to change RSA1024 relay identity keys [OBSOLETE]
-* [`231-migrate-authority-rsa1024-ids.txt`](/proposals/231-migrate-authority-rsa1024-ids.txt): Migrating authority RSA1024 identity keys [OBSOLETE]
-* [`233-quicken-tor2web-mode.txt`](/proposals/233-quicken-tor2web-mode.txt): Making Tor2Web mode faster [REJECTED]
-* [`234-remittance-addresses.txt`](/proposals/234-remittance-addresses.txt): Adding remittance field to directory specification [REJECTED]
-* [`241-suspicious-guard-turnover.txt`](/proposals/241-suspicious-guard-turnover.txt): Resisting guard-turnover attacks [REJECTED]
-* [`246-merge-hsdir-and-intro.txt`](/proposals/246-merge-hsdir-and-intro.txt): Merging Hidden Service Directories and Introduction Points [REJECTED]
-* [`253-oob-hmac.txt`](/proposals/253-oob-hmac.txt): Out of Band Circuit HMACs [DEAD]
-* [`258-dirauth-dos.txt`](/proposals/258-dirauth-dos.txt): Denial-of-service resistance for directory authorities [DEAD]
-* [`259-guard-selection.txt`](/proposals/259-guard-selection.txt): New Guard Selection Behaviour [OBSOLETE]
-* [`261-aez-crypto.txt`](/proposals/261-aez-crypto.txt): AEZ for relay cryptography [OBSOLETE]
-* [`263-ntru-for-pq-handshake.txt`](/proposals/263-ntru-for-pq-handshake.txt): Request to change key exchange protocol for handshake v1.2 [OBSOLETE]
-* [`268-guard-selection.txt`](/proposals/268-guard-selection.txt): New Guard Selection Behaviour [OBSOLETE]
-* [`270-newhope-hybrid-handshake.txt`](/proposals/270-newhope-hybrid-handshake.txt): RebelAlliance: A Post-Quantum Secure Hybrid Handshake Based on NewHope [OBSOLETE]
-* [`276-lower-bw-granularity.txt`](/proposals/276-lower-bw-granularity.txt): Report bandwidth with lower granularity in consensus documents [DEAD]
-* [`286-hibernation-api.txt`](/proposals/286-hibernation-api.txt): Controller APIs for hibernation access on mobile [REJECTED]
-* [`319-wide-everything.md`](/proposals/319-wide-everything.md): RELAY_FRAGMENT cells [OBSOLETE]
-* [`320-tap-out-again.md`](/proposals/320-tap-out-again.md): Removing TAP usage from v2 onion services [REJECTED]
-* [`325-packed-relay-cells.md`](/proposals/325-packed-relay-cells.md): Packed relay cells: saving space on small commands [OBSOLETE]
+* [`098-todo.txt`](/proposals/098-todo.txt): Proposals that should be written \[OBSOLETE\]
+* [`099-misc.txt`](/proposals/099-misc.txt): Miscellaneous proposals \[OBSOLETE\]
+* [`100-tor-spec-udp.txt`](/proposals/100-tor-spec-udp.txt): Tor Unreliable Datagram Extension Proposal \[DEAD\]
+* [`115-two-hop-paths.txt`](/proposals/115-two-hop-paths.txt): Two Hop Paths \[DEAD\]
+* [`116-two-hop-paths-from-guard.txt`](/proposals/116-two-hop-paths-from-guard.txt): Two hop paths from entry guards \[DEAD\]
+* [`120-shutdown-descriptors.txt`](/proposals/120-shutdown-descriptors.txt): Shutdown descriptors when Tor servers stop \[DEAD\]
+* [`127-dirport-mirrors-downloads.txt`](/proposals/127-dirport-mirrors-downloads.txt): Relaying dirport requests to Tor download site / website \[OBSOLETE\]
+* [`128-bridge-families.txt`](/proposals/128-bridge-families.txt): Families of private bridges \[DEAD\]
+* [`131-verify-tor-usage.txt`](/proposals/131-verify-tor-usage.txt): Help users to verify they are using Tor \[OBSOLETE\]
+* [`132-browser-check-tor-service.txt`](/proposals/132-browser-check-tor-service.txt): A Tor Web Service For Verifying Correct Browser Configuration \[OBSOLETE\]
+* [`134-robust-voting.txt`](/proposals/134-robust-voting.txt): More robust consensus voting with diverse authority sets \[REJECTED\]
+* [`141-jit-sd-downloads.txt`](/proposals/141-jit-sd-downloads.txt): Download server descriptors on demand \[OBSOLETE\]
+* [`142-combine-intro-and-rend-points.txt`](/proposals/142-combine-intro-and-rend-points.txt): Combine Introduction and Rendezvous Points \[DEAD\]
+* [`144-enforce-distinct-providers.txt`](/proposals/144-enforce-distinct-providers.txt): Increase the diversity of circuits by detecting nodes belonging the same provider \[OBSOLETE\]
+* [`147-prevoting-opinions.txt`](/proposals/147-prevoting-opinions.txt): Eliminate the need for v2 directories in generating v3 directories \[REJECTED\]
+* [`164-reporting-server-status.txt`](/proposals/164-reporting-server-status.txt): Reporting the status of server votes \[OBSOLETE\]
+* [`165-simple-robust-voting.txt`](/proposals/165-simple-robust-voting.txt): Easy migration for voting authority sets \[REJECTED\]
+* [`168-reduce-circwindow.txt`](/proposals/168-reduce-circwindow.txt): Reduce default circuit window \[REJECTED\]
+* [`173-getinfo-option-expansion.txt`](/proposals/173-getinfo-option-expansion.txt): GETINFO Option Expansion \[OBSOLETE\]
+* [`175-automatic-node-promotion.txt`](/proposals/175-automatic-node-promotion.txt): Automatically promoting Tor clients to nodes \[REJECTED\]
+* [`182-creditbucket.txt`](/proposals/182-creditbucket.txt): Credit Bucket \[OBSOLETE\]
+* [`189-authorize-cell.txt`](/proposals/189-authorize-cell.txt): AUTHORIZE and AUTHORIZED cells \[OBSOLETE\]
+* [`190-shared-secret-bridge-authorization.txt`](/proposals/190-shared-secret-bridge-authorization.txt): Bridge Client Authorization Based on a Shared Secret \[OBSOLETE\]
+* [`191-mitm-bridge-detection-resistance.txt`](/proposals/191-mitm-bridge-detection-resistance.txt): Bridge Detection Resistance against MITM-capable Adversaries \[OBSOLETE\]
+* [`192-store-bridge-information.txt`](/proposals/192-store-bridge-information.txt): Automatically retrieve and store information about bridges \[OBSOLETE\]
+* [`195-TLS-normalization-for-024.txt`](/proposals/195-TLS-normalization-for-024.txt): TLS certificate normalization for Tor 0.2.4.x \[DEAD\]
+* [`197-postmessage-ipc.txt`](/proposals/197-postmessage-ipc.txt): Message-based Inter-Controller IPC Channel \[REJECTED\]
+* [`199-bridgefinder-integration.txt`](/proposals/199-bridgefinder-integration.txt): Integration of BridgeFinder and BridgeFinderHelper \[OBSOLETE\]
+* [`203-https-frontend.txt`](/proposals/203-https-frontend.txt): Avoiding censorship by impersonating an HTTPS server \[OBSOLETE\]
+* [`209-path-bias-tuning.txt`](/proposals/209-path-bias-tuning.txt): Tuning the Parameters for the Path Bias Defense \[OBSOLETE\]
+* [`213-remove-stream-sendmes.txt`](/proposals/213-remove-stream-sendmes.txt): Remove stream-level sendmes from the design \[DEAD\]
+* [`229-further-socks5-extensions.txt`](/proposals/229-further-socks5-extensions.txt): Further SOCKS5 extensions \[REJECTED\]
+* [`230-rsa1024-relay-id-migration.txt`](/proposals/230-rsa1024-relay-id-migration.txt): How to change RSA1024 relay identity keys \[OBSOLETE\]
+* [`231-migrate-authority-rsa1024-ids.txt`](/proposals/231-migrate-authority-rsa1024-ids.txt): Migrating authority RSA1024 identity keys \[OBSOLETE\]
+* [`233-quicken-tor2web-mode.txt`](/proposals/233-quicken-tor2web-mode.txt): Making Tor2Web mode faster \[REJECTED\]
+* [`234-remittance-addresses.txt`](/proposals/234-remittance-addresses.txt): Adding remittance field to directory specification \[REJECTED\]
+* [`241-suspicious-guard-turnover.txt`](/proposals/241-suspicious-guard-turnover.txt): Resisting guard-turnover attacks \[REJECTED\]
+* [`246-merge-hsdir-and-intro.txt`](/proposals/246-merge-hsdir-and-intro.txt): Merging Hidden Service Directories and Introduction Points \[REJECTED\]
+* [`253-oob-hmac.txt`](/proposals/253-oob-hmac.txt): Out of Band Circuit HMACs \[DEAD\]
+* [`258-dirauth-dos.txt`](/proposals/258-dirauth-dos.txt): Denial-of-service resistance for directory authorities \[DEAD\]
+* [`259-guard-selection.txt`](/proposals/259-guard-selection.txt): New Guard Selection Behaviour \[OBSOLETE\]
+* [`261-aez-crypto.txt`](/proposals/261-aez-crypto.txt): AEZ for relay cryptography \[OBSOLETE\]
+* [`263-ntru-for-pq-handshake.txt`](/proposals/263-ntru-for-pq-handshake.txt): Request to change key exchange protocol for handshake v1.2 \[OBSOLETE\]
+* [`268-guard-selection.txt`](/proposals/268-guard-selection.txt): New Guard Selection Behaviour \[OBSOLETE\]
+* [`270-newhope-hybrid-handshake.txt`](/proposals/270-newhope-hybrid-handshake.txt): RebelAlliance: A Post-Quantum Secure Hybrid Handshake Based on NewHope \[OBSOLETE\]
+* [`276-lower-bw-granularity.txt`](/proposals/276-lower-bw-granularity.txt): Report bandwidth with lower granularity in consensus documents \[DEAD\]
+* [`286-hibernation-api.txt`](/proposals/286-hibernation-api.txt): Controller APIs for hibernation access on mobile \[REJECTED\]
+* [`319-wide-everything.md`](/proposals/319-wide-everything.md): RELAY_FRAGMENT cells \[OBSOLETE\]
+* [`320-tap-out-again.md`](/proposals/320-tap-out-again.md): Removing TAP usage from v2 onion services \[REJECTED\]
+* [`325-packed-relay-cells.md`](/proposals/325-packed-relay-cells.md): Packed relay cells: saving space on small commands \[OBSOLETE\]
diff --git a/proposals/README.md b/proposals/README.md
index d7b662e..abaeebf 100644
--- a/proposals/README.md
+++ b/proposals/README.md
@@ -8,10 +8,10 @@ others are under active discussion.
If you're looking for a specific proposal, you can find it,
by filename, in the summary bar on the left, or at
[this index](./BY_INDEX.md). You can also see a list of Tor protocols
-by their status at [`README.md`].
+by their status at [`BY_STATUS.md`](./BY_STATUS.md).
For information on creating a new proposal, you would ideally look at
-[`001-process.txt`]. That file is a bit out-of-date, though, and you
+[`001-process.txt`](./001-process.txt). That file is a bit out-of-date, though, and you
should probably just contact the developers.
* <a href="..">Back to the Tor specifications</a>
diff --git a/proposals/SUMMARY.md b/proposals/SUMMARY.md
index 15b787b..f66d166 100644
--- a/proposals/SUMMARY.md
+++ b/proposals/SUMMARY.md
@@ -237,7 +237,7 @@
- [`324-rtt-congestion-control`](./324-rtt-congestion-control.txt): RTT-based Congestion Control for Tor (FINISHED)
- [`325-packed-relay-cells`](./325-packed-relay-cells.md): Packed relay cells: saving space on small commands (OBSOLETE)
- [`326-tor-relay-well-known-uri-rfc8615`](./326-tor-relay-well-known-uri-rfc8615.md): The "tor-relay" Well-Known Resource Identifier (OPEN)
- - [`327-pow-over-intro`](./327-pow-over-intro.txt): A First Take at PoW Over Introduction Circuits (FINISHED)
+ - [`327-pow-over-intro`](./327-pow-over-intro.txt): A First Take at PoW Over Introduction Circuits (CLOSED)
- [`328-relay-overload-report`](./328-relay-overload-report.md): Make Relays Report When They Are Overloaded (CLOSED)
- [`329-traffic-splitting`](./329-traffic-splitting.txt): Overcoming Tor's Bottlenecks with Traffic Splitting (FINISHED)
- [`330-authority-contact`](./330-authority-contact.md): Modernizing authority contact entries (OPEN)
diff --git a/spec/STYLE.md b/spec/STYLE.md
index 102b786..74388c3 100644
--- a/spec/STYLE.md
+++ b/spec/STYLE.md
@@ -133,7 +133,7 @@ for more information about how.)
If you want to link to a specific section within a file,
make sure that the section has a defined anchor that makes sense.
-The syntax to define [heading ids] in mdbook looks like this:
+The syntax to define heading ids in mdbook looks like this:
`## Heading with a long title that you want shorter name for { #shortname }`
diff --git a/spec/SUMMARY.md b/spec/SUMMARY.md
index c425ee6..e08c8f7 100644
--- a/spec/SUMMARY.md
+++ b/spec/SUMMARY.md
@@ -29,7 +29,6 @@
- [Closing streams](./tor-spec/closing-streams.md)
- [Remote hostname lookup](./tor-spec/remote-hostname-lookup.md)
- [Flow control](./tor-spec/flow-control.md)
- - [Handling resource exhaustion](./tor-spec/resource-exhaustion.md)
- [Subprotocol versioning](./tor-spec/subprotocol-versioning.md)
- [`Ed25519 certificates in Tor`](./cert-spec.md)
- [`Tor directory protocol, version 3`](./dir-spec/index.md)
@@ -95,7 +94,9 @@
- [Connection-level padding](./padding-spec/connection-level-padding.md)
- [Circuit-level padding](./padding-spec/circuit-level-padding.md)
- [Acknowledgments](./padding-spec/acknowledgments.md)
-- [Preventing Denial-Of-Service](./dos-spec.md)
+- [`Preventing Denial-Of-Service`](./dos-spec/index.md)
+ - [Overview](./dos-spec/overview.md)
+ - [Memory exhaustion](./dos-spec/memory-exhaustion.md)
# Additional behaviors for clients
@@ -127,6 +128,11 @@
- [Appendix G: Managing authorized client data \[CLIENT-AUTH-MGMT\]](./rend-spec/client-authorization.md)
- [Appendix F: Two methods for managing revision counters.](./rend-spec/revision-counter-mgt.md)
- [Appendix G: Text vectors](./rend-spec/text-vectors.md)
+- [`Proof of Work for onion service introduction`](./hspow-spec/index.md)
+ - [Motivation](./hspow-spec/motivation.md)
+ - [Common protocol](./hspow-spec/common-protocol.md)
+ - [Version 1, Equi-X and Blake2b](./hspow-spec/v1-equix.md)
+ - [Analysis and discussion](./hspow-spec/analysis-discussion.md)
# Anticensorship tools and protocols
diff --git a/spec/back-matter.md b/spec/back-matter.md
index 6a50633..90ddea2 100644
--- a/spec/back-matter.md
+++ b/spec/back-matter.md
@@ -55,12 +55,14 @@ see the
## Editing advice
-To edit these specs, clone the [git repository] and edit the
-appropriate file in the [`spec` directory]. These files will match
+To edit these specs, clone the
+[git repository](https://gitlab.torproject.org/tpo/core/torspec/)
+and edit the
+appropriate file in the `spec` directory. These files will match
the URLs of their corresponding pages, so if you want to edit
-[`tor-spec/flow-control.html`],
+`tor-spec/flow-control.html`,
you'll be looking for a file
-called [`spec/tor-spec/flow-control.md`].
+called `spec/tor-spec/flow-control.md`.
We have started a [style guide](./STYLE.md) for writing new parts of
this spec; as of 2023 it is quite preliminary. You should feel free to
diff --git a/spec/dos-spec/index.md b/spec/dos-spec/index.md
new file mode 100644
index 0000000..3645935
--- /dev/null
+++ b/spec/dos-spec/index.md
@@ -0,0 +1,7 @@
+# Denial-of-service prevention mechanisms in Tor
+
+This document covers the strategy, motivation, and implementation for denial-of-service mitigation systems designed into Tor.
+
+The older `dos-spec` document is now the [Memory exhaustion](./memory-exhaustion.md) section here.
+
+An in-depth description of the proof of work mechanism for onion services, originally [proposal 327](../../proposals/327-pow-over-intro.txt), is now in the [Proof of Work for onion service introduction](../hspow-spec/index.md) spec. \ No newline at end of file
diff --git a/spec/dos-spec.md b/spec/dos-spec/memory-exhaustion.md
index d37649f..2cc55eb 100644
--- a/spec/dos-spec.md
+++ b/spec/dos-spec/memory-exhaustion.md
@@ -1,28 +1,10 @@
-# Denial-of-service prevention mechanisms in Tor
+# Memory exhaustion { #oom }
-This document is incomplete; it describes some mechanisms that Tor
-uses to avoid different kinds of denial-of-service attacks.
+Memory exhaustion is a broad issue with many underlying causes. The Tor protocol requires clients, onion services, relays, and authorities to store various kind of information in buffers and caches. But an attacker can use these buffers and queues to exhaust the memory of the a targeted Tor process, and force the operating system to kill that process.
-## Handling low-memory conditions { #oom }
+With this in mind, any Tor implementation (especially one that runs as a relay or onion service) must take steps to prevent memory-based denial-of-service attacks.
-(See also `tor-spec.txt`, section 8.1.)
-
-The Tor protocol requires clients, onion services, relays, and
-authorities to store various kind of information in buffers and
-caches. But an attacker can use these buffers and queues to queues
-to exhaust the memory of the a targeted Tor process, and force the
-operating system to kill that process.
-
-Worse still, the ability to kill targeted Tor instances can be used
-to facilitate traffic analysis. (For example, see
-[the "Sniper Attack" paper](https://www.freehaven.net/anonbib/#sniper14)
-by Jansen, Tschorsch, Johnson, and Scheuermann.
-
-With this in mind, any Tor implementation—especially one that
-runs as a relay or onion service—must take steps to prevent
-memory-based denial-of-service attacks.
-
-### Detecting low memory { #oom-detection }
+## Detecting low memory { #oom-detection }
The easiest way to notice you're out of memory would, in theory, be
getting an error when you try to allocate more. Unfortunately, some
diff --git a/spec/dos-spec/overview.md b/spec/dos-spec/overview.md
new file mode 100644
index 0000000..0ea0994
--- /dev/null
+++ b/spec/dos-spec/overview.md
@@ -0,0 +1,78 @@
+# Overview
+
+As a public and anonymous network, Tor is open to many types of denial-of-service attempts. It's necessary to constantly develop a variety of defenses that mitigate specific types of attacks.
+
+These mitigations are expected to improve network availability, but DoS mitigation is also important for limiting the avenues an attacker could use to perform active attacks on anonymity. For example, the ability to kill targeted Tor instances can be used to facilitate traffic analysis. See the ["Sniper Attack" paper](https://www.freehaven.net/anonbib/#sniper14) by Jansen, Tschorsch, Johnson, and Scheuermann.
+
+The attack and defense environment changes over time.
+Expect that this document is an attempt to describe the current state of things, but that it may not be complete.
+
+The defenses here are organized by the type of resource under contention. These can be physical resources ([Memory](#memory), [CPU](#cpu), [Bandwidth](#bandwidth)) or protocol resources ([Channels](#channels), [Circuits](#circuits), [Introductions](#hs-intro)).
+
+In practice there are always overlaps between these resource types.
+Connecting to an onion service, for example, puts some strain on every resource type here.
+
+## Physical resources
+
+### Memory {#memory}
+
+[Memory exhaustion](./memory-exhaustion.md) is both one of the most serious denial-of-service avenues and the subject of the most fully developed defense mechanisms so far. We track overall memory use and free the most disposable objects first when usage is over threshold.
+
+### CPU {#cpu}
+
+The available CPU time on a router can be exhausted, assuming the implementation is not capable of processing network input at line rate in all circumstances.
+This is especially problematic in the single-threaded C implementation.
+Certain expensive operations like circuit extension handshakes are deferred to a thread pool, but time on the main thread is still a precious resource.
+
+We currently don't directly monitor and respond to CPU usage.
+Instead C Tor relies on limits for protocol resources, like circuits extensions and onion service introductions, that are associated with this CPU load.
+
+### Bandwidth {#bandwidth}
+
+Relay operators can place hard limits on total bandwidth using the `Bandwidth` or `RelayBandwidth` options. These options can help relay operators avoid bandwidth peaks on their network, however they aren't designed as denial of service prevention mechanisms.
+
+Beyond just shaving off harmful bandwidth peaks it's important that normal service is not disrupted too much, and especially not disrupted in a targetable way.
+To approximate this goal we rely on [flow control](../tor-spec/flow-control.md) and fair dequeueing of relayed cells.
+
+## Protocol resources
+
+### Channels {#channels}
+
+All channels to some extent are a limited resource, but we focus specifically on preventing floods of incoming TLS connections.
+
+Excessive incoming TLS connections consume memory as well as limited network and operating system resources.
+Excessive incoming connections typically signal a low-effort denial of service attack.
+
+The C Tor implementation establishes limits on both the number of concurrent connections per IP address and the rate of new connections, using the `DoSConnection` family of configuration options and their corresponding consensus parameters.
+
+### Circuits {#circuits}
+
+Excessive circuit creation can impact the entire path of that circuit, so it's important to reject these attacks any time they can be identified. Ideally we reject them as early as possible, before they have fully built the circuit.
+
+Because of Tor's anonymity, most affected nodes experience the circuit flood as coming from every direction. The guard position, however, has a chance to notice specific peers that are creating too many circuits.
+
+The C Tor implementation limits the acceptable rate of circuit creation per client IP address using the `DoSCircuit` configuration options and their corresponding consensus parameters.
+
+### Onion service introductions {#hs-intro}
+
+Flooding an onion service with introduction attempts causes significant network load. In addition to the CPU, memory, and bandwidth load experienced by the introduction point and the service, all involved relays experience a circuit creation flood.
+
+We have two types of onion service DoS mitigations currently. Both are optional, enabled as needed by individual onion servce operators.
+
+#### Mitigation by rate limiting {#hs-intro-rate}
+
+Introduction attempts can be rate-limited by each introduction point, at the request of the service.
+
+This defense is configured by an operator using the `HiddenServiceEnableIntroDos` configuration options. Services use the [introduction DoS extension](../rend-spec/introduction-protocol.html#EST_INTRO_DOS_EXT) to communicate these settings to each introduction point.
+
+#### Mitigation using proof of work {#hs-intro-pow}
+
+A short non-interactive computational puzzle can be solved with each connection attempt. Requests provided by the client will be entered into a queue prioritized by their puzzle solution's effort score. Requests are processed by the service at a limited rate, which can be adjusted to a value within the server's capabilities.
+
+Based on the queue behavior, servers will continuously provide an updated effort suggestion.
+Queue backlogs cause the effort to rise, and an idle server will cause the effort to decay.
+If the queue is never overfull the effort decays to zero, asking clients not to include a proof-of-work solution at all.
+
+We may support multiple cryptographic algorithms for this puzzle in the future, but currently we support one type. It's called `v1` in our protocol, and it's based on the Equi-X algorithm developed for this purpose. See the document on [Proof of Work for onion service introduction](../hspow-spec/index.md).
+
+This defense is configured by an operator using the `HiddenServicePoW` configuration options. Additionally, it requires both the client and the onion service to be compiled with the `pow` module (and `--enable-gpl` mode) available. Despite this non-default build setting, proof of work *is* available through common packagers like the Tor Browser and Debian.
diff --git a/spec/guard-spec/algorithm.md b/spec/guard-spec/algorithm.md
index 0eaeb0e..ba1c725 100644
--- a/spec/guard-spec/algorithm.md
+++ b/spec/guard-spec/algorithm.md
@@ -350,24 +350,21 @@ The per-circuit state machine is:
closed.
```mermaid
----
-title: Circuit state transitions
----
-
-[*] -> usable_on_completion
-[*] -> usable_if_no_better_guard
-usable_on_completion -> complete
-usable_on_completion -> failed
-usable_if_no_better_guard -> usable_on_completion
-usable_if_no_better_guard -> waiting_for_better_guard
-usable_if_no_better_guard -> failed
-waiting_for_better_guard -> complete
-waiting_for_better_guard -> failed
-waiting_for_better_guard -> closed
-complete -> failed
-complete -> closed
-failed -> [*]
-closed -> [*]
+stateDiagram-v2
+ [*] --> usable_on_completion
+ [*] --> usable_if_no_better_guard
+ usable_on_completion --> complete
+ usable_on_completion --> failed
+ usable_if_no_better_guard --> usable_on_completion
+ usable_if_no_better_guard --> waiting_for_better_guard
+ usable_if_no_better_guard --> failed
+ waiting_for_better_guard --> complete
+ waiting_for_better_guard --> failed
+ waiting_for_better_guard --> closed
+ complete --> failed
+ complete --> closed
+ failed --> [*]
+ closed --> [*]
```
<!-- TODO: The above diagram does not yet render. Fix that. -->
@@ -410,11 +407,11 @@ When we want to build a circuit, and we need to pick a guard:
When selecting a guard according to this approach, its circuit
is `<usable_on_completion>`.
- [Note: We do not use {is_pending} on primary guards, since we
+ \[Note: We do not use {is_pending} on primary guards, since we
are willing to try to build multiple circuits through them
before we know for sure whether they work, and since we will
not use any non-primary guards until we are sure that the
- primary guards are all down. (XX is this good?)]
+ primary guards are all down. (XX is this good?)\]
* Otherwise, if the ordered intersection of {CONFIRMED_GUARDS}
and {USABLE_FILTERED_GUARDS} is nonempty, return the first
diff --git a/spec/hspow-spec/analysis-discussion.md b/spec/hspow-spec/analysis-discussion.md
new file mode 100644
index 0000000..e021b85
--- /dev/null
+++ b/spec/hspow-spec/analysis-discussion.md
@@ -0,0 +1,416 @@
+# Analysis and discussion
+
+*Warning*: Take all the PoW performance numbers on this page with a large grain of salt. Most of this is based on very early analysis that has not been updated for the current state of implementation.
+
+For current performance numbers on a specific piece of hardware, please run `cargo bench` from the [`equix/bench`](https://gitlab.torproject.org/tpo/core/arti/-/tree/main/crates/equix/bench) crate within [Arti](https://gitlab.torproject.org/tpo/core/arti/). This framework tests both the C and Rust implementations side-by-side.
+
+## Attacker strategies {#attacker-strategies}
+
+To design a protocol and choose its parameters, we first need to understand a few high-level attacker strategies to see what we are fighting against.
+
+### Overwhelm PoW verification ("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 [`v1` verification algorithm](./v1-equix.md#service-verify) section.
+
+That's why we need the PoW algorithm to have a cheap verification time so that this attack is not possible: we explore this PoW parameter below in the section on [PoW verification](#pow-tuning-verification).
+
+### Overwhelm rendezvous capacity ("bottom half") {#attack-bottom-half}
+
+Given the way [the introduction queue](./common-protocol.md#intro-queue) works, 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 process of [handling queued introductions](./common-protocol.md#handling-queue).
+
+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"](./motivation.md#user-profiles).
+
+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"](./motivation.md#user-profiles).
+This would block out all standard users and only allow motivated users to pass.
+
+### 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:
+
+```text
+ 0.31*(1520+91) ~ 0.5 sec.
+ 5.5*91 ~ 0.5 sec.
+```
+
+This attack only has half the bandwidth requirement of a [top-half attack](#attack-top-half) and half the compute requirement of a [bottom-half attack](#attack-bottom-half)..
+
+Alternatively, the attacker can adjust the ratio between invalid and high-effort requests depending on their bandwidth and compute capabilities.
+
+### Gaming the effort control logic {#attack-effort}
+
+Another way to beat this system is for the attacker to game the [effort control logic](./common-protocol.md#effort-control). Essentially, 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 [bottom-half attack](#attack-bottom-half) using medium effort PoW (see [this post by tevador on tor-dev from May 2020](https://lists.torproject.org/pipermail/tor-dev/2020-May/014268.html)).
+
+### Precomputed PoW attack {#attack-precomputed}
+
+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 [effort control attack](#attack-effort).
+
+## Parameter tuning {#parameter-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 previously considered the concept of a nonzero starting difficulty setting. This analysis still references such a concept, even though the currently recommended implementation uses a starting effort of zero. (We now expect early increases in effort during an attack to be driven primarily by client retry behavior.)
+
+At the end of this section we will estimate 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.
+
+### PoW verification {#pow-tuning-verification}
+
+Verifying a PoW token is the first thing that a service does when it receives an INTRODUCE2 cell. Our current implementation is described by the [`v1` verification algorithm](./v1-equix.md#service-verify) specification.
+
+Verification time is a critical performance parameter. Actual times can be measured by `cargo bench` now, and the verification speeds we achieve are more like 50-120 microseconds. The specific numbers below are dated, but the analysys below is preserved as an illustration of the design space we are optimizing within.
+
+To defend against a [top-half attack](#attack-top-half) it's important that we can quickly perform all the steps in-between receiving an introduction request over the network and adding it to our effort-prioritized queue.
+
+All time 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.
+
+During our [performance measurements on tor](#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 [top-half attack](#attack-top-half).
+- For a PoW function with a 2ms verification time, an attacker needs to send 442 dummy introduction cells per second to succeed in a [top-half attack](#attack-top-half).
+- For a PoW function with a 10ms verification time, an attacker needs to send 97 dummy introduction cells per second to succeed in a [top-half attack](#attack-top-half).
+
+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.
+
+### 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 successful [bottom-half attack](#attack-bottom-half) 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.
+
+The original analysis here concluded that we still need a starting difficulty setting that will be used for bootstrapping the system.
+The client and attacker can still aim higher or lower but for UX purposes and for analysis purposes it was useful to define a starting difficulty, to minimize retries by clients.
+
+In current use it was found that an effort of 1 makes a fine minimum, so we don't normally have a concept of minimum effort. Consider the actual "minimum effort" in `v1` now to simply be the expected runtime of one single Equi-X solve.
+
+#### Analysis based on adversary power {#pow-difficulty-adversary}
+
+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.
+
+```text
+ ===============================================================
+ | 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 starting values of our PoW difficulty.
+
+#### Analysis based on Tor's performance {#pow-difficulty-tor}
+
+To go deeper here, we can use the [performance measurements on tor](#tor-measurements) to get a more specific intuition on the starting 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 introduction cell | Cells handled 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 [bottom-half attack](#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 [bottom-half attack](#attack-bottom-half) attack.
+
+We can use this table to specify a starting difficulty that won't allow our target adversary to succeed in an [bottom-half attack](#attack-bottom-half) attack.
+
+Note that in practice verification times are much lower; the scale of the above table does not match the current implementation's reality.
+
+## User experience {#ux}
+
+This proposal has user facing UX consequences.
+
+When the client first attempts a pow, it can note how long iterations of the hash function take, and then use this to determine an estimation of the duration of the PoW.
+This estimation could be communicated via the control port or other mechanism, such that the browser could display how long the PoW is expected to take on their device.
+If the device is a mobile platform, and this time estimation is large, it could recommend that the user try from a desktop machine.
+
+## Future work {#future-work}
+
+### 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 seen in [client-side effort estimation](./common-protocol.md#client-effort) would be alleviated.
+ 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.
+
+### Future designs {#future-designs}
+
+This is just the beginning in DoS defences for Tor and there are various future 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 the `v1` design, and hence we want to start easy before we get into more serious projects.
+The current implementation requires complexity within the Equi-X implementation but its impact on the overall tor network can be relatively simple.
+
+## Environment {#environment}
+
+This algorithm shares a broad concept, proof of work, with some notoriously power hungry and wasteful software. We love the environment, and we too are concerned with how proof of work schemes typically waste huge amounts of energy by doing useless hash iterations.
+
+Nevertheless, there are some massive differences in both the scale and the dynamics of what we are doing here: we are performing fairly small amounts of computation, and it's used as part of a scheme to disincentivize attacks entirely. If we do our job well, people stop computing these proof-of-work functions entirely and find something else to attack.
+
+We think we aren't making a bad situation worse: DoS attacks on the Tor network are already happening and attackers are already burning energy to carry them out.
+As we see in the [denial-of-service overview](../dos-spec/overview.md#hs-intro), attacks on onion services are in a position to cause downstream resource consumption of nearly every type.
+Each relay involved experiences increased CPU load from the circuit floods they process.
+We think that asking legitimate clients to carry out PoW computations doesn't affect the equation too much, since an attacker right now can very quickly use the same resources that hundreds of legitimate clients do in a whole day.
+
+We hope to make things better: The hope is that systems 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 [The DoS Catch-22](./motivation.md#catch22).
+
+## Acknowledgements {#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.
+
+## Scheduler implementation for C tor {#tor-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.
+
+### The Main Loop {#tor-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:
+ - Path selection
+ - 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.
+
+### Requirements for PoW {#tor-pow-queue}
+
+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 ([the introduction queue](./common-protocol.md#intro-queue)).
+- Defer "bottom half" INTRO2 cell processing for after cells have been queued into the priority queue.
+
+### Proposed scheduler {#tor-scheduler}
+
+The intuitive way to address the [queueing requirements](#tor-pow-queue) above 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.
+
+We thus propose to split the INTRODUCE2 handling into two different steps: "top half" and "bottom half" process.
+
+#### Top half and bottom half {#top-half-bottom-half}
+
+The top half process is responsible for queuing introductions into the priority queue as follows:
+
+1. Unpack cell from inbuf to local buffer.
+2. Decrypt cell (AES operations).
+3. Parse INTRODUCE2 cell header and validate PoW.
+4. Return to mainloop event which essentially means step (1).
+
+The top-half basically does all operations from the [main loop](#tor-main-loop) section above, excepting (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:
+
+1. Pop INTRODUCE2 cell from priority queue.
+2. Parse and process INTRODUCE2 cell.
+3. End event and yield back to mainloop.
+
+#### Scheduling the bottom half process {#sched-bottom-half}
+
+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.
+
+## 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.
+
+### 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.
+
+ ```text
+ 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](#tor-main-loop) section above:
+
+ ```text
+ 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 subtract the "bottom half" mean time to get how much the "top half" takes:
+
+ ```text
+ => 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.
+
+## References
+
+```text
+ [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_TEVADOR_2]: https://lists.torproject.org/pipermail/tor-dev/2020-June/014358.html
+ [REF_TEVADOR_SIM]: https://github.com/mikeperry-tor/scratchpad/blob/master/tor-pow/effort_sim.py#L57
+```
diff --git a/spec/hspow-spec/common-protocol.md b/spec/hspow-spec/common-protocol.md
new file mode 100644
index 0000000..e0910ac
--- /dev/null
+++ b/spec/hspow-spec/common-protocol.md
@@ -0,0 +1,203 @@
+# Common protocol
+
+We have made an effort to split the design of the proof-of-work subsystem into an algorithm-specific piece that can be upgraded, and a core protocol that provides queueing and effort adjustment.
+
+Currently there is only one versioned subprotocol defined:
+- [Version 1, Equi-X and Blake2b](./v1-equix.md)
+
+## Overview
+
+```text
+ +----------------------------------+
+ | 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 document takes place during the [introduction phase of the onion service protocol](../rend-spec/introduction-protocol.md).
+
+The system described in this proposal is not meant to be on all the time, and it can be entirely disabled for services that do not experience DoS attacks.
+
+When the subsystem is enabled, suggested effort is continuously adjusted and the computational puzzle can be bypassed entirely when the effort reaches zero.
+In these cases, the proof-of-work subsystem can be dormant but still provide the necessary parameters for clients to voluntarily provide effort in order to get better placement in the priority queue.
+
+The protocol involves the following major steps:
+
+1. Service encodes PoW parameters in descriptor: `pow-params` in the [second layer plaintext format](../rend-spec/hsdesc-encrypt.md#second-layer-plaintext).
+2. Client fetches descriptor and begins solving. Currently this must use the [`v1` solver algorithm](../hspow-spec/v1-equix.md#client-solver).
+3. Client finishes solving and sends results using the [proof-of-work extension to INTRODUCE1](../rend-spec/introduction-protocol.md#INTRO1_POW_EXT).
+4. Service verifies the proof and queues an introduction based on proven effort. This currently uses the [`v1` verify algorithm](../hspow-spec/v1-equix.md#service-verify) only.
+5. Requests are continuously drained from the queue, highest effort first, subject to multiple constraints on speed. See below for more on [handling queued requests](#handling-queue).
+
+## 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 hash table to check whether a (seed, nonce) tuple has been used before for the active 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 or similar as our replay cache mechanism. A probabilistic filter means that we will potentially flag some connections as replays even if they are not, with this false positive probability increasing as the number of entries increase. With the right parameter tuning this probability should be negligible, and dropped requests will be retried by the client.
+
+## The introduction queue {#intro-queue}
+
+When proof-of-work is enabled for a service, that service diverts all incoming introduction requests to a priority queue system rather than handling them immediately.
+
+### Adding introductions to the introduction queue {#add-queue}
+
+When PoW is enabled and an introduction request includes a verified proof, the service queues each request in a data structure sorted by effort. Requests including no proof at all MUST be assigned an effort of zero. Requests with a proof that fails to verify MUST be rejected and not enqueued.
+
+Services MUST check whether the queue is overfull when adding to it, not just when processing requests.
+Floods of low-effort and zero-effort introductions need to be efficiently discarded when the queue is growing faster than it's draining.
+
+The C implementation chooses a maximum number of queued items based on its configured dequeue rate limit multiplied by the circuit timeout.
+In effect, items past this threshold are expected not to be reachable by the time they will timeout.
+When this limit is exceeded, the queue experiences a mass trim event where the lowest effort half of all items are discarded.
+
+### Handling queued introductions {#handling-queue}
+
+When deciding which introduction request to consider next, the service chooses the highest available effort. When efforts are equivalent, the oldest queued request is chosen.
+
+The service should handle introductions only 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 more on how we expect such a system to work in Tor, see the [scheduler analysis and discussion](./analysis-discussion.md#tor-scheduler) section.
+
+## Effort control {#effort-control}
+
+### Overall strategy for effort determination {#effort-strategy}
+
+Denial-of-service 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.
+Instead of forcing clients to go below a static target configured by the service operator, 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.
+Clients automatically increase their bid when retrying, and services regularly offer a suggested starting point based on the recent queue status.
+
+[Motivated users](./motivation.md#user-profiles) can spend a high amount of effort in their PoW computation, which should guarantee access to the service given reasonable adversary models.
+
+An effective effort control algorithm will improve reachability and UX by suggesting values that reduce overall service load to tolerable values while also leaving users with a tolerable overall delay.
+
+The service starts with a default suggested-effort value of 0, which keeps the PoW defenses dormant until we notice signs of queue overload.
+
+The entire process of determining effort can be thought of as a set of multiple coupled feedback loops.
+Clients perform their own effort adjustments via [timeout retry](#client-timeout) atop a base effort suggested by the service.
+That suggestion incorporates the service's control adjustments atop a base effort calculated using a sum of currently-queued client effort.
+
+Each feedback loop has an opportunity to cover different time scales.
+Clients can make adjustments at every single circuit creation request, whereas services are limited by the extra load that frequent updates would place on HSDir nodes.
+
+In the combined client/service system these client-side increases are expected to provide the most effective quick response to an emerging DoS attack.
+After early clients increase the effort using timeouts, later clients benefit from the service detecting this increased queued effort and publishing a larger suggested effort.
+
+Effort increases and decreases both have a cost.
+Increasing effort will make the service more expensive to contact,
+and decreasing effort makes new requests likely to become backlogged behind older requests.
+The steady state condition is preferable to either of these side-effects, but ultimately it's expected that the control loop always oscillates to some degree.
+
+### Service-side effort control {#service-effort}
+
+Services keep an internal suggested effort target which updates on a regular periodic timer in response to measurements made on queue behavior in the previous period.
+These internal effort changes can optionally trigger client-visible [descriptor changes](#service-effort-update) when the difference is great enough to warrant republication to the [HSDir](../rend-spec/hsdesc.md).
+
+This evaluation and update period is referred to as `HS_UPDATE_PERIOD`.
+The service-side effort control loop takes inspiration from TCP congestion control's additive increase / multiplicative decrease approach, but unlike a typical AIMD this algorithm is fixed-rate and doesn't update immediately in response to events.
+
+TODO: `HS_UPDATE_PERIOD` is hardcoded to 300 (5 minutes) currently, but it should be configurable in some way.
+Is it more appropriate to use the service's torrc here or a consensus parameter?
+
+#### Per-period service state {#service-effort-periodic}
+
+During each update period, the service maintains some state:
+
+1. `TOTAL_EFFORT`, a sum of all effort values for rendezvous requests that were successfully validated and enqueued.
+2. `REND_HANDLED`, a count of rendezvous requests that were actually launched. Requests that made it to dequeueing but were too old to launch by then are not included.
+3. `HAD_QUEUE`, a flag which is set if at any time in the update period we saw the priority queue filled with more than a minimum amount of work, greater than we would expect to process in approximately 1/4 second using the configured dequeue rate.
+4. `MAX_TRIMMED_EFFORT`, the largest observed single request effort that we discarded during the period. Requests are discarded either due to age (timeout) or during culling events that discard the bottom half of the entire queue when it's too full.
+
+#### Service AIMD conditions {#service-effort-aimd}
+
+At the end of each period, the service may decide to increase effort, decrease effort, or make no changes, based on these accumulated state values:
+
+1. If `MAX_TRIMMED_EFFORT` > our previous internal `suggested_effort`, always INCREASE.
+ Requests that follow our latest advice are being dropped.
+2. If the `HAD_QUEUE` flag was set and the queue still contains at least one item with effort >= our previous internal `suggested_effort`, INCREASE.
+ Even if we haven't yet reached the point of dropping requests, this signal indicates that our latest suggestion isn't high enough and requests will build up in the queue.
+3. If neither condition 1 or 2 are taking place and the queue is below a level we would expect to process in approximately 1/4 second, choose to DECREASE.
+4. If none of these conditions match, the `suggested_effort` is unchanged.
+
+When we INCREASE, the internal `suggested_effort` is increased to either its previous value + 1, or (`TOTAL_EFFORT` / `REND_HANDLED`), whichever is larger.
+
+When we DECREASE, the internal `suggested_effort` is scaled by 2/3rds.
+
+Over time, this will continue to decrease our effort suggestion any time the service is fully processing its request queue.
+If the queue stays empty, the effort suggestion decreases to zero and clients should no longer submit a proof-of-work solution with their first connection attempt.
+
+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.
+When [adding requests to the queue](#add-queue), services do accept valid solutions with efforts higher or lower than the published values from `pow-params`.
+
+#### Updating descriptor with new suggested effort {#service-effort-update}
+
+The service descriptors may be updated for multiple reasons including introduction point rotation common to all v3 onion services, scheduled seed rotations like the one described for [`v1` parameters](./v1-equix.md#parameter-descriptor), and updates to the effort suggestion.
+Even though the internal effort value updates on a regular timer, we avoid propagating those changes into the descriptor and the HSDir hosts unless there is a significant change.
+
+If the PoW params otherwise match but the seed has changed by less than 15 percent, services SHOULD NOT upload a new descriptor.
+
+### Client-side effort control {#client-effort}
+
+Clients are responsible for making their own effort adjustments in response to connection trouble, to allow the system a chance to react before the service has published new effort values.
+This is an important tool to uphold UX expectations without relying on excessively frequent updates through the HSDir.
+
+TODO: This is the weak link in user experience for our current implementation. The C tor implementation does not detect and retry onion service connections as reliably as we would like. Currently our best strategy to improve retry behavior is the Arti rewrite.
+
+#### Failure ambiguity {#client-failure-ambiguity}
+
+The first challenge in reacting to failure, in our case, is to even accurately and quickly understand when a failure has occurred.
+
+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.
+
+From the client's perspective there's no way to attribute this failure to the service itself rather than the introduction point, so error accounting is performed separately for each introduction-point.
+Prior mechanisms will discard an introduction point that's required too many retries.
+
+#### Clients handling timeouts {#client-timeout}
+
+Alice can fail to reach the onion service if her introduction request gets trimmed off the priority queue when [enqueueing new requests](#add-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.
+If the fetched descriptor includes a new suggested effort or seed, it should first retry the request with these parameters.
+
+TODO: This is not actually implemented yet, but we should do it.
+How often should clients at most try to fetch new descriptors?
+Determined by a consensus parameter?
+This change will also allow clients to retry effectively in cases where the service has just been reconfigured to enable PoW defenses.
+
+Every time the client retries the connection, it will count these failures per-introduction-point. These counts of previous retries are combined with the service's `suggested_effort` when calculating the actual effort to spend on any individual request to a service that advertises PoW support, even when the currently advertised `suggested_effort` is zero.
+
+On each retry, the client modifies its solver effort:
+
+1. If the effort is below `CLIENT_POW_EFFORT_DOUBLE_UNTIL` (= 1000) it will be doubled.
+2. Otherwise, multiply the effort by `CLIENT_POW_RETRY_MULTIPLIER` (= 1.5).
+3. Constrain the effort to no less than `CLIENT_MIN_RETRY_POW_EFFORT` (= 8). Note that this limit is specific to retries only. Clients may use a lower effort for their first connection attempt.
+3. Apply the maximum effort limit [described below](#client-limits).
+
+#### Client-imposed effort limits {#client-limits}
+
+There isn't a practical upper limit on effort defined by the protocol itself, but clients may choose a maximum effort limit to enforce.
+It may be desirable to do this in some cases to improve responsiveness, but the main reason for this limit currently is as a workaround for weak cancellation support in our implementation.
+
+Effort values used for both initial connections and retries are currently limited to no greater than `CLIENT_MAX_POW_EFFORT` (= 10000).
+
+TODO: This hardcoded limit should be replaced by timed limits and/or an unlimited solver with robust cancellation. This is [issue 40787](https://gitlab.torproject.org/tpo/core/tor/-/issues/40787) in C tor.
diff --git a/spec/hspow-spec/index.md b/spec/hspow-spec/index.md
new file mode 100644
index 0000000..14db248
--- /dev/null
+++ b/spec/hspow-spec/index.md
@@ -0,0 +1,5 @@
+# Proof of Work for onion service introduction
+
+The overall denial-of-service prevention strategies in Tor are described in the [Denial-of-service prevention mechanisms in Tor](../dos-spec/index.md) document. This document describes one specific mitigation, the proof-of-work client puzzle for onion service introduction.
+
+This was originally [proposal 327, A First Take at PoW Over Introduction Circuits](../proposals/327-pow-over-intro.txt) authored by George Kadianakis, Mike Perry, David Goulet, and tevador.
diff --git a/spec/hspow-spec/motivation.md b/spec/hspow-spec/motivation.md
new file mode 100644
index 0000000..8fffe3f
--- /dev/null
+++ b/spec/hspow-spec/motivation.md
@@ -0,0 +1,85 @@
+# Motivation
+
+See the [denial-of-service overview](../dos-spec/overview.md) for the big-picture view.
+Here we are focusing on a mitigation for attacks on one specific resource: onion service introductions.
+
+Attackers can generate low-effort floods of introductions which cause the onion service and all involved relays to perform a disproportionate amount of work, leading to a denial-of-service opportunity.
+This proof-of-work scheme intends to make introduction floods unattractive to attackers, reducing the network-wide impact of this activity.
+
+Previous to this work, 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 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 [`draft-nygren-tls-client-puzzles-02`](https://www.ietf.org/archive/id/draft-nygren-tls-client-puzzles-02.txt).
+
+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.
+
+## Related work {#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:
+
+- [`draft-nygren-tls-client-puzzles-02`](https://www.ietf.org/archive/id/draft-nygren-tls-client-puzzles-02.txt)
+- [`draft-nir-tls-puzzles-00`](https://www.ietf.org/archive/id/draft-nir-tls-puzzles-00.txt)
+- [`draft-ietf-ipsecme-ddos-protection-10`](https://tools.ietf.org/html/draft-ietf-ipsecme-ddos-protection-10)
+
+## Threat model
+
+### Attacker profiles {#attacker-profiles}
+
+This mitigation is written to thwart specific attackers. The current protocol is not intended to defend against all and every DoS attack on the Internet, but there are adversary 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 GB 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 at our disposal (see the [discussion on future designs](./analysis-discussion.md#future-designs)).
+
+### User profiles {#user-profiles}
+
+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.
+ 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 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.
+
+### 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.
diff --git a/spec/hspow-spec/v1-equix.md b/spec/hspow-spec/v1-equix.md
new file mode 100644
index 0000000..77b7f95
--- /dev/null
+++ b/spec/hspow-spec/v1-equix.md
@@ -0,0 +1,176 @@
+# Onion service proof-of-work: Version 1, Equi-X and Blake2b
+
+## Implementations {#implementations}
+
+For our `v1` proof-of-work function we use the Equi-X asymmetric client puzzle algorithm by tevador.
+The concept and the C implementation were developed specifically for our use case by tevador, based on a survey of existing work and an analysis of Tor's requirements.
+
+- [Original Equi-X source repository](https://github.com/tevador/equix)
+- [Development log](https://github.com/tevador/equix/blob/master/devlog.md)
+
+Equi-X is an asymmetric PoW function based on Equihash<60,3>, using HashX as the underlying layer.
+It features lightning fast verification speed, and also aims to minimize the asymmetry 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.
+
+At this point there is no formal specification for Equi-X or the underlying HashX function.
+We have two actively maintained implementations of both components, which we subject to automated cross-compatibility and fuzz testing:
+
+- A fork of tevador's implementation is maintained within the C tor repository.
+
+ This is the [`src/ext/equix` subdirectory](https://gitlab.torproject.org/tpo/core/tor/-/tree/main/src/ext/equix).
+ Currently this contains important fixes for security, portability, and testability which have not been merged upstream!
+ This implementation is released under the LGPL license.
+ When `tor` is built with the required `--enable-gpl` option this code will be statically linked.
+
+- As part of Arti, a new Rust re-implementation was written based loosely on tevador's original.
+
+ This is the [`equix` crate](https://tpo.pages.torproject.net/core/doc/rust/equix/index.html).
+ This implementation currently has somewhat lower verification performance than the original but otherwise offers equivalent features.
+
+## Algorithm overview {#overview}
+
+The overall scheme consists of several layers that provide different pieces of this functionality:
+
+1. At the lowest layers, Blake2b and siphash are used as hashing and PRNG algorithms that are well suited to common 64-bit CPUs.
+2. A custom hash function family, HashX, randomizes its implementation for each new seed value.
+ These functions are tuned to utilize the pipelined integer performance on a modern 64-bit CPU.
+ This layer provides the strongest ASIC resistance, since a hardware reimplementation would need to include a CPU-like pipelined execution unit to keep up.
+3. The Equi-X layer itself builds on HashX and adds an algorithmic puzzle that's designed to be strongly asymmetric and to require RAM to solve efficiently.
+4. The PoW protocol itself builds on this Equi-X function with a particular construction of the challenge input and particular constraints on the allowed Blake2b hash of the solution.
+ This layer provides a linearly adjustable effort that we can verify.
+5. At this point, all further layers are part of the [common protocol](./common-protocol.md). Above the level of individual PoW handshakes, the client and service form a closed-loop system that adjusts the effort of future handshakes.
+
+Equi-X itself provides two functions that will be used in this proposal:
+- `equix_solve`(`challenge`) which solves a puzzle instance, returning a variable number of solutions per invocation depending on the specific challenge value.
+- `equix_verify`(`challenge`, `solution`) which verifies a puzzle solution quickly.
+ Verification still depends on executing the HashX function, but far fewer times than when searching for a solution.
+
+For the purposes of this proposal, all cryptographic algorithms are assumed to produce and consume byte strings, even if internally they operate on some other data type like 64-bit words.
+This is conventionally little endian order for Blake2b, which contrasts with Tor's typical use of big endian.
+HashX itself is configured with an 8-byte output but its input is a single 64-bit word of undefined byte order, of which only the low 16 bits are used by Equi-X in its solution output.
+We treat Equi-X solution arrays as byte arrays using their packed little endian 16-bit representation.
+
+## Linear effort adjustment {#effort}
+
+The underlying Equi-X puzzle has an approximately fixed computational cost.
+Adjustable effort comes from the construction of the overlying Blake2b layer, which requires clients to test a variable number of Equi-X solutions in order to find answers which also satisfy this layer's effort constraint.
+
+It's common for proof-of-work systems to define an exponential effort function based on a particular number of leading zero bits or equivalent.
+For the benefit of our effort control system, it's quite useful if we have a linear scale instead. We use the first 32 bits of a hashed version of the Equi-X solution as a uniformly distributed random value.
+
+Conceptually we could define a function:
+```text
+unsigned effort(uint8_t *token)
+```
+which takes as its argument a hashed solution, interprets it as a bitstring, and returns the quotient of dividing a bitstring of 1s by it.
+
+So for example:
+```text
+effort(00000001100010101101) = 11111111111111111111
+ / 00000001100010101101
+```
+or the same in decimal:
+```text
+effort(6317) = 1048575 / 6317 = 165.
+```
+
+In practice we can avoid even having to perform this division, performing just one multiply instead to see if a request's claimed effort is supported by the smallness of the resulting 32-bit hash prefix.
+This assumes we send the desired effort explicitly as part of each PoW solution.
+We do want to force clients to pick a specific effort before looking for a solution, otherwise a client could opportunistically claim a very large effort any time a lucky hash prefix comes up.
+Thus the effort is communicated explicitly in our protocol, and it forms part of the concatenated Equi-X challenge.
+
+## Parameter descriptor {#parameter-descriptor}
+
+This whole protocol starts with the service encoding its parameters in a `pow-params` line within the 'encrypted' (inner) part of the v3 descriptor. The [second layer plaintext format](../rend-spec/hsdesc-encrypt.md#second-layer-plaintext) describes it canonically. The parameters offered are:
+- `type`, always `v1` for the algorithm described here
+- `seed-b64`, a periodically updated 32-byte random seed, base64 encoded
+- `suggested-effort`, the latest output from the [service-side effort controller](./common-protocol.md#service-effort)
+- `expiration-time`, a timestamp when we plan to replace the seed.
+
+Seed expiration and rotation allows used nonces to expire from the anti-replay memory.
+At every seed rotation, a new expiration time is chosen uniformly at random from the recommended range:
+- At the earliest, 105 minutes in the future
+- At the latest, 2 hours in the future (15 minutes later)
+
+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 the usage of seed headings below in the [introduction extension](#intro-ext).
+
+## Client computes a solution {#client-solver}
+
+If a client receives a descriptor with `pow-params`, it should assume that the service is prepared to receive PoW solutions 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.
+If it has, the descriptor may be out of date.
+Clients SHOULD fetch a fresh descriptor if the descriptor is stale and the seed is expired.
+
+Inputs to the solver:
+
+1. Effort `E`, the [client-side effort choice](./common-protocol.md#client-effort) made based on the server's `suggested-effort` and the client's connection attempt history. This is a 32-bit unsigned integer.
+2. Constant personalization string `P`, equal to the following nul-terminated ASCII text: `"Tor hs intro v1\0"`.
+3. Identity string `ID`, a 32-byte value unique to the specific onion service. This is the blinded public ID key `KP_hs_blind_id`.
+4. Seed `C`, a 32-byte random value decoded from `seed-b64` above.
+5. Initial nonce `N`, a 16-byte value generated using a secure random generator.
+
+The solver itself is iterative; the following steps are repeated until they succeed:
+
+1. Construct the *challenge string* by concatenating `P || ID || C || N || htonl(E)`.
+2. Calculate a candidate proof `S` by passing this challenge to Equi-X.
+
+ `S = equix_solve(P || ID || C || N || htonl(E))`
+3. Calculate a 32-bit check value by interpreting a 32-bit Blake2b hash of the concatenated challenge and solution as an integer in network byte order.
+
+ `R = ntohl(blake2b_32(P || ID || C || N || htonl(E) || S))`
+4. Check if 32-bit multiplication of `R * E` would overflow
+
+ If `R * E` overflows (the result would be greater than `UINT32_MAX`) the solver must retry with another nonce value. The client interprets N as a 16-byte little-endian integer, increments it by 1, and goes back to step 1.
+
+ If there is no overflow (the result is less than or equal to `UINT32_MAX`) this is a valid solution. The client can submit final nonce `N`, effort `E`, the first 4 bytes of seed `C`, and proof `S`.
+
+Note that the Blake2b hash includes the output length parameter in its initial state vector, so a `blake2b_32` is not equivalent to the prefix of a `blake2b_512`.
+We calculate the 32-bit Blake2b specifically, and interpret it in network byte order as an unsigned integer.
+
+At the end of the above procedure, the client should have calculated a proof `S` and final nonce `N` that satisfies both the Equi-X proof conditions and the Blake2b effort test.
+The time taken, on average, is linearly proportional with the target effort `E` parameter.
+
+The algorithm as described is suitable for single-threaded computation.
+Optionally, a client may choose multiple nonces and attempt several solutions in parallel on separate CPU cores.
+The specific choice of nonce is entirely up to the client, so parallelization choices like this do not impact the network protocol's interoperability at all.
+
+## Client sends its proof in an INTRO1 extension {#intro-ext}
+
+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. The encrypted portion of the INTRODUCE1 cell only gets read by the onion service and is ignored by the introduction point.
+
+This extension includes the chosen nonce and effort in full, as well as the actual Equi-X proof.
+Clients provide only the first 4 bytes of the seed, enough to disambiguate between multiple recent seeds offered by the service.
+
+This format is defined canonically as the [proof-of-work extension to INTRODUCE1](../rend-spec/introduction-protocol.md#INTRO1_POW_EXT).
+
+## 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 enabled on the service.
+If it's not enabled, the extension SHOULD BE ignored.
+If enabled, even if the suggested effort is currently zero, 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](./common-protocol.md#intro-queue).
+
+To verify the client's proof-of-work the service MUST do the following steps:
+
+1. Find a valid seed `C` that starts with `POW_SEED`.
+ Fail if no such seed exists.
+2. Fail if `N = POW_NONCE` is present in the [replay protection data structure](./common-protocol.md#replay-protection).
+3. Construct the *challenge string* as above by concatenating `P || ID || C || N || htonl(E)`. In this case, `E` and `N` are values provided by the client.
+4. Calculate `R = ntohl(blake2b_32(P || ID || C || N || htonl(E) || S))`, as above
+5. Fail if the the effort test overflows (`R * E > UINT32_MAX`).
+6. Fail if Equi-X reports that the proof `S` is malformed or not applicable (`equix_verify(P || ID || C || N || htonl(E), S) != EQUIX_OK`)
+7. If both the Blake2b and Equi-X tests pass, the request can be enqueued with priority `E`.
+
+It's a minor performance optimization for services to compute the effort test before invoking `equix_verify`.
+Blake2b verification is cheaper than Equi-X verification, so this ordering slightly raises the minimum effort required to perform a [top-half attack](./analysis-discussion.md#attack-top-half).
+
+If any of these steps fail the service MUST ignore this introduction request and abort the protocol.
+
+In this document 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](./common-protocol.md#intro-queue).
diff --git a/spec/param-spec.md b/spec/param-spec.md
index f74319c..088ee77 100644
--- a/spec/param-spec.md
+++ b/spec/param-spec.md
@@ -378,27 +378,75 @@ 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
+"circpad_global_allowed_cells" -- This is the number of padding cells
+that must be sent before the 'circpad_global_max_padding_percent'
+parameter is applied.
+Min: 0. Max: 65535. Default: 0
+
+"circpad_global_max_padding_pct" -- This is the maximum ratio of
+padding cells to total cells, specified as a percent. If the global
+ratio of padding cells to total cells across all circuits exceeds
+this percent value, no more padding is sent until the ratio becomes
+lower. 0 means no limit.
+Min: 0. Max: 100. Default: 0
+
+"circpad_padding_disabled" -- If set to 1, no circuit padding machines
+will negotiate, and all current padding machines will cease padding
+immediately.
+Min: 0. Max: 1. Default: 0
-"nf_pad_before_usage" -- DOCDOC
+"circpad_padding_reduced" -- If set to 1, only circuit padding
+machines marked as "reduced"/"low overhead" will be used.
+(Currently no such machines are marked as "reduced overhead").
+Min: 0. Max: 1. Default: 0
-"nf_pad_relays" -- DOCDOC
+"nf_conntimeout_clients"
+ - The number of seconds to keep never-used circuits opened and
+ available for clients to use. Note that the actual client timeout is
+ randomized uniformly from this value to twice this value.
+ - The number of seconds to keep idle (not currently used) canonical
+ channels are open and available. (We do this to ensure a sufficient
+ time duration of padding, which is the ultimate goal.)
+ - This value is also used to determine how long, after a port has been
+ used, we should attempt to keep building predicted circuits for that
+ port. (See path-spec.txt section 2.1.1.) This behavior was
+ originally added to work around implementation limitations, but it
+ serves as a reasonable default regardless of implementation.
+ - For all use cases, reduced padding clients use half the consensus
+ value.
+ - Implementations MAY mark circuits held open past the reduced padding
+ quantity (half the consensus value) as "not to be used for streams",
+ to prevent their use from becoming a distinguisher.
+Min: 60. Max: 86400. Default: 1800
+
+"nf_conntimeout_relays" -- The number of seconds that idle
+relay-to-relay connections are kept open.
+Min: 60. Max: 604800. Default: 3600
+
+"nf_ito_low" -- The low end of the range to send padding when
+inactive, in ms.
+Min: 0. Max: 60000. Default: 1500
+
+"nf_ito_high" -- The high end of the range to send padding, in ms.
+If nf_ito_low == nf_ito_high == 0, padding will be disabled.
+Min: nf_ito_low. Max: 60000. Default: 9500
+
+"nf_ito_low_reduced" -- For reduced padding clients: the low
+end of the range to send padding when inactive, in ms.
+Min: 0. Max: 60000. Default: 9000
+
+"nf_ito_high_reduced" -- For reduced padding clients: the high
+end of the range to send padding, in ms.
+Min: nf_ito_low_reduced. Max: 60000. Default: 14000
+
+"nf_pad_before_usage" -- If set to 1, OR connections are padded
+before the client uses them for any application traffic. If 0,
+OR connections are not padded until application data begins.
+Min: 0. Max: 1. Default: 1
+
+"nf_pad_relays" -- If set to 1, we also pad inactive
+relay-to-relay connections.
+Min: 0. Max: 1. Default: 0
"nf_pad_single_onion" -- DOCDOC
diff --git a/spec/rend-spec/hsdesc-encrypt.md b/spec/rend-spec/hsdesc-encrypt.md
index 06713a2..09aacbd 100644
--- a/spec/rend-spec/hsdesc-encrypt.md
+++ b/spec/rend-spec/hsdesc-encrypt.md
@@ -239,13 +239,42 @@ list of intro points etc. The plaintext has the following format:
"single-onion-service"
- [None or at most once]
+ [At most once]
If present, this line indicates that the service is a Single Onion
Service (see prop260 for more details about that type of service). This
field has been introduced in 0.3.0 meaning 0.2.9 service don't include
this.
+ "pow-params" SP type SP seed-b64 SP suggested-effort
+ SP expiration-time NL
+
+ [At most once per "type"]
+
+ If present, this line provides parameters for an optional proof-of-work
+ client puzzle. A client that supports an offered scheme can include a
+ corresponding solution in its introduction request to improve priority
+ in the service's processing queue.
+
+ Only version 1 is currently defined.
+ Other versions may have a different format.
+ Introduced in tor-0.4.8.1-alpha.
+
+ 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. Can be
+ zero to mean that PoW is available but not currently
+ suggested for a first connection attempt.
+
+ expiration-time: A timestamp in "YYYY-MM-DDTHH:MM:SS" format (iso time
+ with no space) after which the above seed expires and
+ is no longer valid as the input for PoW.
+
Followed by zero or more introduction points as follows (see section
[NUM_INTRO_POINT] below for accepted values):
diff --git a/spec/rend-spec/introduction-protocol.md b/spec/rend-spec/introduction-protocol.md
index 98e71a2..dee054f 100644
--- a/spec/rend-spec/introduction-protocol.md
+++ b/spec/rend-spec/introduction-protocol.md
@@ -34,7 +34,7 @@ the introduction request to the client.
<a id="rend-spec-v3.txt-3.1.1"></a>
-### Extensible ESTABLISH_INTRO protocol. {#EST_INTRO}
+### Extensible ESTABLISH_INTRO protocol {#EST_INTRO}
When a hidden service is establishing a new introduction point, it
sends an ESTABLISH_INTRO cell with the following contents:
@@ -115,15 +115,17 @@ later in INTRODUCE1 cells.
<a id="rend-spec-v3.txt-3.1.1.1"></a>
-#### Denial-of-Service Defense Extension. {#EST_INTRO_DOS_EXT}
+#### Denial-of-Service defense extension {#EST_INTRO_DOS_EXT}
This extension can be used to send Denial-of-Service (DoS) parameters to
the introduction point in order for it to apply them for the introduction
circuit.
+This is for the [rate limiting DoS mitigation](../dos-spec/overview.md#hs-intro-rate) specifically.
+
If used, it needs to be encoded within the N_EXTENSIONS field of the
ESTABLISH_INTRO cell defined in the previous section. The content is
-defined as follow:
+defined as follows:
EXT_FIELD_TYPE:
@@ -240,7 +242,7 @@ apply to the extension fields here as described \[EST_INTRO\] above.
<a id="rend-spec-v3.txt-3.2"></a>
-## Sending an INTRODUCE1 cell to the introduction point. {#SEND_INTRO1}
+## Sending an INTRODUCE1 cell to the introduction point {#SEND_INTRO1}
In order to participate in the introduction protocol, a client must
know the following:
@@ -267,7 +269,7 @@ or that its request will not succeed.
<a id="rend-spec-v3.txt-3.2.1"></a>
-### INTRODUCE1 cell format {#FMT_INTRO1}
+### Extensible INTRODUCE1 cell format {#FMT_INTRO1}
When a client is connecting to an introduction point, INTRODUCE1 cells
should be of the form:
@@ -310,6 +312,51 @@ client.)
The same rules for multiplicity, ordering, and handling unknown types
apply to the extension fields here as described \[EST_INTRO\] above.
+#### Proof-of-work extension to INTRODUCE1 {#INTRO1_POW_EXT}
+
+This extension can be used to optionally attach a proof of work to the introduction request.
+The proof must be calculated using unique parameters appropriate for this specific service.
+An acceptable proof will raise the priority of this introduction request according to the proof's verified computational effort.
+
+This is for the [proof-of-work DoS mitigation](../dos-spec/overview.md#hs-intro-pow), described in depth by the [Proof of Work for onion service introduction](../hspow-spec/index.md) specification.
+
+If used, it needs to be encoded within the N_EXTENSIONS field of the
+ESTABLISH_INTRO cell defined in the previous section. The content is
+defined as follows:
+
+EXT_FIELD_TYPE:
+
+\[02\] -- `PROOF_OF_WORK`
+
+```text
+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 here
+POW_NONCE is the nonce value chosen by the client's solver
+POW_EFFORT is the effort value chosen by the client,
+ as a 32-bit integer in network byte order
+POW_SEED identifies which seed was in use, by its first 4 bytes
+POW_SOLUTION is a matching proof computed by the client's solver
+```
+
+Only version 1 is currently defined.
+Other versions may have a different format.
+A correctly functioning client only submits solutions with a version and seed which were advertised by the server and have not yet expired.
+An extension with an unknown version or expired seed is suspicious and SHOULD result in introduction failure.
+
+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.
+
+Introduced in tor-0.4.8.1-alpha.
+
<a id="rend-spec-v3.txt-3.2.2"></a>
### INTRODUCE_ACK cell format. {#INTRO_ACK}
@@ -487,14 +534,14 @@ prop327.
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] of prop327).
+section \[INTRO_QUEUE\] of prop327).
(TODO: We should have a proof-of-work.md to fold in prop327. For now, just
point to the proposal.)
#### Subprotocol Request
-[RESERVED]
+\[RESERVED\]
EXT_FIELD_TYPE:
diff --git a/spec/rend-spec/revision-counter-mgt.md b/spec/rend-spec/revision-counter-mgt.md
index 9088cf7..22a5772 100644
--- a/spec/rend-spec/revision-counter-mgt.md
+++ b/spec/rend-spec/revision-counter-mgt.md
@@ -9,73 +9,74 @@ choose a strategy also used by other Tor implementations. Here we
describe two, and additionally list some strategies that implementors
should NOT use.
-F.1. Increment-on-generation
+## F.1. Increment-on-generation {#increment-on-generation}
-```text
- This is the simplest strategy, and the one used by Tor through at
- least version 0.3.4.0-alpha.
+This is the simplest strategy, and the one used by Tor through at
+least version 0.3.4.0-alpha.
- Whenever using a new blinded key, the service records the
- highest revision counter it has used with that key. When generating
- a descriptor, the service uses the smallest non-negative number
- higher than any number it has already used.
+Whenever using a new blinded key, the service records the
+highest revision counter it has used with that key. When generating
+a descriptor, the service uses the smallest non-negative number
+higher than any number it has already used.
- In other words, the revision counters under this system start fresh
- with each blinded key as 0, 1, 2, 3, and so on.
+In other words, the revision counters under this system start fresh
+with each blinded key as 0, 1, 2, 3, and so on.
- F.2. Encrypted time in period
+## F.2. Encrypted time in period {#encrypted-time}
- This scheme is what we recommend for situations when multiple
- service instances need to coordinate their revision counters,
- without an actual coordination mechanism.
+This scheme is what we recommend for situations when multiple
+service instances need to coordinate their revision counters,
+without an actual coordination mechanism.
- Let T be the number of seconds that have elapsed since the descriptor
- became valid, plus 1. (T must be at least 1.) Implementations can use the
- number of seconds since the start time of the shared random protocol run
- that corresponds to this descriptor.
+Let T be the number of seconds that have elapsed
+since the beginning of the time period,
+plus 1. (T must be at least 1.)
- Let S be a secret that all the service providers share. For
- example, it could be the private signing key corresponding to the
- current blinded key.
+Let S be a secret that all the service providers share. For
+example, it could be the private signing key corresponding to the
+current blinded key.
- Let K be an AES-256 key, generated as
- K = H("rev-counter-generation" | S)
+Let K be an AES-256 key, generated as
+```
+K = H("rev-counter-generation" | S)
+```
- Use K, and AES in counter mode with IV=0, to generate a stream of T
- * 2 bytes. Consider these bytes as a sequence of T 16-bit
- little-endian words. Add these words.
+Use `K`, and AES in counter mode with IV=0, to generate a stream of
+`T * 2` bytes. Consider these bytes as a sequence of T 16-bit
+little-endian words. Add these words.
- Let the sum of these words be the revision counter.
+Let the sum of these words, plus T, be the revision counter.
- Cryptowiki attributes roughly this scheme to G. Bebek in:
+> (We include T in the sum so that every increment in T adds at least
+> one to the output.)
- G. Bebek. Anti-tamper database research: Inference control
- techniques. Technical Report EECS 433 Final Report, Case
- Western Reserve University, November 2002.
+Cryptowiki attributes roughly this scheme to G. Bebek in:
- Although we believe it is suitable for use in this application, it
- is not a perfect order-preserving encryption algorithm (and all
- order-preserving encryption has weaknesses). Please think twice
- before using it for anything else.
+> G. Bebek. Anti-tamper database research: Inference control
+> techniques. Technical Report EECS 433 Final Report, Case
+> Western Reserve University, November 2002.
- (This scheme can be optimized pretty easily by caching the encryption of
- X*1, X*2, X*3, etc for some well chosen X.)
+Although we believe it is suitable for use in this application, it
+is not a perfect order-preserving encryption algorithm (and all
+order-preserving encryption has weaknesses). Please think twice
+before using it for anything else.
- For a slow reference implementation, see src/test/ope_ref.py in the
- Tor source repository. [XXXX for now, see the same file in Nick's
- "ope_hax" branch -- it isn't merged yet.]
+(This scheme can be optimized pretty easily by caching the encryption of
+`X*1`, `X*2`, `X*3`, etc for some well chosen `X`.)
- This scheme is not currently implemented in Tor.
+For a slow reference implementation
+that can generate test vectors,
+see `src/test/ope_ref.py` in the
+Tor source repository.
- F.X. Some revision-counter strategies to avoid
+## F.X. Some revision-counter strategies to avoid {#avoid}
- Though it might be tempting, implementations SHOULD NOT use the
- current time or the current time within the period directly as their
- revision counter -- doing so leaks their view of the current time,
- which can be used to link the onion service to other services run on
- the same host.
+Though it might be tempting, implementations SHOULD NOT use the
+current time or the current time within the period directly as their
+revision counter -- doing so leaks their view of the current time,
+which can be used to link the onion service to other services run on
+the same host.
- Similarly, implementations SHOULD NOT let the revision counter
- increase forever without resetting it -- doing so links the service
- across changes in the blinded public key.
-```
+Similarly, implementations SHOULD NOT let the revision counter
+increase forever without resetting it -- doing so links the service
+across changes in the blinded public key.
diff --git a/spec/tor-spec/create-created-cells.md b/spec/tor-spec/create-created-cells.md
index 965cad1..8975cca 100644
--- a/spec/tor-spec/create-created-cells.md
+++ b/spec/tor-spec/create-created-cells.md
@@ -141,10 +141,10 @@ connect to it. Recognized specifiers are:
| Value | Description
| ----- | -----------
-| [00] | TLS-over-TCP, IPv4 address. A four-byte IPv4 address plus two-byte ORPort.
-| [01] | TLS-over-TCP, IPv6 address. A sixteen-byte IPv6 address plus two-byte ORPort.
-| [02] | Legacy identity. A 20-byte SHA1 identity fingerprint. At most one may be listed.
-| [03] | Ed25519 identity. A 32-byte Ed25519 identity fingerprint. At most one may be listed.
+| \[00\] | TLS-over-TCP, IPv4 address. A four-byte IPv4 address plus two-byte ORPort.
+| \[01\] | TLS-over-TCP, IPv6 address. A sixteen-byte IPv6 address plus two-byte ORPort.
+| \[02\] | Legacy identity. A 20-byte SHA1 identity fingerprint. At most one may be listed.
+| \[03\] | Ed25519 identity. A 32-byte Ed25519 identity fingerprint. At most one may be listed.
Nodes MUST ignore unrecognized specifiers, and MUST accept multiple
instances of specifiers other than 'legacy identity' and
@@ -336,7 +336,7 @@ The server's handshake reply is:
| `SERVER_KP` | `Y` | `G_LENGTH` bytes
| `AUTH` | `H(auth_input, t_mac)` | `H_LENGTH` bytes
-The client then checks `Y` is in G<sup>*</sup> [see NOTE below], and computes
+The client then checks `Y` is in G<sup>*</sup> \[see NOTE below\], and computes
```text
secret_input = EXP(Y,x) | EXP(B,x) | ID | B | X | Y | PROTOID
@@ -601,21 +601,24 @@ they may be overridden in the description of individual extensions.)
Currently supported extensions are:
- * 1 -- `CC_FIELD_REQUEST` [Client to server]
+ * 1 -- `CC_FIELD_REQUEST` \[Client to server\]
Contains an empty payload. Signifies that the client
wants to use the extended congestion control described
- in proposal 324.
+ in [proposal 324].
- * 2 -- `CC_FIELD_RESPONSE` [Server to client]
+ * 2 -- `CC_FIELD_RESPONSE` \[Server to client\]
Indicates that the relay will use the congestion control
- of proposal 324, as requested by the client. One byte
+ of [proposal 324], as requested by the client. One byte
in length:
`sendme_inc [1 byte]`
- * 3 -- Subprotocol Request [Client to Server]
+ * 3 -- Subprotocol Request \[Client to Server\]
(RESERVED) Tells the endpoint what protocol version to use on the
- circuit (prop346).
+ circuit ([proposal 346]).
+
+[proposal 324]: ../proposals/324-rtt-congestion-control.txt
+[proposal 346]: ../proposals/346-protovers-again.md
diff --git a/spec/tor-spec/flow-control.md b/spec/tor-spec/flow-control.md
index 91c04e3..e0f7ad1 100644
--- a/spec/tor-spec/flow-control.md
+++ b/spec/tor-spec/flow-control.md
@@ -24,7 +24,9 @@ a high-priority (non-relayed) cell. If it's been less than N seconds
(currently N=30), we give the whole connection high priority, else we
give the whole connection low priority. We also give low priority
to reads and writes for connections that are serving directory
-information. See proposal 111 for details.
+information. See [proposal 111] for details.
+
+[proposal 111]: ../proposals/111-local-traffic-priority.txt
<a id="tor-spec.txt-7.2"></a>
diff --git a/spec/tor-spec/negotiating-channels.md b/spec/tor-spec/negotiating-channels.md
index c328e12..1ab3721 100644
--- a/spec/tor-spec/negotiating-channels.md
+++ b/spec/tor-spec/negotiating-channels.md
@@ -22,7 +22,7 @@ In brief:
to establish clock skew and IP addresses.
- The initiator checks whether the CERTS cell is correct,
and decides whether to authenticate.
- - If the initiator does not wants to authenticate,
+ - If the initiator does not wants to authenticate,
it sends a [NETINFO cell](#NETINFO-cells).
- If the initiator wants to authenticate,
it sends a [CERTS cell](#CERTS-cells),
@@ -38,6 +38,24 @@ except for VPADDING cells.
by scanning-resistance designs.
It is not specified here.)
+```mermaid
+sequenceDiagram
+ Initiator --> Responder: TLS Handshake
+
+ Note over Initiator,Responder: The rest is encrypted
+
+ Initiator ->> Responder: VERSIONS
+ Responder ->> Initiator: VERSIONS, CERTS, AUTH_CHALLENGE, NETINFO
+
+ opt if the initiator wants to authenticate
+ Initiator ->> Responder: CERTS, AUTHENTICATE
+ end
+
+ Initiator ->> Responder: NETINFO
+```
+
+
+
## The TLS handshake {#tls}
<span id="in-protocol">The
@@ -303,34 +321,34 @@ cell, and authenticated the responder.
If AuthType is 1 (meaning "RSA-SHA256-TLSSecret"), then the
Authentication field of the AUTHENTICATE cell contains the following:
-* TYPE: The characters "AUTH0001" [8 octets]
-* CID: A SHA256 hash of the initiator's RSA1024 identity key [32 octets]
-* SID: A SHA256 hash of the responder's RSA1024 identity key [32 octets]
+* TYPE: The characters "AUTH0001" \[8 octets\]
+* CID: A SHA256 hash of the initiator's RSA1024 identity key \[32 octets\]
+* SID: A SHA256 hash of the responder's RSA1024 identity key \[32 octets\]
* SLOG: A SHA256 hash of all bytes sent from the responder to the
initiator as part of the negotiation up to and including the
AUTH_CHALLENGE cell; that is, the VERSIONS cell, the CERTS cell,
- the AUTH_CHALLENGE cell, and any padding cells. [32 octets]
+ the AUTH_CHALLENGE cell, and any padding cells. \[32 octets\]
* CLOG: A SHA256 hash of all bytes sent from the initiator to the
responder as part of the negotiation so far; that is, the
- VERSIONS cell and the CERTS cell and any padding cells. [32
- octets]
-* SCERT: A SHA256 hash of the responder's TLS link certificate. [32
- octets]
+ VERSIONS cell and the CERTS cell and any padding cells. \[32
+ octets\]
+* SCERT: A SHA256 hash of the responder's TLS link certificate. \[32
+ octets\]
* TLSSECRETS: A SHA256 HMAC, using the TLS master secret as the
secret key, of the following:
- client_random, as sent in the TLS Client Hello
- server_random, as sent in the TLS Server Hello
- the NUL terminated ASCII string:
"Tor V3 handshake TLS cross-certification"
- [32 octets]
+ \[32 octets\]
* RAND: A 24 byte value, randomly chosen by the initiator. (In an
imitation of SSL3's gmt_unix_time field, older versions of Tor
sent an 8-byte timestamp as the first 8 bytes of this field;
- new implementations should not do that.) [24 octets]
+ new implementations should not do that.) \[24 octets\]
* SIG: A signature of a SHA256 hash of all the previous fields
using the initiator's "Authenticate" key as presented. (As
always in Tor, we use OAEP-MGF1 padding; see [Ciphers](./preliminaries.md#ciphers))
- [variable length]
+ \[variable length\]
To check the AUTHENTICATE cell, a responder checks that all fields
from TYPE through TLSSECRETS contain their unique
@@ -352,31 +370,31 @@ Authentication field of the AuthType cell is as below:
Modified values and new fields below are marked with asterisks.
-* TYPE: The characters "AUTH0003" [8 octets]
-* CID: A SHA256 hash of the initiator's RSA1024 identity key [32 octets]
-* SID: A SHA256 hash of the responder's RSA1024 identity key [32 octets]
-* CID_ED: The initiator's Ed25519 identity key [32 octets]
-* SID_ED: The responder's Ed25519 identity key, or all-zero. [32 octets]
+* TYPE: The characters "AUTH0003" \[8 octets\]
+* CID: A SHA256 hash of the initiator's RSA1024 identity key \[32 octets\]
+* SID: A SHA256 hash of the responder's RSA1024 identity key \[32 octets\]
+* CID_ED: The initiator's Ed25519 identity key \[32 octets\]
+* SID_ED: The responder's Ed25519 identity key, or all-zero. \[32 octets\]
* SLOG: A SHA256 hash of all bytes sent from the responder to the
initiator as part of the negotiation up to and including the
AUTH_CHALLENGE cell; that is, the VERSIONS cell, the CERTS cell,
- the AUTH_CHALLENGE cell, and any padding cells. [32 octets]
+ the AUTH_CHALLENGE cell, and any padding cells. \[32 octets\]
* CLOG: A SHA256 hash of all bytes sent from the initiator to the
responder as part of the negotiation so far; that is, the
- VERSIONS cell and the CERTS cell and any padding cells. [32
- octets]
-* SCERT: A SHA256 hash of the responder's TLS link certificate. [32
- octets]
+ VERSIONS cell and the CERTS cell and any padding cells. \[32
+ octets\]
+* SCERT: A SHA256 hash of the responder's TLS link certificate. \[32
+ octets\]
* TLSSECRETS: The output of an RFC5705 Exporter function on the
TLS session, using as its inputs:
- The label string "EXPORTER FOR TOR TLS CLIENT BINDING AUTH0003"
- The context value equal to the initiator's Ed25519 identity key.
- The length 32.
- [32 octets]
-* RAND: A 24 byte value, randomly chosen by the initiator. [24 octets]
+ \[32 octets\]
+* RAND: A 24 byte value, randomly chosen by the initiator. \[24 octets\]
* SIG: A signature of all previous fields using the initiator's
Ed25519 authentication key (as in the cert with CertType 6).
- [variable length]
+ \[variable length\]
To check the AUTHENTICATE cell, a responder checks that all fields
from TYPE through TLSSECRETS contain their unique
diff --git a/spec/tor-spec/relay-cells.md b/spec/tor-spec/relay-cells.md
index 3f0c3a7..5de6d90 100644
--- a/spec/tor-spec/relay-cells.md
+++ b/spec/tor-spec/relay-cells.md
@@ -44,18 +44,18 @@ The relay commands are:
| 13 | RELAY_BEGIN_DIR | forward |
| 14 | RELAY_EXTEND2 | forward | control
| 15 | RELAY_EXTENDED2 | backward | control
-| 16..18 | Reserved for UDP; Not yet in use, see [prop339][prop339].
-| 19..22 | Reserved for Conflux, see [prop329][prop329].
-| 32..40 | Used for hidden services; see the [rendezvous spec][rend-spec].
-| 41..42 | Used for circuit padding; see ["Circuit-level padding"][circ-padding] in the padding spec.
-| 43 | XON (See Sec 4 of [prop324][prop324]) | forward or backward |
-| 44 | XOFF (See Sec 4 of [prop324][prop324]) | forward or backward |
+| 16..18 | Reserved for UDP; Not yet in use, see [prop339].
+| 19..22 | Reserved for Conflux, see [prop329].
+| 32..40 | Used for hidden services; see the [rendezvous spec].
+| 41..42 | Used for circuit padding; see ["Circuit-level padding"] in the padding spec.
+| 43 | XON (See Sec 4 of [prop324]) | forward or backward |
+| 44 | XOFF (See Sec 4 of [prop324]) | forward or backward |
[prop324]: ../proposals/324-rtt-congestion-control.txt
[prop329]: ../proposals/329-traffic-splitting.md
[prop339]: ../proposals/339-udp-over-tor.md
-[rend-spec]: ../rend-spec/index.md
-[circ-padding]: ../padding-spec/circuit-level-padding.md#circuit-level-padding
+[rendezvous spec]: ../rend-spec/index.md
+["Circuit-level padding"]: ../padding-spec/circuit-level-padding.md#circuit-level-padding
Commands labelled as "forward" must only be sent by the originator
of the circuit. Commands labelled as "backward" must only be sent by
@@ -108,7 +108,9 @@ bytes for other cell types; see [Cell Packet format](./cell-packet-format.md#cel
<span id="relay-cell-padding">The
'Padding' field is used to make relay cell contents unpredictable, to
-avoid certain attacks (see proposal 289 for rationale). Implementations
+avoid certain attacks (see
+[proposal 289](../proposals/289-authenticated-sendmes.txt)
+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.</span>
diff --git a/spec/tor-spec/resource-exhaustion.md b/spec/tor-spec/resource-exhaustion.md
deleted file mode 100644
index 4dddf9f..0000000
--- a/spec/tor-spec/resource-exhaustion.md
+++ /dev/null
@@ -1,31 +0,0 @@
-<a id="tor-spec.txt-8"></a>
-
-# Handling resource exhaustion
-
-<a id="tor-spec.txt-8.1"></a>
-
-## Memory exhaustion
-
-(See also ["Denial-of-service prevention mechanisms in Tor"](../dos-spec.md).)
-
-If RAM becomes low, an OR should begin destroying circuits until
-more memory is free again. We recommend the following algorithm:
-
-- Set a threshold amount of RAM to recover at 10% of the total RAM.
-
-- Sort the circuits by their 'staleness', defined as the age of the
- oldest data queued on the circuit. This data can be:
-
- * Bytes that are waiting to flush to or from a stream on that
- circuit.
-
- * Bytes that are waiting to flush from a connection created with
- BEGIN_DIR.
-
- * Cells that are waiting to flush or be processed.
-
-- While we have not yet recovered enough RAM:
-
- * Free all memory held by the most stale circuit, and send DESTROY
- cells in both directions on that circuit. Count the amount of
- memory we recovered towards the total.
diff --git a/spec/tor-spec/routing-relay-cells.md b/spec/tor-spec/routing-relay-cells.md
index 15a5f20..abe9828 100644
--- a/spec/tor-spec/routing-relay-cells.md
+++ b/spec/tor-spec/routing-relay-cells.md
@@ -93,4 +93,4 @@ OP receives relay cell from node 1:
Stop and process the payload.
```
-[1]: ["Relay cells"](./relay-cells.md#relay-cells)
+\[1\]: ["Relay cells"](./relay-cells.md#relay-cells)
diff --git a/spec/tor-spec/subprotocol-versioning.md b/spec/tor-spec/subprotocol-versioning.md
index 780a337..8d241cc 100644
--- a/spec/tor-spec/subprotocol-versioning.md
+++ b/spec/tor-spec/subprotocol-versioning.md
@@ -85,7 +85,7 @@ Current versions are:
* "1" is the RSA link authentication described in [Link authentication type 1: RSA-SHA256-TLSSecret](./negotiating-channels.md#RSA-SHA256-TLSSecret).
- * "2" is unused, and reserved by proposal 244.
+ * "2" is unused, and reserved by [proposal 244].
* "3" is the ed25519 link authentication described in [Link authentication type 3: Ed25519-SHA256-RFC5705](./negotiating-channels.md#Ed25519-SHA256-RFC5705).
@@ -155,14 +155,15 @@ Current versions are as follows.
* react to consensuses recommending or requiring support for
"Relay=3".
- This subprotocol version is described in proposal 311, and
- implemented in Tor 0.4.5.1-alpha.
+ This subprotocol version is described in
+ [proposal 311], and implemented in Tor 0.4.5.1-alpha.
* "4" -- support the ntorv3 (version 3) key exchange and all features in
- 0.4.7.3-alpha. This adds a new CREATE2 cell type. See proposal 332
+ 0.4.7.3-alpha. This adds a new CREATE2 cell type. See [proposal 332]
and [The "ntor-v3" handshake](./create-created-cells.md#ntor-v3) for more details.
- * "5" -- [RESERVED] support the ntorv3 subprotocol request extension (prop346)
+ * "5" -- \[RESERVED\] support the ntorv3 subprotocol request extension
+ ([proposal 346])
allowing a client to request what features to be used on a circuit.
<a id="tor-spec.txt-9.4"></a>
@@ -171,11 +172,10 @@ Current versions are as follows.
The "HSIntro" protocol handles introduction points.
- * "3" -- supports authentication as of proposal 121 in Tor
- 0.2.1.6-alpha.
+ * "3" -- supports authentication as of [proposal 121] in Tor 0.2.1.6-alpha.
* "4" -- support ed25519 authentication keys which is defined by the HS v3
- protocol as part of proposal 224 in Tor 0.3.0.4-alpha.
+ protocol as part of [proposal 224] in Tor 0.3.0.4-alpha.
* "5" -- support ESTABLISH_INTRO cell DoS parameters extension for onion
service version 3 only in Tor 0.4.2.1-alpha.
@@ -202,7 +202,7 @@ of URLs available to fetch them.
* "1" -- supports all features in Tor 0.2.0.10-alpha.
* "2" -- support ed25519 blinded keys request which is defined by the HS v3
- protocol as part of proposal 224 in Tor 0.3.0.4-alpha.
+ protocol as part of [proposal 224] in Tor 0.3.0.4-alpha.
<a id="tor-spec.txt-9.7"></a>
@@ -266,12 +266,12 @@ These correspond more or less with consensus methods.
Describes the padding capabilities of the relay.
- * "1" -- [DEFUNCT] Relay supports circuit-level padding. This version MUST NOT
+ * "1" -- \[DEFUNCT\] Relay supports circuit-level padding. This version MUST NOT
be used as it was also enabled in relays that don't actually support
circuit-level padding. Advertised by Tor versions from
tor-0.4.0.1-alpha and only up to and including tor-0.4.1.4-rc.
- * "2" -- Relay supports the HS circuit setup padding machines (proposal 302).
+ * "2" -- Relay supports the HS circuit setup padding machines ([proposal 302]).
Advertised by Tor versions from tor-0.4.1.5 and onwards.
<a id="tor-spec.txt-9.12"></a>
@@ -282,11 +282,11 @@ Describes the flow control protocol at the circuit and stream level. If
there is no FlowCtrl advertised, tor supports the unauthenticated flow
control features (version 0).
- * "1" -- supports authenticated circuit level SENDMEs as of proposal 289 in
+ * "1" -- supports authenticated circuit level SENDMEs as of [proposal 289] in
Tor 0.4.1.1-alpha.
* "2" -- supports congestion control by the Exits which implies a new SENDME
- format and algorithm. See proposal 324 for more details. Advertised
+ format and algorithm. See [proposal 324] for more details. Advertised
in tor 0.4.7.3-alpha.
## "Conflux"
@@ -295,7 +295,7 @@ Describes the communications mechanisms used to bundle circuits together,
in order to split traffic across multiple paths.
> TODO: This is not yet described here. For details see
-> [Proposal 329](../proposals/329-traffic-splitting.txt).
+> [proposal 329].
<a id="tor-spec.txt-9.13"></a>
@@ -303,6 +303,19 @@ in order to split traffic across multiple paths.
Describes the UDP protocol capabilities of a relay.
- * "1" -- [RESERVED] supports UDP by an Exit as in the relay command
- CONNECT_UDP, CONNECTED_UDP and DATAGRAM. See proposal
- 339 for more details. (Not yet advertised, reserved)
+ * "1" -- \[RESERVED\] supports UDP by an Exit as in the relay command
+ CONNECT_UDP, CONNECTED_UDP and DATAGRAM. See [proposal 339] for more details.
+ (Not yet advertised, reserved)
+
+[proposal 121]: ../proposals/121-hidden-service-authentication.txt
+[proposal 224]: ../proposals/224-rend-spec-ng.txt
+[proposal 244]: ../proposals/244-use-rfc5705-for-tls-binding.txt
+[proposal 289]: ../proposals/289-authenticated-sendmes.txt
+[proposal 302]: ../proposals/302-padding-machines-for-onion-clients.txt
+[proposal 311]: ../proposals/311-relay-ipv6-reachability.txt
+[proposal 324]: ../proposals/324-rtt-congestion-control.txt
+[proposal 329]: ../proposals/329-traffic-splitting.txt
+[proposal 332]: ../proposals/332-ntor-v3-with-extra-data.md
+[proposal 339]: ../proposals/339-udp-over-tor.md
+[proposal 346]: ../proposals/346-protovers-again.md
+