aboutsummaryrefslogtreecommitdiff
path: root/proposals
diff options
context:
space:
mode:
Diffstat (limited to 'proposals')
-rw-r--r--proposals/000-index.txt100
-rw-r--r--proposals/001-process.txt2
-rw-r--r--proposals/098-todo.txt6
-rw-r--r--proposals/099-misc.txt7
-rw-r--r--proposals/100-tor-spec-udp.txt2
-rw-r--r--proposals/101-dir-voting.txt2
-rw-r--r--proposals/102-drop-opt.txt2
-rw-r--r--proposals/103-multilevel-keys.txt2
-rw-r--r--proposals/104-short-descriptors.txt2
-rw-r--r--proposals/105-handshake-revision.txt2
-rw-r--r--proposals/106-less-tls-constraint.txt2
-rw-r--r--proposals/107-uptime-sanity-checking.txt2
-rw-r--r--proposals/108-mtbf-based-stability.txt2
-rw-r--r--proposals/109-no-sharing-ips.txt2
-rw-r--r--proposals/110-avoid-infinite-circuits.txt2
-rw-r--r--proposals/111-local-traffic-priority.txt2
-rw-r--r--proposals/112-bring-back-pathlencoinweight.txt2
-rw-r--r--proposals/113-fast-authority-interface.txt2
-rw-r--r--proposals/114-distributed-storage.txt2
-rw-r--r--proposals/115-two-hop-paths.txt2
-rw-r--r--proposals/116-two-hop-paths-from-guard.txt2
-rw-r--r--proposals/117-ipv6-exits.txt2
-rw-r--r--proposals/118-multiple-orports.txt2
-rw-r--r--proposals/119-controlport-auth.txt2
-rw-r--r--proposals/120-shutdown-descriptors.txt2
-rw-r--r--proposals/121-hidden-service-authentication.txt2
-rw-r--r--proposals/122-unnamed-flag.txt2
-rw-r--r--proposals/123-autonaming.txt2
-rw-r--r--proposals/124-tls-certificates.txt2
-rw-r--r--proposals/125-bridges.txt2
-rw-r--r--proposals/126-geoip-reporting.txt2
-rw-r--r--proposals/127-dirport-mirrors-downloads.txt2
-rw-r--r--proposals/128-bridge-families.txt2
-rw-r--r--proposals/129-reject-plaintext-ports.txt2
-rw-r--r--proposals/130-v2-conn-protocol.txt2
-rw-r--r--proposals/131-verify-tor-usage.txt2
-rw-r--r--proposals/132-browser-check-tor-service.txt2
-rw-r--r--proposals/133-unreachable-ors.txt2
-rw-r--r--proposals/134-robust-voting.txt2
-rw-r--r--proposals/135-private-tor-networks.txt2
-rw-r--r--proposals/136-legacy-keys.txt2
-rw-r--r--proposals/137-bootstrap-phases.txt2
-rw-r--r--proposals/138-remove-down-routers-from-consensus.txt2
-rw-r--r--proposals/139-conditional-consensus-download.txt2
-rw-r--r--proposals/140-consensus-diffs.txt2
-rw-r--r--proposals/141-jit-sd-downloads.txt2
-rw-r--r--proposals/142-combine-intro-and-rend-points.txt2
-rw-r--r--proposals/143-distributed-storage-improvements.txt2
-rw-r--r--proposals/144-enforce-distinct-providers.txt2
-rw-r--r--proposals/145-newguard-flag.txt2
-rw-r--r--proposals/146-long-term-stability.txt2
-rw-r--r--proposals/147-prevoting-opinions.txt2
-rw-r--r--proposals/148-uniform-client-end-reason.txt2
-rw-r--r--proposals/149-using-netinfo-data.txt2
-rw-r--r--proposals/150-exclude-exit-nodes.txt2
-rw-r--r--proposals/151-path-selection-improvements.txt2
-rw-r--r--proposals/152-single-hop-circuits.txt2
-rw-r--r--proposals/153-automatic-software-update-protocol.txt2
-rw-r--r--proposals/154-automatic-updates.txt2
-rw-r--r--proposals/155-four-hidden-service-improvements.txt2
-rw-r--r--proposals/156-tracking-blocked-ports.txt2
-rw-r--r--proposals/157-specific-cert-download.txt2
-rw-r--r--proposals/158-microdescriptors.txt2
-rw-r--r--proposals/159-exit-scanning.txt2
-rw-r--r--proposals/160-bandwidth-offset.txt2
-rw-r--r--proposals/161-computing-bandwidth-adjustments.txt2
-rw-r--r--proposals/162-consensus-flavors.txt2
-rw-r--r--proposals/163-detecting-clients.txt2
-rw-r--r--proposals/164-reporting-server-status.txt2
-rw-r--r--proposals/165-simple-robust-voting.txt2
-rw-r--r--proposals/166-statistics-extra-info-docs.txt2
-rw-r--r--proposals/167-params-in-consensus.txt2
-rw-r--r--proposals/168-reduce-circwindow.txt2
-rw-r--r--proposals/169-eliminating-renegotiation.txt2
-rw-r--r--proposals/170-user-path-config.txt2
-rw-r--r--proposals/171-separate-streams.txt2
-rw-r--r--proposals/172-circ-getinfo-option.txt2
-rw-r--r--proposals/173-getinfo-option-expansion.txt2
-rw-r--r--proposals/174-optimistic-data-server.txt2
-rw-r--r--proposals/175-automatic-node-promotion.txt2
-rw-r--r--proposals/176-revising-handshake.txt2
-rw-r--r--proposals/177-flag-abstention.txt2
-rw-r--r--proposals/178-param-voting.txt2
-rw-r--r--proposals/179-TLS-cert-and-parameter-normalization.txt2
-rw-r--r--proposals/180-pluggable-transport.txt2
-rw-r--r--proposals/181-optimistic-data-client.txt2
-rw-r--r--proposals/182-creditbucket.txt2
-rw-r--r--proposals/183-refillintervals.txt2
-rw-r--r--proposals/184-v3-link-protocol.txt2
-rw-r--r--proposals/185-dir-without-dirport.txt2
-rw-r--r--proposals/186-multiple-orports.txt2
-rw-r--r--proposals/187-allow-client-auth.txt2
-rw-r--r--proposals/188-bridge-guards.txt2
-rw-r--r--proposals/189-authorize-cell.txt2
-rw-r--r--proposals/190-shared-secret-bridge-authorization.txt2
-rw-r--r--proposals/191-mitm-bridge-detection-resistance.txt2
-rw-r--r--proposals/192-store-bridge-information.txt2
-rw-r--r--proposals/193-safe-cookie-authentication.txt2
-rw-r--r--proposals/194-mnemonic-urls.txt2
-rw-r--r--proposals/195-TLS-normalization-for-024.txt2
-rw-r--r--proposals/196-transport-control-ports.txt2
-rw-r--r--proposals/197-postmessage-ipc.txt2
-rw-r--r--proposals/198-restore-clienthello-semantics.txt2
-rw-r--r--proposals/199-bridgefinder-integration.txt2
-rw-r--r--proposals/200-new-create-and-extend-cells.txt2
-rw-r--r--proposals/201-bridge-v3-reqs-stats.txt2
-rw-r--r--proposals/202-improved-relay-crypto.txt2
-rw-r--r--proposals/203-https-frontend.txt2
-rw-r--r--proposals/204-hidserv-subdomains.txt2
-rw-r--r--proposals/205-local-dnscache.txt2
-rw-r--r--proposals/206-directory-sources.txt2
-rw-r--r--proposals/207-directory-guards.txt2
-rw-r--r--proposals/208-ipv6-exits-redux.txt2
-rw-r--r--proposals/209-path-bias-tuning.txt2
-rw-r--r--proposals/210-faster-headless-consensus-bootstrap.txt2
-rw-r--r--proposals/211-mapaddress-tor-status.txt2
-rw-r--r--proposals/212-using-old-consensus.txt2
-rw-r--r--proposals/213-remove-stream-sendmes.txt2
-rw-r--r--proposals/214-longer-circids.txt2
-rw-r--r--proposals/215-update-min-consensus-ver.txt2
-rw-r--r--proposals/216-ntor-handshake.txt2
-rw-r--r--proposals/217-ext-orport-auth.txt2
-rw-r--r--proposals/218-usage-controller-events.txt2
-rw-r--r--proposals/219-expanded-dns.txt2
-rw-r--r--proposals/220-ecc-id-keys.txt2
-rw-r--r--proposals/221-stop-using-create-fast.txt2
-rw-r--r--proposals/222-remove-client-timestamps.txt2
-rw-r--r--proposals/223-ace-handshake.txt2
-rw-r--r--proposals/224-rend-spec-ng.txt2
-rw-r--r--proposals/225-strawman-shared-rand.txt2
-rw-r--r--proposals/226-bridgedb-database-improvements.txt2
-rw-r--r--proposals/227-vote-on-package-fingerprints.txt2
-rw-r--r--proposals/228-cross-certification-onionkeys.txt2
-rw-r--r--proposals/229-further-socks5-extensions.txt2
-rw-r--r--proposals/230-rsa1024-relay-id-migration.txt2
-rw-r--r--proposals/231-migrate-authority-rsa1024-ids.txt2
-rw-r--r--proposals/232-pluggable-transports-through-proxy.txt2
-rw-r--r--proposals/233-quicken-tor2web-mode.txt2
-rw-r--r--proposals/234-remittance-addresses.txt2
-rw-r--r--proposals/235-kill-named-flag.txt2
-rw-r--r--proposals/236-single-guard-node.txt2
-rw-r--r--proposals/237-directory-servers-for-all.txt2
-rw-r--r--proposals/238-hs-relay-stats.txt2
-rw-r--r--proposals/239-consensus-hash-chaining.txt2
-rw-r--r--proposals/240-auth-cert-revocation.txt2
-rw-r--r--proposals/241-suspicious-guard-turnover.txt2
-rw-r--r--proposals/242-better-families.txt2
-rw-r--r--proposals/243-hsdir-flag-need-stable.txt2
-rw-r--r--proposals/244-use-rfc5705-for-tls-binding.txt2
-rw-r--r--proposals/245-tap-out.txt2
-rw-r--r--proposals/246-merge-hsdir-and-intro.txt2
-rw-r--r--proposals/247-hs-guard-discovery.txt2
-rw-r--r--proposals/248-removing-rsa-identities.txt2
-rw-r--r--proposals/249-large-create-cells.txt2
-rw-r--r--proposals/250-commit-reveal-consensus.txt2
-rw-r--r--proposals/251-netflow-padding.txt2
-rw-r--r--proposals/252-single-onion.txt2
-rw-r--r--proposals/253-oob-hmac.txt2
-rw-r--r--proposals/254-padding-negotiation.txt2
-rw-r--r--proposals/255-hs-load-balancing.txt2
-rw-r--r--proposals/256-key-revocation.txt2
-rw-r--r--proposals/257-hiding-authorities.txt2
-rw-r--r--proposals/258-dirauth-dos.txt2
-rw-r--r--proposals/259-guard-selection.txt2
-rw-r--r--proposals/260-rend-single-onion.txt2
-rw-r--r--proposals/261-aez-crypto.txt2
-rw-r--r--proposals/262-rekey-circuits.txt2
-rw-r--r--proposals/263-ntru-for-pq-handshake.txt2
-rw-r--r--proposals/264-subprotocol-versions.txt8
-rw-r--r--proposals/265-load-balancing-with-overhead.txt29
-rw-r--r--proposals/266-removing-current-obsolete-clients.txt10
-rw-r--r--proposals/267-tor-consensus-transparency.txt2
-rw-r--r--proposals/268-guard-selection.txt2
-rw-r--r--proposals/269-hybrid-handshake.txt2
-rw-r--r--proposals/270-newhope-hybrid-handshake.txt2
-rw-r--r--proposals/271-another-guard-selection.txt2
-rw-r--r--proposals/272-valid-and-running-by-default.txt2
-rw-r--r--proposals/273-exit-relay-pinning.txt2
-rw-r--r--proposals/274-rotate-onion-keys-less.txt2
-rw-r--r--proposals/275-md-published-time-is-silly.txt4
-rw-r--r--proposals/276-lower-bw-granularity.txt2
-rw-r--r--proposals/277-detect-id-sharing.txt2
-rw-r--r--proposals/278-directory-compression-scheme-negotiation.txt2
-rw-r--r--proposals/279-naming-layer-api.txt2
-rw-r--r--proposals/280-privcount-in-tor.txt2
-rw-r--r--proposals/281-bulk-md-download.txt2
-rw-r--r--proposals/282-remove-named-from-consensus.txt4
-rw-r--r--proposals/283-ipv6-in-micro-consensus.txt2
-rw-r--r--proposals/284-hsv3-control-port.txt2
-rw-r--r--proposals/285-utf-8.txt4
-rw-r--r--proposals/286-hibernation-api.txt2
-rw-r--r--proposals/287-reduce-lifetime.txt2
-rw-r--r--proposals/288-privcount-with-shamir.txt2
-rw-r--r--proposals/289-authenticated-sendmes.txt2
-rw-r--r--proposals/290-deprecate-consensus-methods.txt2
-rw-r--r--proposals/291-two-guard-nodes.txt6
-rw-r--r--proposals/292-mesh-vanguards.txt4
-rw-r--r--proposals/293-know-when-to-publish.txt2
-rw-r--r--proposals/294-tls-1.3.txt2
-rw-r--r--proposals/295-relay-crypto-with-adl.txt2
-rw-r--r--proposals/296-expose-bandwidth-files.txt5
-rw-r--r--proposals/297-safer-protover-shutdowns.txt2
-rw-r--r--proposals/298-canonical-families.txt2
-rw-r--r--proposals/299-ip-failure-count.txt2
-rw-r--r--proposals/300-walking-onions.txt2
-rw-r--r--proposals/301-dont-vote-on-package-fingerprints.txt4
-rw-r--r--proposals/302-padding-machines-for-onion-clients.txt2
-rw-r--r--proposals/303-protover-removal-policy.txt2
-rw-r--r--proposals/304-socks5-extending-hs-error-codes.txt2
-rw-r--r--proposals/305-establish-intro-dos-defense-extention.txt2
-rw-r--r--proposals/306-ipv6-happy-eyeballs.txt2
-rw-r--r--proposals/307-onionbalance-v3.txt2
-rw-r--r--proposals/308-counter-galois-onion.txt12
-rw-r--r--proposals/309-optimistic-socks-in-tor.txt2
-rw-r--r--proposals/310-bandaid-on-guard-selection.txt2
-rw-r--r--proposals/311-relay-ipv6-reachability.txt2
-rw-r--r--proposals/312-relay-auto-ipv6-addr.txt2
-rw-r--r--proposals/313-relay-ipv6-stats.txt2
-rw-r--r--proposals/315-update-dir-required-fields.txt2
-rw-r--r--proposals/316-flashflow.md93
-rw-r--r--proposals/317-secure-dns-name-resolution.txt2
-rw-r--r--proposals/319-wide-everything.md4
-rw-r--r--proposals/323-walking-onions-full.md39
-rw-r--r--proposals/324-rtt-congestion-control.txt454
-rw-r--r--proposals/325-packed-relay-cells.md60
-rw-r--r--proposals/326-tor-relay-well-known-uri-rfc8615.md57
-rw-r--r--proposals/327-pow-over-intro.txt554
-rw-r--r--proposals/328-relay-overload-report.md10
-rw-r--r--proposals/329-traffic-splitting.txt1152
-rw-r--r--proposals/331-res-tokens-for-anti-dos.md53
-rw-r--r--proposals/332-ntor-v3-with-extra-data.md6
-rw-r--r--proposals/333-vanguards-lite.md26
-rw-r--r--proposals/334-middle-only-flag.txt2
-rw-r--r--proposals/336-randomize-guard-retries.md8
-rw-r--r--proposals/337-simpler-guard-usability.md2
-rw-r--r--proposals/339-udp-over-tor.md87
-rw-r--r--proposals/340-packed-and-fragmented.md516
-rw-r--r--proposals/341-better-oos.md171
-rw-r--r--proposals/342-decouple-hs-interval.md107
-rw-r--r--proposals/343-rend-caa.txt112
-rw-r--r--proposals/344-protocol-info-leaks.txt1188
-rw-r--r--proposals/345-specs-in-mdbook.md255
-rw-r--r--proposals/346-protovers-again.md298
-rw-r--r--proposals/347-domain-separation.md80
-rw-r--r--proposals/348-udp-app-support.md742
-rw-r--r--proposals/349-command-state-validation.md666
-rw-r--r--proposals/BY_INDEX.md500
-rw-r--r--proposals/BY_INDEX_template.md2
-rw-r--r--proposals/BY_STATUS.md371
-rw-r--r--proposals/BY_STATUS_template.md (renamed from proposals/README_template.md)2
-rw-r--r--proposals/README.md370
-rw-r--r--proposals/SUMMARY.md265
-rw-r--r--proposals/SUMMARY_template.md11
-rw-r--r--proposals/proposal-status.txt2
-rwxr-xr-xproposals/reindex.py200
255 files changed, 7187 insertions, 1893 deletions
diff --git a/proposals/000-index.txt b/proposals/000-index.txt
index 4692f07..7e37484 100644
--- a/proposals/000-index.txt
+++ b/proposals/000-index.txt
@@ -1,3 +1,4 @@
+```
Filename: 000-index.txt
Title: Index of Tor Proposals
Author: Nick Mathewson
@@ -18,8 +19,8 @@ Proposals by number:
000 Index of Tor Proposals [META]
001 The Tor Proposal Process [META]
-098 Proposals that should be written [META]
-099 Miscellaneous proposals [META]
+098 Proposals that should be written [OBSOLETE]
+099 Miscellaneous proposals [OBSOLETE]
100 Tor Unreliable Datagram Extension Proposal [DEAD]
101 Voting on the Tor Directory System [CLOSED]
102 Dropping "opt" from the directory format [CLOSED]
@@ -185,7 +186,7 @@ Proposals by number:
262 Re-keying live circuits with new cryptographic material [RESERVE]
263 Request to change key exchange protocol for handshake v1.2 [OBSOLETE]
264 Putting version numbers on the Tor subprotocols [CLOSED]
-265 Load Balancing with Overhead Parameters [ACCEPTED]
+265 Load Balancing with Overhead Parameters [OPEN]
266 Removing current obsolete clients from the Tor network [SUPERSEDED]
267 Tor Consensus Transparency [OPEN]
268 New Guard Selection Behaviour [OBSOLETE]
@@ -211,24 +212,24 @@ Proposals by number:
288 Privacy-Preserving Statistics with Privcount in Tor (Shamir version) [RESERVE]
289 Authenticating sendme cells to mitigate bandwidth attacks [CLOSED]
290 Continuously update consensus methods [META]
-291 The move to two guard nodes [NEEDS-REVISION]
-292 Mesh-based vanguards [ACCEPTED]
+291 The move to two guard nodes [FINISHED]
+292 Mesh-based vanguards [CLOSED]
293 Other ways for relays to know when to publish [CLOSED]
294 TLS 1.3 Migration [DRAFT]
295 Using ADL for relay cryptography (solving the crypto-tagging attack) [OPEN]
-296 Have Directory Authorities expose raw bandwidth list files [OPEN]
+296 Have Directory Authorities expose raw bandwidth list files [CLOSED]
297 Relaxing the protover-based shutdown rules [CLOSED]
298 Putting family lines in canonical form [CLOSED]
299 Preferring IPv4 or IPv6 based on IP Version Failure Count [SUPERSEDED]
300 Walking Onions: Scaling and Saving Bandwidth [INFORMATIONAL]
-301 Don't include package fingerprints in consensus documents [OPEN]
+301 Don't include package fingerprints in consensus documents [CLOSED]
302 Hiding onion service clients using padding [CLOSED]
303 When and how to remove support for protocol versions [OPEN]
304 Extending SOCKS5 Onion Service Error Codes [CLOSED]
305 ESTABLISH_INTRO Cell DoS Defense Extension [CLOSED]
306 A Tor Implementation of IPv6 Happy Eyeballs [OPEN]
307 Onion Balance Support for Onion Service v3 [RESERVE]
-308 Counter Galois Onion: A New Proposal for Forward-Secure Relay Cryptography [OPEN]
+308 Counter Galois Onion: A New Proposal for Forward-Secure Relay Cryptography [SUPERSEDED]
309 Optimistic SOCKS Data [OPEN]
310 Towards load-balancing in Prop 271 [CLOSED]
311 Tor Relay IPv6 Reachability [ACCEPTED]
@@ -239,27 +240,37 @@ Proposals by number:
316 FlashFlow: A Secure Speed Test for Tor (Parent Proposal) [DRAFT]
317 Improve security aspects of DNS name resolution [NEEDS-REVISION]
318 Limit protover values to 0-63 [CLOSED]
-319 RELAY_FRAGMENT cells [OPEN]
+319 RELAY_FRAGMENT cells [OBSOLETE]
320 Removing TAP usage from v2 onion services [REJECTED]
321 Better performance and usability for the MyFamily option (v2) [ACCEPTED]
322 Extending link specifiers to include the directory port [OPEN]
323 Specification for Walking Onions [OPEN]
-324 RTT-based Congestion Control for Tor [OPEN]
-325 Packed relay cells: saving space on small commands [OPEN]
+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 [DRAFT]
+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 [DRAFT]
+329 Overcoming Tor's Bottlenecks with Traffic Splitting [FINISHED]
330 Modernizing authority contact entries [OPEN]
331 Res tokens: Anonymous Credentials for Onion Service DoS Resilience [DRAFT]
-332 Ntor protocol with extra data, version 3 [FINISHED]
-333 Vanguards lite [FINISHED]
+332 Ntor protocol with extra data, version 3 [CLOSED]
+333 Vanguards lite [CLOSED]
334 A Directory Authority Flag To Mark Relays As Middle-only [SUPERSEDED]
335 An authority-only design for MiddleOnly [CLOSED]
-336 Randomized schedule for guard retries [ACCEPTED]
-337 A simpler way to decide, "Is this guard usable?" [ACCEPTED]
+336 Randomized schedule for guard retries [CLOSED]
+337 A simpler way to decide, "Is this guard usable?" [CLOSED]
338 Use an 8-byte timestamp in NETINFO cells [ACCEPTED]
-339 UDP traffic over Tor [DRAFT]
+339 UDP traffic over Tor [ACCEPTED]
+340 Packed and fragmented relay messages [OPEN]
+341 A better algorithm for out-of-sockets eviction [OPEN]
+342 Decoupling hs_interval and SRV lifetime [DRAFT]
+343 CAA Extensions for the Tor Rendezvous Specification [OPEN]
+344 Prioritizing Protocol Information Leaks in Tor [OPEN]
+345 Migrating the tor specifications to mdbook [CLOSED]
+346 Clarifying and extending the use of protocol versioning [OPEN]
+347 Domain separation for certificate signing keys [OPEN]
+348 UDP Application Support in Tor [OPEN]
+349 Client-Side Command Acceptance Validation [DRAFT]
Proposals by status:
@@ -267,10 +278,9 @@ Proposals by status:
DRAFT:
294 TLS 1.3 Migration
316 FlashFlow: A Secure Speed Test for Tor (Parent Proposal)
- 327 A First Take at PoW Over Introduction Circuits
- 329 Overcoming Tor's Bottlenecks with Traffic Splitting
331 Res tokens: Anonymous Credentials for Onion Service DoS Resilience
- 339 UDP traffic over Tor
+ 342 Decoupling hs_interval and SRV lifetime
+ 349 Client-Side Command Acceptance Validation
NEEDS-REVISION:
212 Increase Acceptable Consensus Age [for 0.2.4.x+]
219 Support for full DNS and DNSSEC resolution in Tor [for 0.2.5.x]
@@ -278,52 +288,49 @@ Proposals by status:
248 Remove all RSA identity keys
269 Transitionally secure hybrid handshakes
279 A Name System API for Tor Onion Services
- 291 The move to two guard nodes
317 Improve security aspects of DNS name resolution
OPEN:
239 Consensus Hash Chaining
240 Early signing key revocation for directory authorities
+ 265 Load Balancing with Overhead Parameters [for arti-dirauth]
267 Tor Consensus Transparency
277 Detect multiple relay instances running with same ID [for 0.3.??]
287 Reduce circuit lifetime without overloading the network
295 Using ADL for relay cryptography (solving the crypto-tagging attack)
- 296 Have Directory Authorities expose raw bandwidth list files
- 301 Don't include package fingerprints in consensus documents
303 When and how to remove support for protocol versions
306 A Tor Implementation of IPv6 Happy Eyeballs
- 308 Counter Galois Onion: A New Proposal for Forward-Secure Relay Cryptography
309 Optimistic SOCKS Data
- 319 RELAY_FRAGMENT cells
322 Extending link specifiers to include the directory port
323 Specification for Walking Onions
- 324 RTT-based Congestion Control for Tor
- 325 Packed relay cells: saving space on small commands
326 The "tor-relay" Well-Known Resource Identifier
330 Modernizing authority contact entries
+ 340 Packed and fragmented relay messages
+ 341 A better algorithm for out-of-sockets eviction
+ 343 CAA Extensions for the Tor Rendezvous Specification
+ 344 Prioritizing Protocol Information Leaks in Tor
+ 346 Clarifying and extending the use of protocol versioning
+ 347 Domain separation for certificate signing keys
+ 348 UDP Application Support in Tor
ACCEPTED:
- 265 Load Balancing with Overhead Parameters [for 0.2.9.x]
- 282 Remove "Named" and "Unnamed" handling from consensus voting [for 0.3.3.x]
- 285 Directory documents should be standardized as UTF-8
- 292 Mesh-based vanguards
+ 282 Remove "Named" and "Unnamed" handling from consensus voting [for arti-dirauth]
+ 285 Directory documents should be standardized as UTF-8 [for arti-dirauth]
311 Tor Relay IPv6 Reachability
312 Tor Relay Automatic IPv6 Address Discovery
313 Tor Relay IPv6 Statistics
321 Better performance and usability for the MyFamily option (v2)
- 336 Randomized schedule for guard retries
- 337 A simpler way to decide, "Is this guard usable?"
338 Use an 8-byte timestamp in NETINFO cells
+ 339 UDP traffic over Tor
META:
000 Index of Tor Proposals
001 The Tor Proposal Process
- 098 Proposals that should be written
- 099 Miscellaneous proposals
202 Two improved relay encryption protocols for Tor cells
257 Refactoring authorities and making them more isolated from the net
290 Continuously update consensus methods
FINISHED:
260 Rendezvous Single Onion Services [in 0.2.9.3-alpha]
- 332 Ntor protocol with extra data, version 3
- 333 Vanguards lite [in 0.4.7.1-alpha]
+ 291 The move to two guard nodes
+ 324 RTT-based Congestion Control for Tor
+ 329 Overcoming Tor's Bottlenecks with Traffic Splitting
CLOSED:
101 Voting on the Tor Directory System [in 0.2.0.x]
102 Dropping "opt" from the directory format [in 0.2.0.x]
@@ -409,14 +416,17 @@ Proposals by status:
271 Another algorithm for guard selection [in 0.3.0.1-alpha]
272 Listed routers should be Valid, Running, and treated as such [in 0.2.9.3-alpha, 0.2.9.4-alpha]
274 Rotate onion keys less frequently [in 0.3.1.1-alpha]
- 275 Stop including meaningful "published" time in microdescriptor consensus [for 0.3.1.x-alpha] [in 0.4.7.3-alpha]
+ 275 Stop including meaningful "published" time in microdescriptor consensus [for 0.3.1.x-alpha] [in 0.4.8.1-alpha]
278 Directory Compression Scheme Negotiation [in 0.3.1.1-alpha]
283 Move IPv6 ORPorts from microdescriptors to the microdesc consensus [for 0.3.3.x] [in 0.3.3.1-alpha]
284 Hidden Service v3 Control Port
289 Authenticating sendme cells to mitigate bandwidth attacks [in 0.4.1.1-alpha]
+ 292 Mesh-based vanguards
293 Other ways for relays to know when to publish [for 0.3.5] [in 0.4.0.1-alpha]
+ 296 Have Directory Authorities expose raw bandwidth list files [in 0.4.0.1-alpha]
297 Relaxing the protover-based shutdown rules [for 0.3.5.x] [in 0.4.0.x]
298 Putting family lines in canonical form [for 0.3.6.x] [in 0.4.0.1-alpha]
+ 301 Don't include package fingerprints in consensus documents
302 Hiding onion service clients using padding [in 0.4.1.1-alpha]
304 Extending SOCKS5 Onion Service Error Codes
305 ESTABLISH_INTRO Cell DoS Defense Extension
@@ -424,8 +434,14 @@ 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]
335 An authority-only design for MiddleOnly [in 0.4.7.2-alpha]
+ 336 Randomized schedule for guard retries
+ 337 A simpler way to decide, "Is this guard usable?"
+ 345 Migrating the tor specifications to mdbook
SUPERSEDED:
112 Bring Back Pathlen Coin Weight
113 Simplifying directory authority administration
@@ -452,6 +468,7 @@ Proposals by status:
266 Removing current obsolete clients from the Tor network
280 Privacy-Preserving Statistics with Privcount in Tor
299 Preferring IPv4 or IPv6 based on IP Version Failure Count
+ 308 Counter Galois Onion: A New Proposal for Forward-Secure Relay Cryptography
334 A Directory Authority Flag To Mark Relays As Middle-only
DEAD:
100 Tor Unreliable Datagram Extension Proposal
@@ -480,6 +497,8 @@ Proposals by status:
286 Controller APIs for hibernation access on mobile
320 Removing TAP usage from v2 onion services
OBSOLETE:
+ 098 Proposals that should be written
+ 099 Miscellaneous proposals
127 Relaying dirport requests to Tor download site / website
131 Help users to verify they are using Tor
132 A Tor Web Service For Verifying Correct Browser Configuration
@@ -502,6 +521,8 @@ Proposals by status:
263 Request to change key exchange protocol for handshake v1.2
268 New Guard Selection Behaviour
270 RebelAlliance: A Post-Quantum Secure Hybrid Handshake Based on NewHope
+ 319 RELAY_FRAGMENT cells
+ 325 Packed relay cells: saving space on small commands
RESERVE:
133 Incorporate Unreachable ORs into the Tor Network
172 GETINFO controller option for circuit information
@@ -521,3 +542,4 @@ Proposals by status:
INFORMATIONAL:
159 Exit Scanning
300 Walking Onions: Scaling and Saving Bandwidth
+```
diff --git a/proposals/001-process.txt b/proposals/001-process.txt
index 7211c3b..51526bb 100644
--- a/proposals/001-process.txt
+++ b/proposals/001-process.txt
@@ -1,3 +1,4 @@
+```
Filename: 001-process.txt
Title: The Tor Proposal Process
Author: Nick Mathewson
@@ -207,3 +208,4 @@ Proposal numbering:
Numbers 000-099 are reserved for special and meta-proposals. 100 and up
are used for actual proposals. Numbers aren't recycled.
+```
diff --git a/proposals/098-todo.txt b/proposals/098-todo.txt
index a0bbbeb..91202c9 100644
--- a/proposals/098-todo.txt
+++ b/proposals/098-todo.txt
@@ -1,8 +1,11 @@
+```
Filename: 098-todo.txt
Title: Proposals that should be written
Author: Nick Mathewson, Roger Dingledine
Created: 26-Jan-2007
-Status: Meta
+Status: Obsolete
+
+{Obsolete: This document has been replaced by the tor-spec issue tracker.}
Overview:
@@ -105,3 +108,4 @@ B.2. ... and that we have no idea how to do.
Let onion keys be not just RSA but maybe DH too, for Paul's reply onion
design.
+```
diff --git a/proposals/099-misc.txt b/proposals/099-misc.txt
index a3621dd..bc44540 100644
--- a/proposals/099-misc.txt
+++ b/proposals/099-misc.txt
@@ -1,8 +1,12 @@
+```
Filename: 099-misc.txt
Title: Miscellaneous proposals
Author: Various
Created: 26-Jan-2007
-Status: Meta
+Status: Obsolete
+
+{This document is obsolete; we only used it once, and we have implemented
+its only idea.)
Overview:
@@ -26,3 +30,4 @@ Proposals
-- Nick Mathewson
+```
diff --git a/proposals/100-tor-spec-udp.txt b/proposals/100-tor-spec-udp.txt
index 7f06222..e9f1eae 100644
--- a/proposals/100-tor-spec-udp.txt
+++ b/proposals/100-tor-spec-udp.txt
@@ -1,3 +1,4 @@
+```
Filename: 100-tor-spec-udp.txt
Title: Tor Unreliable Datagram Extension Proposal
Author: Marc Liberatore
@@ -420,3 +421,4 @@ traffic "for free".
example, what happens when a UDP packet doesn't fit in a single cell?)
-NM
+```
diff --git a/proposals/101-dir-voting.txt b/proposals/101-dir-voting.txt
index 634d3f1..39fa6c6 100644
--- a/proposals/101-dir-voting.txt
+++ b/proposals/101-dir-voting.txt
@@ -1,3 +1,4 @@
+```
Filename: 101-dir-voting.txt
Title: Voting on the Tor Directory System
Author: Nick Mathewson
@@ -281,3 +282,4 @@ by the authorities. -RD]
off very quickly from downloading consensus docs until they're
actually implemented.
+```
diff --git a/proposals/102-drop-opt.txt b/proposals/102-drop-opt.txt
index 490376b..a7d0cbe 100644
--- a/proposals/102-drop-opt.txt
+++ b/proposals/102-drop-opt.txt
@@ -1,3 +1,4 @@
+```
Filename: 102-drop-opt.txt
Title: Dropping "opt" from the directory format
Author: Nick Mathewson
@@ -36,3 +37,4 @@ Status:
once earlier formats are obsolete.
+```
diff --git a/proposals/103-multilevel-keys.txt b/proposals/103-multilevel-keys.txt
index 7ec254a..3bb3c28 100644
--- a/proposals/103-multilevel-keys.txt
+++ b/proposals/103-multilevel-keys.txt
@@ -1,3 +1,4 @@
+```
Filename: 103-multilevel-keys.txt
Title: Splitting identity key from regularly used signing key
Author: Nick Mathewson
@@ -202,3 +203,4 @@ Extensions to Proposal 101.
unknown signing keys might be enough to make the consensus
correctly signed, do not use the consensus, but do not discard
it until we have a new keys document.
+```
diff --git a/proposals/104-short-descriptors.txt b/proposals/104-short-descriptors.txt
index 90e0764..c543bf1 100644
--- a/proposals/104-short-descriptors.txt
+++ b/proposals/104-short-descriptors.txt
@@ -1,3 +1,4 @@
+```
Filename: 104-short-descriptors.txt
Title: Long and Short Router Descriptors
Author: Nick Mathewson
@@ -179,3 +180,4 @@ Migration:
* Once tools that want bandwidth info support fetching extra info:
* Have routers stop including bandwidth info in their router
descriptors.
+```
diff --git a/proposals/105-handshake-revision.txt b/proposals/105-handshake-revision.txt
index 791a016..45a937c 100644
--- a/proposals/105-handshake-revision.txt
+++ b/proposals/105-handshake-revision.txt
@@ -1,3 +1,4 @@
+```
Filename: 105-handshake-revision.txt
Title: Version negotiation for the Tor protocol.
Author: Nick Mathewson, Roger Dingledine
@@ -321,3 +322,4 @@ Security issues:
authorities' RecommmendedVersions mechanism, even if it is still
technically possible to use them.
+```
diff --git a/proposals/106-less-tls-constraint.txt b/proposals/106-less-tls-constraint.txt
index 7e7621d..1655525 100644
--- a/proposals/106-less-tls-constraint.txt
+++ b/proposals/106-less-tls-constraint.txt
@@ -1,3 +1,4 @@
+```
Filename: 106-less-tls-constraint.txt
Title: Checking fewer things during TLS handshakes
Author: Nick Mathewson
@@ -109,3 +110,4 @@ OTHER SPEC CHANGES:
When a client doesn't give us an identity, we should never extend any
circuits to it (duh), and we should allow it to set circuit ID however it
wants.
+```
diff --git a/proposals/107-uptime-sanity-checking.txt b/proposals/107-uptime-sanity-checking.txt
index 922129b..7764889 100644
--- a/proposals/107-uptime-sanity-checking.txt
+++ b/proposals/107-uptime-sanity-checking.txt
@@ -1,3 +1,4 @@
+```
Filename: 107-uptime-sanity-checking.txt
Title: Uptime Sanity Checking
Author: Kevin Bauer & Damon McCoy
@@ -52,3 +53,4 @@ Discussion:
This proposal also led to 108-mtbf-based-stability.txt
+```
diff --git a/proposals/108-mtbf-based-stability.txt b/proposals/108-mtbf-based-stability.txt
index 2941037..962d273 100644
--- a/proposals/108-mtbf-based-stability.txt
+++ b/proposals/108-mtbf-based-stability.txt
@@ -1,3 +1,4 @@
+```
Filename: 108-mtbf-based-stability.txt
Title: Base "Stable" Flag on Mean Time Between Failures
Author: Nick Mathewson
@@ -86,3 +87,4 @@ Implementation:
Servers should probe at random intervals to test whether servers are
running.
+```
diff --git a/proposals/109-no-sharing-ips.txt b/proposals/109-no-sharing-ips.txt
index a0f1fff..98927e9 100644
--- a/proposals/109-no-sharing-ips.txt
+++ b/proposals/109-no-sharing-ips.txt
@@ -1,3 +1,4 @@
+```
Filename: 109-no-sharing-ips.txt
Title: No more than one server per IP address
Author: Kevin Bauer & Damon McCoy
@@ -88,3 +89,4 @@ Compatibility:
[Note Roger's tweak to this behavior, in
http://archives.seul.org/or/cvs/Oct-2007/msg00118.html]
+```
diff --git a/proposals/110-avoid-infinite-circuits.txt b/proposals/110-avoid-infinite-circuits.txt
index 7d6772d..07f5461 100644
--- a/proposals/110-avoid-infinite-circuits.txt
+++ b/proposals/110-avoid-infinite-circuits.txt
@@ -1,3 +1,4 @@
+```
Filename: 110-avoid-infinite-circuits.txt
Title: Avoiding infinite length circuits
Author: Roger Dingledine
@@ -118,3 +119,4 @@ Acknowledgements:
is working on implementing a fix based on this design in the summer
2007 timeframe.)
+```
diff --git a/proposals/111-local-traffic-priority.txt b/proposals/111-local-traffic-priority.txt
index 9411463..762634e 100644
--- a/proposals/111-local-traffic-priority.txt
+++ b/proposals/111-local-traffic-priority.txt
@@ -1,3 +1,4 @@
+```
Filename: 111-local-traffic-priority.txt
Title: Prioritizing local traffic over relayed traffic
Author: Roger Dingledine
@@ -149,3 +150,4 @@ Prognosis:
We could probably remove the third case and it would still work,
but hey.
+```
diff --git a/proposals/112-bring-back-pathlencoinweight.txt b/proposals/112-bring-back-pathlencoinweight.txt
index 3f6c337..5109328 100644
--- a/proposals/112-bring-back-pathlencoinweight.txt
+++ b/proposals/112-bring-back-pathlencoinweight.txt
@@ -1,3 +1,4 @@
+```
Filename: 112-bring-back-pathlencoinweight.txt
Title: Bring Back Pathlen Coin Weight
Author: Mike Perry
@@ -161,3 +162,4 @@ Migration:
[1] http://www.cs.umass.edu/~mwright/papers/levine-timing.pdf
+```
diff --git a/proposals/113-fast-authority-interface.txt b/proposals/113-fast-authority-interface.txt
index 8912b53..55e925f 100644
--- a/proposals/113-fast-authority-interface.txt
+++ b/proposals/113-fast-authority-interface.txt
@@ -1,3 +1,4 @@
+```
Filename: 113-fast-authority-interface.txt
Title: Simplifying directory authority administration
Author: Nick Mathewson
@@ -83,3 +84,4 @@ Resolution:
automatically create bindings", and that approach is implemented.
There are remaining issues in the problem statement above that need
their own solutions.
+```
diff --git a/proposals/114-distributed-storage.txt b/proposals/114-distributed-storage.txt
index 91a787d..1c0f40f 100644
--- a/proposals/114-distributed-storage.txt
+++ b/proposals/114-distributed-storage.txt
@@ -1,3 +1,4 @@
+```
Filename: 114-distributed-storage.txt
Title: Distributed Storage for Tor Hidden Service Descriptors
Author: Karsten Loesing
@@ -437,3 +438,4 @@ Compatibility:
After the second transition phase, the authoritative directories should stop
serving hidden service descriptors.
+```
diff --git a/proposals/115-two-hop-paths.txt b/proposals/115-two-hop-paths.txt
index 9854c9a..7ef07b4 100644
--- a/proposals/115-two-hop-paths.txt
+++ b/proposals/115-two-hop-paths.txt
@@ -1,3 +1,4 @@
+```
Filename: 115-two-hop-paths.txt
Title: Two Hop Paths
Author: Mike Perry
@@ -383,3 +384,4 @@ Migration:
[1] http://p2pnet.net/story/11279
[2] http://www.cs.umass.edu/~mwright/papers/levine-timing.pdf
[3] Proof available upon request ;)
+```
diff --git a/proposals/116-two-hop-paths-from-guard.txt b/proposals/116-two-hop-paths-from-guard.txt
index f456253..8228c7a 100644
--- a/proposals/116-two-hop-paths-from-guard.txt
+++ b/proposals/116-two-hop-paths-from-guard.txt
@@ -1,3 +1,4 @@
+```
Filename: 116-two-hop-paths-from-guard.txt
Title: Two hop paths from entry guards
Author: Michael Lieberman
@@ -116,3 +117,4 @@ MIT
mentioned above.
2) It would give governments an incentive to confiscate exit nodes to see if
they are pulling this trick.
+```
diff --git a/proposals/117-ipv6-exits.txt b/proposals/117-ipv6-exits.txt
index f343ff7..e5231db 100644
--- a/proposals/117-ipv6-exits.txt
+++ b/proposals/117-ipv6-exits.txt
@@ -1,3 +1,4 @@
+```
Filename: 117-ipv6-exits.txt
Title: IPv6 exits
Author: coderman
@@ -409,3 +410,4 @@ Contents
'Network Address Translation - Protocol Translation (NAT-PT)'
http://www.ietf.org/rfc/rfc2766.txt
+```
diff --git a/proposals/118-multiple-orports.txt b/proposals/118-multiple-orports.txt
index 69ab382..0378589 100644
--- a/proposals/118-multiple-orports.txt
+++ b/proposals/118-multiple-orports.txt
@@ -1,3 +1,4 @@
+```
Filename: 118-multiple-orports.txt
Title: Advertising multiple ORPorts at once
Author: Nick Mathewson
@@ -85,3 +86,4 @@ Notes 3 July:
- Write up the simple version of this. No ranges needed yet. No
networkstatus chagnes yet.
+```
diff --git a/proposals/119-controlport-auth.txt b/proposals/119-controlport-auth.txt
index 9ed1cc1..32c70b6 100644
--- a/proposals/119-controlport-auth.txt
+++ b/proposals/119-controlport-auth.txt
@@ -1,3 +1,4 @@
+```
Filename: 119-controlport-auth.txt
Title: New PROTOCOLINFO command for controllers
Author: Roger Dingledine
@@ -138,3 +139,4 @@ Unsolved problems:
to think about how to demand password-based authentication without
bothering the user about it.
+```
diff --git a/proposals/120-shutdown-descriptors.txt b/proposals/120-shutdown-descriptors.txt
index 5cfe2b5..465ef86 100644
--- a/proposals/120-shutdown-descriptors.txt
+++ b/proposals/120-shutdown-descriptors.txt
@@ -1,3 +1,4 @@
+```
Filename: 120-shutdown-descriptors.txt
Title: Shutdown descriptors when Tor servers stop
Author: Roger Dingledine
@@ -81,3 +82,4 @@ Comments:
2) Maybe add a rule "Don't do this for hibernation if we expect to wake
up before the next consensus is published"?
- NM 9 Oct 2007
+```
diff --git a/proposals/121-hidden-service-authentication.txt b/proposals/121-hidden-service-authentication.txt
index 404ca57..678d4d4 100644
--- a/proposals/121-hidden-service-authentication.txt
+++ b/proposals/121-hidden-service-authentication.txt
@@ -1,3 +1,4 @@
+```
Filename: 121-hidden-service-authentication.txt
Title: Hidden Service Authentication
Author: Tobias Kamm, Thomas Lauterbach, Karsten Loesing, Ferdinand Rieger,
@@ -774,3 +775,4 @@ Implementation:
checking access counters.
- Log access for accountability.
+```
diff --git a/proposals/122-unnamed-flag.txt b/proposals/122-unnamed-flag.txt
index 2ce7bb2..d73f2e4 100644
--- a/proposals/122-unnamed-flag.txt
+++ b/proposals/122-unnamed-flag.txt
@@ -1,3 +1,4 @@
+```
Filename: 122-unnamed-flag.txt
Title: Network status entries need a new Unnamed flag
Author: Roger Dingledine
@@ -134,3 +135,4 @@ Implemented-In: 0.2.0.x
blacklisted from the network, the really bad part is that this logic
is really unintuitive to prospective new server operators.
+```
diff --git a/proposals/123-autonaming.txt b/proposals/123-autonaming.txt
index 74c4869..bc9cdfa 100644
--- a/proposals/123-autonaming.txt
+++ b/proposals/123-autonaming.txt
@@ -1,3 +1,4 @@
+```
Filename: 123-autonaming.txt
Title: Naming authorities automatically create bindings
Author: Peter Palfrader
@@ -52,3 +53,4 @@ Proposal:
This automaton does not necessarily need to live in the Tor code, it
can do its job just as well when it's an external tool.
+```
diff --git a/proposals/124-tls-certificates.txt b/proposals/124-tls-certificates.txt
index 9472d14..0149da7 100644
--- a/proposals/124-tls-certificates.txt
+++ b/proposals/124-tls-certificates.txt
@@ -1,3 +1,4 @@
+```
Filename: 124-tls-certificates.txt
Title: Blocking resistant TLS certificate usage
Author: Steven J. Murdoch
@@ -311,3 +312,4 @@ References:
[5] Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer Security (TLS)
% <!-- Local IspellDict: american -->
+```
diff --git a/proposals/125-bridges.txt b/proposals/125-bridges.txt
index 9d95729..2b4d0e6 100644
--- a/proposals/125-bridges.txt
+++ b/proposals/125-bridges.txt
@@ -1,3 +1,4 @@
+```
Filename: 125-bridges.txt
Title: Behavior for bridge users, bridge relays, and bridge authorities
Author: Roger Dingledine
@@ -289,3 +290,4 @@ Implemented-In: 0.2.0.x
We should figure this out in the 0.2.1.x timeframe.
+```
diff --git a/proposals/126-geoip-reporting.txt b/proposals/126-geoip-reporting.txt
index 9f3b21c..131b25f 100644
--- a/proposals/126-geoip-reporting.txt
+++ b/proposals/126-geoip-reporting.txt
@@ -1,3 +1,4 @@
+```
Filename: 126-geoip-reporting.txt
Title: Getting GeoIP data and publishing usage summaries
Author: Roger Dingledine
@@ -408,3 +409,4 @@ Implemented-In: 0.2.0.x
Other ideas?
+```
diff --git a/proposals/127-dirport-mirrors-downloads.txt b/proposals/127-dirport-mirrors-downloads.txt
index 377492c..fcdec60 100644
--- a/proposals/127-dirport-mirrors-downloads.txt
+++ b/proposals/127-dirport-mirrors-downloads.txt
@@ -1,3 +1,4 @@
+```
Filename: 127-dirport-mirrors-downloads.txt
Title: Relaying dirport requests to Tor download site / website
Author: Roger Dingledine
@@ -153,3 +154,4 @@ Status: Obsolete
you about a gmail autoresponder address just as easily, and then you'd
get better authentication of the Tor program to boot.
+```
diff --git a/proposals/128-bridge-families.txt b/proposals/128-bridge-families.txt
index e5bdcf9..67f208e 100644
--- a/proposals/128-bridge-families.txt
+++ b/proposals/128-bridge-families.txt
@@ -1,3 +1,4 @@
+```
Filename: 128-bridge-families.txt
Title: Families of private bridges
Author: Roger Dingledine
@@ -62,3 +63,4 @@ Status: Dead
ideas/ directory. Somebody should pick it up sometime and finish the
design and implementation.
+```
diff --git a/proposals/129-reject-plaintext-ports.txt b/proposals/129-reject-plaintext-ports.txt
index 8080ff5..91b9bd4 100644
--- a/proposals/129-reject-plaintext-ports.txt
+++ b/proposals/129-reject-plaintext-ports.txt
@@ -1,3 +1,4 @@
+```
Filename: 129-reject-plaintext-ports.txt
Title: Block Insecure Protocols by Default
Author: Kevin Bauer & Damon McCoy
@@ -112,3 +113,4 @@ Next steps:
b) We should decide which ports to reject by default. The current
consensus is 23,109,110,143 -- the same set that we warn for now.
+```
diff --git a/proposals/130-v2-conn-protocol.txt b/proposals/130-v2-conn-protocol.txt
index f5c31cc..fddbb75 100644
--- a/proposals/130-v2-conn-protocol.txt
+++ b/proposals/130-v2-conn-protocol.txt
@@ -1,3 +1,4 @@
+```
Filename: 130-v2-conn-protocol.txt
Title: Version 2 Tor connection protocol
Author: Nick Mathewson
@@ -182,3 +183,4 @@ Proposal:
Until NETINFO cells have been exchanged, the connection is not open.
+```
diff --git a/proposals/131-verify-tor-usage.txt b/proposals/131-verify-tor-usage.txt
index 8af1151..19a5737 100644
--- a/proposals/131-verify-tor-usage.txt
+++ b/proposals/131-verify-tor-usage.txt
@@ -1,3 +1,4 @@
+```
Filename: 131-verify-tor-usage.txt
Title: Help users to verify they are using Tor
Author: Steven J. Murdoch
@@ -146,3 +147,4 @@ Related work:
Tor should be able to respond with a webpage to notify the user of how
to fix the problem. This also implies that Tor must be told of the
special IP address, and so must be effectively permanent.
+```
diff --git a/proposals/132-browser-check-tor-service.txt b/proposals/132-browser-check-tor-service.txt
index 7aecaaf..d652d6f 100644
--- a/proposals/132-browser-check-tor-service.txt
+++ b/proposals/132-browser-check-tor-service.txt
@@ -1,3 +1,4 @@
+```
Filename: 132-browser-check-tor-service.txt
Title: A Tor Web Service For Verifying Correct Browser Configuration
Author: Robert Hogan
@@ -143,3 +144,4 @@ Open Issues:
future. Or maybe it's not such a bad thing, Tor is merely attempting to make
normally invalid resource requests valid for a given purpose.
+```
diff --git a/proposals/133-unreachable-ors.txt b/proposals/133-unreachable-ors.txt
index 5e2916b..ed80d7a 100644
--- a/proposals/133-unreachable-ors.txt
+++ b/proposals/133-unreachable-ors.txt
@@ -1,3 +1,4 @@
+```
Filename: 133-unreachable-ors.txt
Title: Incorporate Unreachable ORs into the Tor Network
Author: Robert Hogan
@@ -126,3 +127,4 @@ Implementation Issues:
published OR should be willing to accept is an open question. Is one
hundred, mostly idle, such orconns too onerous?
+```
diff --git a/proposals/134-robust-voting.txt b/proposals/134-robust-voting.txt
index c5dfb3b..66dfef5 100644
--- a/proposals/134-robust-voting.txt
+++ b/proposals/134-robust-voting.txt
@@ -1,3 +1,4 @@
+```
Filename: 134-robust-voting.txt
Title: More robust consensus voting with diverse authority sets
Author: Peter Palfrader
@@ -121,3 +122,4 @@ requirement that an adversary must compromise a majority of authorities
in order to control the consensus.
-- Nick
+```
diff --git a/proposals/135-private-tor-networks.txt b/proposals/135-private-tor-networks.txt
index 19ef68b..7ce0d4c 100644
--- a/proposals/135-private-tor-networks.txt
+++ b/proposals/135-private-tor-networks.txt
@@ -1,3 +1,4 @@
+```
Filename: 135-private-tor-networks.txt
Title: Simplify Configuration of Private Tor Networks
Author: Karsten Loesing
@@ -279,3 +280,4 @@ Test:
[warn] Failed to parse/validate config: TestingTorNetwork may only be
configured in combination with a non-default set of DirServers.
+```
diff --git a/proposals/136-legacy-keys.txt b/proposals/136-legacy-keys.txt
index f2b1b5c..ab8c9de 100644
--- a/proposals/136-legacy-keys.txt
+++ b/proposals/136-legacy-keys.txt
@@ -1,3 +1,4 @@
+```
Filename: 136-legacy-keys.txt
Title: Mass authority migration with legacy keys
Author: Nick Mathewson
@@ -98,3 +99,4 @@ Notes:
I don't think this achieves us anything either, though.
+```
diff --git a/proposals/137-bootstrap-phases.txt b/proposals/137-bootstrap-phases.txt
index ebe044c..fbb5081 100644
--- a/proposals/137-bootstrap-phases.txt
+++ b/proposals/137-bootstrap-phases.txt
@@ -1,3 +1,4 @@
+```
Filename: 137-bootstrap-phases.txt
Title: Keep controllers informed as Tor bootstraps
Author: Roger Dingledine
@@ -233,3 +234,4 @@ Implemented-In: 0.2.1.x
Controllers should use this getinfo when they connect or attach to
Tor to learn its current state.
+```
diff --git a/proposals/138-remove-down-routers-from-consensus.txt b/proposals/138-remove-down-routers-from-consensus.txt
index 776911b..037edbb 100644
--- a/proposals/138-remove-down-routers-from-consensus.txt
+++ b/proposals/138-remove-down-routers-from-consensus.txt
@@ -1,3 +1,4 @@
+```
Filename: 138-remove-down-routers-from-consensus.txt
Title: Remove routers that are not Running from consensus documents
Author: Peter Palfrader
@@ -47,3 +48,4 @@ Implemented-In: 0.2.1.2-alpha
consensus document is formed like before but a new last step removes
all routers from the listing that are not marked as Running.
+```
diff --git a/proposals/139-conditional-consensus-download.txt b/proposals/139-conditional-consensus-download.txt
index 941f5ad..ea00acc 100644
--- a/proposals/139-conditional-consensus-download.txt
+++ b/proposals/139-conditional-consensus-download.txt
@@ -1,3 +1,4 @@
+```
Filename: 139-conditional-consensus-download.txt
Title: Download consensus documents only when it will be trusted
Author: Peter Palfrader
@@ -92,3 +93,4 @@ Footnotes:
1. For the purpose of this proposal a client can be any Tor instance
that downloads a consensus document. This includes relays,
directory caches as well as end users.
+```
diff --git a/proposals/140-consensus-diffs.txt b/proposals/140-consensus-diffs.txt
index c50aba0..d1a5a1d 100644
--- a/proposals/140-consensus-diffs.txt
+++ b/proposals/140-consensus-diffs.txt
@@ -1,3 +1,4 @@
+```
Filename: 140-consensus-diffs.txt
Title: Provide diffs between consensuses
Author: Peter Palfrader
@@ -231,3 +232,4 @@ Ticket: https://bugs.torproject.org/13339
This parameter determines how old a consensus can be (in hours)
before a client should no longer try to find a diff for it.
+```
diff --git a/proposals/141-jit-sd-downloads.txt b/proposals/141-jit-sd-downloads.txt
index bba6493..1216ded 100644
--- a/proposals/141-jit-sd-downloads.txt
+++ b/proposals/141-jit-sd-downloads.txt
@@ -1,3 +1,4 @@
+```
Filename: 141-jit-sd-downloads.txt
Title: Download server descriptors on demand
Author: Peter Palfrader
@@ -321,3 +322,4 @@ Status: Obsolete
B needs to contact C so it can ask about the descriptor before passing it
back to the client.
+```
diff --git a/proposals/142-combine-intro-and-rend-points.txt b/proposals/142-combine-intro-and-rend-points.txt
index 3abd5c8..6ad34eb 100644
--- a/proposals/142-combine-intro-and-rend-points.txt
+++ b/proposals/142-combine-intro-and-rend-points.txt
@@ -1,3 +1,4 @@
+```
Filename: 142-combine-intro-and-rend-points.txt
Title: Combine Introduction and Rendezvous Points
Author: Karsten Loesing, Christian Wilms
@@ -275,3 +276,4 @@ References:
[5] Lasse Øverlier and Paul Syverson, Locating Hidden Servers. In the
Proceedings of the 2006 IEEE Symposium on Security and Privacy, May 2006.
+```
diff --git a/proposals/143-distributed-storage-improvements.txt b/proposals/143-distributed-storage-improvements.txt
index ce3f781..c89c309 100644
--- a/proposals/143-distributed-storage-improvements.txt
+++ b/proposals/143-distributed-storage-improvements.txt
@@ -1,3 +1,4 @@
+```
Filename: 143-distributed-storage-improvements.txt
Title: Improvements of Distributed Storage for Tor Hidden Service Descriptors
Author: Karsten Loesing
@@ -191,3 +192,4 @@ Compatibility:
All proposed improvements are compatible to the currently implemented
design as described in proposal 114.
+```
diff --git a/proposals/144-enforce-distinct-providers.txt b/proposals/144-enforce-distinct-providers.txt
index 1a682f3..da3845e 100644
--- a/proposals/144-enforce-distinct-providers.txt
+++ b/proposals/144-enforce-distinct-providers.txt
@@ -1,3 +1,4 @@
+```
Filename: 144-enforce-distinct-providers.txt
Title: Increase the diversity of circuits by detecting nodes belonging the
same provider
@@ -163,3 +164,4 @@ In the Proceedings of the Seventh Workshop on Privacy Enhancing Technologies
(PET 2007), Ottawa, Canada, June 2007.
http://freehaven.net/anonbib/#murdoch-pet2007
[5] http://bugs.noreply.org/flyspray/index.php?do=details&id=690
+```
diff --git a/proposals/145-newguard-flag.txt b/proposals/145-newguard-flag.txt
index 98c6508..7646727 100644
--- a/proposals/145-newguard-flag.txt
+++ b/proposals/145-newguard-flag.txt
@@ -1,3 +1,4 @@
+```
Filename: 145-newguard-flag.txt
Title: Separate "suitable as a guard" from "suitable as a new guard"
Author: Nick Mathewson
@@ -38,3 +39,4 @@ Alternatives
We might instead have authorities list weights with which nodes
should be picked as guards.
+```
diff --git a/proposals/146-long-term-stability.txt b/proposals/146-long-term-stability.txt
index 650be33..110231f 100644
--- a/proposals/146-long-term-stability.txt
+++ b/proposals/146-long-term-stability.txt
@@ -1,3 +1,4 @@
+```
Filename: 146-long-term-stability.txt
Title: Add new flag to reflect long-term stability
Author: Nick Mathewson
@@ -91,3 +92,4 @@ Issues and future possibilities:
Longterm is a really awkward name.
+```
diff --git a/proposals/147-prevoting-opinions.txt b/proposals/147-prevoting-opinions.txt
index 22f5c0f..42787a5 100644
--- a/proposals/147-prevoting-opinions.txt
+++ b/proposals/147-prevoting-opinions.txt
@@ -1,3 +1,4 @@
+```
Filename: 147-prevoting-opinions.txt
Title: Eliminate the need for v2 directories in generating v3 directories
Author: Nick Mathewson
@@ -118,3 +119,4 @@ Reasons for rejection:
-c | sort | grep " [1-4] " | wc -l`, result is 63, divide by 7*24
published consensuses, obtain 0.375 as end result.)
+```
diff --git a/proposals/148-uniform-client-end-reason.txt b/proposals/148-uniform-client-end-reason.txt
index 1db3b3e..0ee8145 100644
--- a/proposals/148-uniform-client-end-reason.txt
+++ b/proposals/148-uniform-client-end-reason.txt
@@ -1,3 +1,4 @@
+```
Filename: 148-uniform-client-end-reason.txt
Title: Stream end reasons from the client side should be uniform
Author: Roger Dingledine
@@ -55,3 +56,4 @@ Design:
like most of the Windows clients currently do and like the non-Windows
clients already do sometimes.
+```
diff --git a/proposals/149-using-netinfo-data.txt b/proposals/149-using-netinfo-data.txt
index 0ad663c..d8d052c 100644
--- a/proposals/149-using-netinfo-data.txt
+++ b/proposals/149-using-netinfo-data.txt
@@ -1,3 +1,4 @@
+```
Filename: 149-using-netinfo-data.txt
Title: Using data from NETINFO cells
Author: Nick Mathewson
@@ -43,3 +44,4 @@ Avoiding MITM attacks
connections without first trying to build a canonical one.
+```
diff --git a/proposals/150-exclude-exit-nodes.txt b/proposals/150-exclude-exit-nodes.txt
index b497ae6..460058c 100644
--- a/proposals/150-exclude-exit-nodes.txt
+++ b/proposals/150-exclude-exit-nodes.txt
@@ -1,3 +1,4 @@
+```
Filename: 150-exclude-exit-nodes.txt
Title: Exclude Exit Nodes from a circuit
Author: Mfr
@@ -45,3 +46,4 @@ Risks:
about broken exits because of this option. This issue can probably
be addressed sufficiently with documentation.
+```
diff --git a/proposals/151-path-selection-improvements.txt b/proposals/151-path-selection-improvements.txt
index e92b574..5eacfa7 100644
--- a/proposals/151-path-selection-improvements.txt
+++ b/proposals/151-path-selection-improvements.txt
@@ -1,3 +1,4 @@
+```
Filename: 151-path-selection-improvements.txt
Title: Improving Tor Path Selection
Author: Fallon Chen, Mike Perry
@@ -147,3 +148,4 @@ Issues
timeout can be achieved without cutting off a great number of the
total paths. This will eliminate a great deal of the performance
variation of Tor usage.
+```
diff --git a/proposals/152-single-hop-circuits.txt b/proposals/152-single-hop-circuits.txt
index d0b28b1..1e271af 100644
--- a/proposals/152-single-hop-circuits.txt
+++ b/proposals/152-single-hop-circuits.txt
@@ -1,3 +1,4 @@
+```
Filename: 152-single-hop-circuits.txt
Title: Optionally allow exit from single-hop circuits
Author: Geoff Goodell
@@ -60,3 +61,4 @@ Security Considerations
exit-from-single-hop-circuits" when choosing random paths through
the Tor network.
+```
diff --git a/proposals/153-automatic-software-update-protocol.txt b/proposals/153-automatic-software-update-protocol.txt
index c2979bb..7cf0c0a 100644
--- a/proposals/153-automatic-software-update-protocol.txt
+++ b/proposals/153-automatic-software-update-protocol.txt
@@ -1,3 +1,4 @@
+```
Filename: 153-automatic-software-update-protocol.txt
Title: Automatic software update protocol
Author: Jacob Appelbaum
@@ -173,3 +174,4 @@ question.
x.x Other Things
Other things should be added to this proposal. What are they?
+```
diff --git a/proposals/154-automatic-updates.txt b/proposals/154-automatic-updates.txt
index 4c2c6d3..e893344 100644
--- a/proposals/154-automatic-updates.txt
+++ b/proposals/154-automatic-updates.txt
@@ -1,3 +1,4 @@
+```
Filename: 154-automatic-updates.txt
Title: Automatic Software Update Protocol
Author: Matt Edman
@@ -375,3 +376,4 @@ References
[3] Tor version specification,
https://tor-svn.freehaven.net/svn/tor/trunk/doc/spec/version-spec.txt
+```
diff --git a/proposals/155-four-hidden-service-improvements.txt b/proposals/155-four-hidden-service-improvements.txt
index 423c9e8..3406481 100644
--- a/proposals/155-four-hidden-service-improvements.txt
+++ b/proposals/155-four-hidden-service-improvements.txt
@@ -1,3 +1,4 @@
+```
Filename: 155-four-hidden-service-improvements.txt
Title: Four Improvements of Hidden Service Performance
Author: Karsten Loesing, Christian Wilms
@@ -118,3 +119,4 @@ References:
[3] http://freehaven.net/~karsten/hidserv/design-2008-08-15.pdf
+```
diff --git a/proposals/156-tracking-blocked-ports.txt b/proposals/156-tracking-blocked-ports.txt
index acc0625..578621f 100644
--- a/proposals/156-tracking-blocked-ports.txt
+++ b/proposals/156-tracking-blocked-ports.txt
@@ -1,3 +1,4 @@
+```
Filename: 156-tracking-blocked-ports.txt
Title: Tracking blocked ports on the client side
Author: Robert Hogan
@@ -527,3 +528,4 @@ Index: src/or/circuitbuild.c
/** If <b>question</b> is the string "entry-guards", then dump
+```
diff --git a/proposals/157-specific-cert-download.txt b/proposals/157-specific-cert-download.txt
index e0ef0e8..8a69611 100644
--- a/proposals/157-specific-cert-download.txt
+++ b/proposals/157-specific-cert-download.txt
@@ -1,3 +1,4 @@
+```
Filename: 157-specific-cert-download.txt
Title: Make certificate downloads specific
Author: Nick Mathewson
@@ -100,3 +101,4 @@ Why cross-certify too?
References:
This is related to part 2 of bug 854.
+```
diff --git a/proposals/158-microdescriptors.txt b/proposals/158-microdescriptors.txt
index 442d705..d267c0b 100644
--- a/proposals/158-microdescriptors.txt
+++ b/proposals/158-microdescriptors.txt
@@ -1,3 +1,4 @@
+```
Filename: 158-microdescriptors.txt
Title: Clients download consensus + microdescriptors
Author: Roger Dingledine
@@ -197,3 +198,4 @@ Implemented-In: 0.2.3.1-alpha
Phase three, clients should start fetching and caching them instead
of normal descriptors.
+```
diff --git a/proposals/159-exit-scanning.txt b/proposals/159-exit-scanning.txt
index d2a7f3b..0f4d329 100644
--- a/proposals/159-exit-scanning.txt
+++ b/proposals/159-exit-scanning.txt
@@ -1,3 +1,4 @@
+```
Filename: 159-exit-scanning.txt
Title: Exit Scanning
Author: Mike Perry
@@ -140,3 +141,4 @@ Having a separate file that is under the exclusive control of the
scanner allows us to heavily isolate the scanner from the Tor
authority, potentially even running them on separate machines.
+```
diff --git a/proposals/160-bandwidth-offset.txt b/proposals/160-bandwidth-offset.txt
index 8ad4d18..33abd45 100644
--- a/proposals/160-bandwidth-offset.txt
+++ b/proposals/160-bandwidth-offset.txt
@@ -1,3 +1,4 @@
+```
Filename: 160-bandwidth-offset.txt
Title: Authorities vote for bandwidth offsets in consensus
Author: Roger Dingledine
@@ -103,3 +104,4 @@ Target: 0.2.1.x
+```
diff --git a/proposals/161-computing-bandwidth-adjustments.txt b/proposals/161-computing-bandwidth-adjustments.txt
index 6968724..38a1f9e 100644
--- a/proposals/161-computing-bandwidth-adjustments.txt
+++ b/proposals/161-computing-bandwidth-adjustments.txt
@@ -1,3 +1,4 @@
+```
Title: Computing Bandwidth Adjustments
Filename: 161-computing-bandwidth-adjustments.txt
Author: Mike Perry
@@ -172,3 +173,4 @@ Status: Closed
This file can be either copied or rsynced into a directory readable
by the directory authority.
+```
diff --git a/proposals/162-consensus-flavors.txt b/proposals/162-consensus-flavors.txt
index 2a227a0..85e6421 100644
--- a/proposals/162-consensus-flavors.txt
+++ b/proposals/162-consensus-flavors.txt
@@ -1,3 +1,4 @@
+```
Filename: 162-consensus-flavors.txt
Title: Publish the consensus in multiple flavors
Author: Nick Mathewson
@@ -188,3 +189,4 @@ Acknowledgements:
Aspects of this design and its applications to hash migration were
heavily influenced by IRC conversations with Marian.
+```
diff --git a/proposals/163-detecting-clients.txt b/proposals/163-detecting-clients.txt
index f2a17a5..5f77703 100644
--- a/proposals/163-detecting-clients.txt
+++ b/proposals/163-detecting-clients.txt
@@ -1,3 +1,4 @@
+```
Filename: 163-detecting-clients.txt
Title: Detecting whether a connection comes from a client
Author: Nick Mathewson
@@ -116,3 +117,4 @@ Open questions:
[Suggested answer: for now, just try making circuits through
the node. Extend this to extending circuits as needed.]
+```
diff --git a/proposals/164-reporting-server-status.txt b/proposals/164-reporting-server-status.txt
index 24fcc8f..418b3f8 100644
--- a/proposals/164-reporting-server-status.txt
+++ b/proposals/164-reporting-server-status.txt
@@ -1,3 +1,4 @@
+```
Filename: 164-reporting-server-status.txt
Title: Reporting the status of server votes
Author: Nick Mathewson
@@ -90,3 +91,4 @@ Risks:
+```
diff --git a/proposals/165-simple-robust-voting.txt b/proposals/165-simple-robust-voting.txt
index 28ea6d9..c759ee8 100644
--- a/proposals/165-simple-robust-voting.txt
+++ b/proposals/165-simple-robust-voting.txt
@@ -1,3 +1,4 @@
+```
Filename: 165-simple-robust-voting.txt
Title: Easy migration for voting authority sets
Author: Nick Mathewson
@@ -134,3 +135,4 @@ Acknowledgments:
The design came out of an IRC conversation with Peter Palfrader. He
had the basic idea first.
+```
diff --git a/proposals/166-statistics-extra-info-docs.txt b/proposals/166-statistics-extra-info-docs.txt
index 8b0c6a1..0075ade 100644
--- a/proposals/166-statistics-extra-info-docs.txt
+++ b/proposals/166-statistics-extra-info-docs.txt
@@ -1,3 +1,4 @@
+```
Filename: 166-statistics-extra-info-docs.txt
Title: Including Network Statistics in Extra-Info Documents
Author: Karsten Loesing
@@ -389,3 +390,4 @@ Implementation notes:
gathering statistics. However, in the near future, statistics shall
be enabled gathered by all relays by default, where requiring a
./configure option would be a barrier for many relay operators.
+```
diff --git a/proposals/167-params-in-consensus.txt b/proposals/167-params-in-consensus.txt
index d23bc9c..f616c35 100644
--- a/proposals/167-params-in-consensus.txt
+++ b/proposals/167-params-in-consensus.txt
@@ -1,3 +1,4 @@
+```
Filename: 167-params-in-consensus.txt
Title: Vote on network parameters in consensus
Author: Roger Dingledine
@@ -45,3 +46,4 @@ Implemented-In: 0.2.2
I don't have any non-integer values in mind yet. So I say we cross
that bridge when we get to it.
+```
diff --git a/proposals/168-reduce-circwindow.txt b/proposals/168-reduce-circwindow.txt
index 9932ff6..48fc146 100644
--- a/proposals/168-reduce-circwindow.txt
+++ b/proposals/168-reduce-circwindow.txt
@@ -1,3 +1,4 @@
+```
Filename: 168-reduce-circwindow.txt
Title: Reduce default circuit window
Author: Roger Dingledine
@@ -132,3 +133,4 @@ Status: Rejected
isn't very complex. Let's shoot for that, and fall back to (b) if the
patch turns out to be so big that we reconsider.
+```
diff --git a/proposals/169-eliminating-renegotiation.txt b/proposals/169-eliminating-renegotiation.txt
index fe4cd58..36f8acd 100644
--- a/proposals/169-eliminating-renegotiation.txt
+++ b/proposals/169-eliminating-renegotiation.txt
@@ -1,3 +1,4 @@
+```
Filename: 169-eliminating-renegotiation.txt
Title: Eliminate TLS renegotiation for the Tor connection handshake
Author: Nick Mathewson
@@ -404,3 +405,4 @@ Superseded-By: 176
now, I think they should just get it. Eventually we can
deprecate the V2 handshake as we did with the V1 handshake.
+```
diff --git a/proposals/170-user-path-config.txt b/proposals/170-user-path-config.txt
index 42163f1..da85700 100644
--- a/proposals/170-user-path-config.txt
+++ b/proposals/170-user-path-config.txt
@@ -1,3 +1,4 @@
+```
Title: Configuration options regarding circuit building
Filename: 170-user-path-config.txt
Author: Sebastian Hahn
@@ -93,3 +94,4 @@ Compatibility:
The old Strict*Nodes options are deprecated, and the StrictNodes
option is new. Tor users may need to update their configuration file.
+```
diff --git a/proposals/171-separate-streams.txt b/proposals/171-separate-streams.txt
index 01668a4..f482b09 100644
--- a/proposals/171-separate-streams.txt
+++ b/proposals/171-separate-streams.txt
@@ -1,3 +1,4 @@
+```
Filename: 171-separate-streams.txt
Title: Separate streams across circuits by connection metadata
Author: Robert Hogan, Jacob Appelbaum, Damon McCoy, Nick Mathewson
@@ -356,3 +357,4 @@ Lingering questions:
I suspect there are issues remaining with DNS and TransPort users, and
that my "just use AutomapHostsOnResolve" suggestion may be
insufficient.
+```
diff --git a/proposals/172-circ-getinfo-option.txt b/proposals/172-circ-getinfo-option.txt
index 38b0da7..9c9cea7 100644
--- a/proposals/172-circ-getinfo-option.txt
+++ b/proposals/172-circ-getinfo-option.txt
@@ -1,3 +1,4 @@
+```
Filename: 172-circ-getinfo-option.txt
Title: GETINFO controller option for circuit information
Author: Damian Johnson
@@ -136,3 +137,4 @@ Specification:
provides the same fields that would be given by calling "GETINFO rcirc/id/"
with the CircID.
+```
diff --git a/proposals/173-getinfo-option-expansion.txt b/proposals/173-getinfo-option-expansion.txt
index 035471d..9c6cc12 100644
--- a/proposals/173-getinfo-option-expansion.txt
+++ b/proposals/173-getinfo-option-expansion.txt
@@ -1,3 +1,4 @@
+```
Filename: 173-getinfo-option-expansion.txt
Title: GETINFO Option Expansion
Author: Damian Johnson
@@ -103,3 +104,4 @@ Specification:
650-EXITS_SEEN TimeStarted="2008-12-25 23:50:43"
PortSummary=80=16,443=8
+```
diff --git a/proposals/174-optimistic-data-server.txt b/proposals/174-optimistic-data-server.txt
index 193565b..ef34526 100644
--- a/proposals/174-optimistic-data-server.txt
+++ b/proposals/174-optimistic-data-server.txt
@@ -1,3 +1,4 @@
+```
Filename: 174-optimistic-data-server.txt
Title: Optimistic Data for Tor: Server Side
Author: Ian Goldberg
@@ -241,3 +242,4 @@ Performance and scalability notes:
There may be more RAM used at Exit nodes, as mentioned above, but it is
transient.
+```
diff --git a/proposals/175-automatic-node-promotion.txt b/proposals/175-automatic-node-promotion.txt
index d6d86a6..2713a2a 100644
--- a/proposals/175-automatic-node-promotion.txt
+++ b/proposals/175-automatic-node-promotion.txt
@@ -1,3 +1,4 @@
+```
Filename: 175-automatic-node-promotion.txt
Title: Automatically promoting Tor clients to nodes
Author: Steven Murdoch
@@ -238,3 +239,4 @@ Status: Rejected
http://www.itl.nist.gov/div898/handbook/pmc/section3/pmc331.htm (e-Handbook of Statistical Methods)
% vim: spell ai et:
+```
diff --git a/proposals/176-revising-handshake.txt b/proposals/176-revising-handshake.txt
index 20a3ef2..f53190a 100644
--- a/proposals/176-revising-handshake.txt
+++ b/proposals/176-revising-handshake.txt
@@ -1,3 +1,4 @@
+```
Filename: 176-revising-handshake.txt
Title: Proposed version-3 link handshake for Tor
Author: Nick Mathewson
@@ -622,3 +623,4 @@ Supersedes: 169
now, I think they should just stick with V1. Eventually we can
deprecate the V2 handshake as we did with the V1 handshake.
When that happens, servers can be V3-only.
+```
diff --git a/proposals/177-flag-abstention.txt b/proposals/177-flag-abstention.txt
index cbc0819..02a4657 100644
--- a/proposals/177-flag-abstention.txt
+++ b/proposals/177-flag-abstention.txt
@@ -1,3 +1,4 @@
+```
Filename: 177-flag-abstention.txt
Title: Abstaining from votes on individual flags
Author: Nick Mathewson
@@ -103,3 +104,4 @@ Examples:
it is not run by wombats. (As now, "no" votes win ties.)
+```
diff --git a/proposals/178-param-voting.txt b/proposals/178-param-voting.txt
index 58d2a62..fc7fe25 100644
--- a/proposals/178-param-voting.txt
+++ b/proposals/178-param-voting.txt
@@ -1,3 +1,4 @@
+```
Filename: 178-param-voting.txt
Title: Require majority of authorities to vote for consensus parameters
Author: Sebastian Hahn
@@ -99,3 +100,4 @@ Implementation:
An example implementation of this feature can be found in
https://gitweb.torproject.org/sebastian/tor.git, branch safer_params.
+```
diff --git a/proposals/179-TLS-cert-and-parameter-normalization.txt b/proposals/179-TLS-cert-and-parameter-normalization.txt
index 4272d4f..cf455a8 100644
--- a/proposals/179-TLS-cert-and-parameter-normalization.txt
+++ b/proposals/179-TLS-cert-and-parameter-normalization.txt
@@ -1,3 +1,4 @@
+```
Filename: 179-TLS-cert-and-parameter-normalization.txt
Title: TLS certificate and parameter normalization
Author: Jacob Appelbaum, Gladys Shufflebottom
@@ -384,3 +385,4 @@ present in the Tor TLS setup process?
[4] httpd-2.2.17/modules/ss/ssl_engine_dh.c
[5] http://tools.ietf.org/html/rfc4419
[6] http://archives.seul.org/or/dev/Jan-2011/msg00037.html
+```
diff --git a/proposals/180-pluggable-transport.txt b/proposals/180-pluggable-transport.txt
index c23e5fa..8626375 100644
--- a/proposals/180-pluggable-transport.txt
+++ b/proposals/180-pluggable-transport.txt
@@ -1,3 +1,4 @@
+```
Filename: 180-pluggable-transport.txt
Title: Pluggable transports for circumvention
Author: Jacob Appelbaum, Nick Mathewson
@@ -548,3 +549,4 @@ Appendix: recommendations for transports
protocols -- and in many cases, most possible variants of a given
protocol won't actually exist in the wild.
+```
diff --git a/proposals/181-optimistic-data-client.txt b/proposals/181-optimistic-data-client.txt
index 6d0a929..e1544df 100644
--- a/proposals/181-optimistic-data-client.txt
+++ b/proposals/181-optimistic-data-client.txt
@@ -1,3 +1,4 @@
+```
Filename: 181-optimistic-data-client.txt
Title: Optimistic Data for Tor: Client Side
Author: Ian Goldberg
@@ -126,3 +127,4 @@ Performance and scalability notes:
OPs may queue a little more data, if the SOCKS client pushes it faster
than the OP can write it out. But that's also true today after the
SOCKS CONNECT returns success, right?
+```
diff --git a/proposals/182-creditbucket.txt b/proposals/182-creditbucket.txt
index fc3cb17..b462a61 100644
--- a/proposals/182-creditbucket.txt
+++ b/proposals/182-creditbucket.txt
@@ -1,3 +1,4 @@
+```
Filename: 182-creditbucket.txt
Title: Credit Bucket
Author: Florian Tschorsch and Björn Scheuermann
@@ -181,3 +182,4 @@ References:
[1] Karsten Loesing. Analysis of Circuit Queues in Tor. August 25, 2009.
[2] https://trac.torproject.org/projects/tor/wiki/sponsors/SponsorD/June2011
+```
diff --git a/proposals/183-refillintervals.txt b/proposals/183-refillintervals.txt
index 81ff5b0..b2425fd 100644
--- a/proposals/183-refillintervals.txt
+++ b/proposals/183-refillintervals.txt
@@ -1,3 +1,4 @@
+```
Filename: 183-refillintervals.txt
Title: Refill Intervals
Author: Florian Tschorsch and Björn Scheuermann
@@ -88,3 +89,4 @@ References:
[1] Karsten Loesing. Analysis of Circuit Queues in Tor. August 25, 2009.
[2] https://trac.torproject.org/projects/tor/wiki/sponsors/SponsorD/June2011
+```
diff --git a/proposals/184-v3-link-protocol.txt b/proposals/184-v3-link-protocol.txt
index 820e779..5de9294 100644
--- a/proposals/184-v3-link-protocol.txt
+++ b/proposals/184-v3-link-protocol.txt
@@ -1,3 +1,4 @@
+```
Filename: 184-v3-link-protocol.txt
Title: Miscellaneous changes for a v3 Tor link protocol
Author: Nick Mathewson
@@ -96,3 +97,4 @@ Notes on future-proofing:
tweaking the link protocol to have a variable-length cell type
encoding.
+```
diff --git a/proposals/185-dir-without-dirport.txt b/proposals/185-dir-without-dirport.txt
index 65cfd43..21c5b8c 100644
--- a/proposals/185-dir-without-dirport.txt
+++ b/proposals/185-dir-without-dirport.txt
@@ -1,3 +1,4 @@
+```
Filename: 185-dir-without-dirport.txt
Title: Directory caches without DirPort
Author: Nick Mathewson
@@ -47,3 +48,4 @@ Consensus:
as a directory cache.
This does not require a new version of the consensus algorithm.
+```
diff --git a/proposals/186-multiple-orports.txt b/proposals/186-multiple-orports.txt
index f66ad83..f29d1c6 100644
--- a/proposals/186-multiple-orports.txt
+++ b/proposals/186-multiple-orports.txt
@@ -1,3 +1,4 @@
+```
Filename: 186-multiple-orports.txt
Title: Multiple addresses for one OR or bridge
Author: Nick Mathewson
@@ -283,3 +284,4 @@ TODO:
* Come up with a better alternative to running6 for the longterm?
+```
diff --git a/proposals/187-allow-client-auth.txt b/proposals/187-allow-client-auth.txt
index 67c878e..b461b92 100644
--- a/proposals/187-allow-client-auth.txt
+++ b/proposals/187-allow-client-auth.txt
@@ -1,3 +1,4 @@
+```
Filename: 187-allow-client-auth.txt
Title: Reserve a cell type to allow client authorization
Author: Nick Mathewson
@@ -129,3 +130,4 @@ Counterargument: it's too late!
break their connections only to a couple of alpha versions which
one hopes by then will be long-deprecated already.
+```
diff --git a/proposals/188-bridge-guards.txt b/proposals/188-bridge-guards.txt
index 2a74416..51f7139 100644
--- a/proposals/188-bridge-guards.txt
+++ b/proposals/188-bridge-guards.txt
@@ -1,3 +1,4 @@
+```
Filename: 188-bridge-guards.txt
Title: Bridge Guards and other anti-enumeration defenses
Author: Nick Mathewson, Isis Lovecruft
@@ -520,3 +521,4 @@ Status: Reserve
What fraction of our traffic is bridge traffic? Will this alter
our circuit selection weights?
+```
diff --git a/proposals/189-authorize-cell.txt b/proposals/189-authorize-cell.txt
index 4836c5f..14d9a77 100644
--- a/proposals/189-authorize-cell.txt
+++ b/proposals/189-authorize-cell.txt
@@ -1,3 +1,4 @@
+```
Filename: 189-authorize-cell.txt
Title: AUTHORIZE and AUTHORIZED cells
Author: George Kadianakis
@@ -138,3 +139,4 @@ Status: Obsolete
This proposal does not try to specify how a bridge can avoid
detection by an adversary.
+```
diff --git a/proposals/190-shared-secret-bridge-authorization.txt b/proposals/190-shared-secret-bridge-authorization.txt
index 31c692b..8c9d45b 100644
--- a/proposals/190-shared-secret-bridge-authorization.txt
+++ b/proposals/190-shared-secret-bridge-authorization.txt
@@ -1,3 +1,4 @@
+```
Filename: 190-shared-secret-bridge-authorization.txt
Title: Bridge Client Authorization Based on a Shared Secret
Author: George Kadianakis
@@ -101,3 +102,4 @@ Notes: This is obsoleted by pluggable transports.
Thanks to Nick Mathewson and Robert Ransom for the help and
suggestions while writing this proposal.
+```
diff --git a/proposals/191-mitm-bridge-detection-resistance.txt b/proposals/191-mitm-bridge-detection-resistance.txt
index a4689bb..4faf60d 100644
--- a/proposals/191-mitm-bridge-detection-resistance.txt
+++ b/proposals/191-mitm-bridge-detection-resistance.txt
@@ -1,3 +1,4 @@
+```
Filename: 191-mitm-bridge-detection-resistance.txt
Title: Bridge Detection Resistance against MITM-capable Adversaries
Author: George Kadianakis
@@ -161,3 +162,4 @@ Status: Obsolete
Thanks to Robert Ransom for his great help and suggestions on
devising this scheme and writing this proposal!
+```
diff --git a/proposals/192-store-bridge-information.txt b/proposals/192-store-bridge-information.txt
index fe7d016..4e2dee0 100644
--- a/proposals/192-store-bridge-information.txt
+++ b/proposals/192-store-bridge-information.txt
@@ -1,3 +1,4 @@
+```
Filename: 192-store-bridge-information.txt
Title: Automatically retrieve and store information about bridges
Author: Sebastian Hahn
@@ -135,3 +136,4 @@ the bridge authority side doesn't need any changes. The new
configuration options governing the behaviour of Tor would be
incompatible with previous versions, so the torrc needs to be adapted.
The state file changes should not affect older versions.
+```
diff --git a/proposals/193-safe-cookie-authentication.txt b/proposals/193-safe-cookie-authentication.txt
index a3717fe..c97fcbb 100644
--- a/proposals/193-safe-cookie-authentication.txt
+++ b/proposals/193-safe-cookie-authentication.txt
@@ -1,3 +1,4 @@
+```
Filename: 193-safe-cookie-authentication.txt
Title: Safe cookie authentication for Tor controllers
Author: Robert Ransom
@@ -142,3 +143,4 @@ Rationale:
to keep controllers from using the server as an oracle for its own
challenges (it could be replaced with a hash function).
+```
diff --git a/proposals/194-mnemonic-urls.txt b/proposals/194-mnemonic-urls.txt
index aeae092..0dfbfc0 100644
--- a/proposals/194-mnemonic-urls.txt
+++ b/proposals/194-mnemonic-urls.txt
@@ -1,3 +1,4 @@
+```
Filename: 194-mnemonic-urls.txt
Title: Mnemonic .onion URLs
Author: Sai, Alex Fink
@@ -198,3 +199,4 @@ https://github.com/hellais/Onion-url/blob/master/dev/mnemonic.py
[17] http://www.reddit.com/r/technology/comments/ecllk
[18] http://wordnet.princeton.edu/wordnet/man2.1/wnstats.7WN.html
+```
diff --git a/proposals/195-TLS-normalization-for-024.txt b/proposals/195-TLS-normalization-for-024.txt
index bfc8d9a..8b3d8a9 100644
--- a/proposals/195-TLS-normalization-for-024.txt
+++ b/proposals/195-TLS-normalization-for-024.txt
@@ -1,3 +1,4 @@
+```
Filename: 195-TLS-normalization-for-024.txt
Title: TLS certificate normalization for Tor 0.2.4.x
Author: Jacob Appelbaum, Gladys Shufflebottom, Nick Mathewson, Tim Wilde
@@ -168,3 +169,4 @@ Target: 0.2.4.x
plausible way would probably be an implementation bug in OpenSSL or
something.
+```
diff --git a/proposals/196-transport-control-ports.txt b/proposals/196-transport-control-ports.txt
index f4d8a0e..972ddb3 100644
--- a/proposals/196-transport-control-ports.txt
+++ b/proposals/196-transport-control-ports.txt
@@ -1,3 +1,4 @@
+```
Filename: 196-transport-control-ports.txt
Title: Extended ORPort and TransportControlPort
Author: George Kadianakis, Nick Mathewson
@@ -238,3 +239,4 @@ Implemented-In: 0.2.5.2-alpha
control information with the Tor client. The current proposal doesn't
yet support this, but we should not add functionality that will
prevent it from being possible.
+```
diff --git a/proposals/197-postmessage-ipc.txt b/proposals/197-postmessage-ipc.txt
index da246b3..e9ae6e6 100644
--- a/proposals/197-postmessage-ipc.txt
+++ b/proposals/197-postmessage-ipc.txt
@@ -1,3 +1,4 @@
+```
Filename: 197-postmessage-ipc.txt
Title: Message-based Inter-Controller IPC Channel
Author: Mike Perry
@@ -97,3 +98,4 @@ Implementation plan
needed. However, Torbutton does not have immediate need for this
protocol.
+```
diff --git a/proposals/198-restore-clienthello-semantics.txt b/proposals/198-restore-clienthello-semantics.txt
index 2a3a560..9ec5aa3 100644
--- a/proposals/198-restore-clienthello-semantics.txt
+++ b/proposals/198-restore-clienthello-semantics.txt
@@ -1,3 +1,4 @@
+```
Filename: 198-restore-clienthello-semantics.txt
Title: Restore semantics of TLS ClientHello
Author: Nick Mathewson
@@ -188,3 +189,4 @@ Open questions:
implications of leaking cell types and circuit IDs to a future
compromise.
+```
diff --git a/proposals/199-bridgefinder-integration.txt b/proposals/199-bridgefinder-integration.txt
index fbabf91..4c806e7 100644
--- a/proposals/199-bridgefinder-integration.txt
+++ b/proposals/199-bridgefinder-integration.txt
@@ -1,3 +1,4 @@
+```
Filename: 199-bridgefinder-integration.txt
Title: Integration of BridgeFinder and BridgeFinderHelper
Author: Mike Perry
@@ -412,3 +413,4 @@ Security Concerns: BridgeFinder and BridgeFinderHelper
encountered.
+```
diff --git a/proposals/200-new-create-and-extend-cells.txt b/proposals/200-new-create-and-extend-cells.txt
index 1a556dc..52934c9 100644
--- a/proposals/200-new-create-and-extend-cells.txt
+++ b/proposals/200-new-create-and-extend-cells.txt
@@ -1,3 +1,4 @@
+```
Filename: 200-new-create-and-extend-cells.txt
Title: Adding new, extensible CREATE, EXTEND, and related cells
Author: Robert Ransom
@@ -153,3 +154,4 @@ Bugs:
type that would require it.
+```
diff --git a/proposals/201-bridge-v3-reqs-stats.txt b/proposals/201-bridge-v3-reqs-stats.txt
index e267cba..81503d0 100644
--- a/proposals/201-bridge-v3-reqs-stats.txt
+++ b/proposals/201-bridge-v3-reqs-stats.txt
@@ -1,3 +1,4 @@
+```
Filename: 201-bridge-v3-reqs-stats.txt
Title: Make bridges report statistics on daily v3 network status requests
Author: Karsten Loesing
@@ -36,3 +37,4 @@ Specification:
[0] https://metrics.torproject.org/papers/countingusers-2010-11-30.pdf
+```
diff --git a/proposals/202-improved-relay-crypto.txt b/proposals/202-improved-relay-crypto.txt
index e9a1fd1..4913f98 100644
--- a/proposals/202-improved-relay-crypto.txt
+++ b/proposals/202-improved-relay-crypto.txt
@@ -1,3 +1,4 @@
+```
Filename: 202-improved-relay-crypto.txt
Title: Two improved relay encryption protocols for Tor cells
Author: Nick Mathewson
@@ -817,3 +818,4 @@ R. References
[23R] The 23 Raccoons, "Analysis of the Relative Severity of Tagging
Attacks" http://archives.seul.org/or/dev/Mar-2012/msg00019.html
(You'll want to read the rest of the thread too.)
+```
diff --git a/proposals/203-https-frontend.txt b/proposals/203-https-frontend.txt
index 4bbb271..e9e83c1 100644
--- a/proposals/203-https-frontend.txt
+++ b/proposals/203-https-frontend.txt
@@ -1,3 +1,4 @@
+```
Filename: 203-https-frontend.txt
Title: Avoiding censorship by impersonating an HTTPS server
Author: Nick Mathewson
@@ -275,3 +276,4 @@ Related work:
(high collateral damage).
1. https://trac.torproject.org/projects/tor/wiki/doc/meek
+```
diff --git a/proposals/204-hidserv-subdomains.txt b/proposals/204-hidserv-subdomains.txt
index 056fbad..aee5727 100644
--- a/proposals/204-hidserv-subdomains.txt
+++ b/proposals/204-hidserv-subdomains.txt
@@ -1,3 +1,4 @@
+```
Filename: 204-hidserv-subdomains.txt
Title: Subdomain support for Hidden Service addresses
Author: Alessandro Preite Martinez
@@ -27,3 +28,4 @@ Status: Closed
simply as "aaaaaaaaaaaaaaaa.onion".
+```
diff --git a/proposals/205-local-dnscache.txt b/proposals/205-local-dnscache.txt
index d0a0107..b7c8aa0 100644
--- a/proposals/205-local-dnscache.txt
+++ b/proposals/205-local-dnscache.txt
@@ -1,3 +1,4 @@
+```
Filename: 205-local-dnscache.txt
Title: Remove global client-side DNS caching
Author: Nick Mathewson
@@ -157,3 +158,4 @@ Status: Closed
without most of the security issues, if we restrict it to
DNSSec-signed answers.
+```
diff --git a/proposals/206-directory-sources.txt b/proposals/206-directory-sources.txt
index d81b2f6..bdb6481 100644
--- a/proposals/206-directory-sources.txt
+++ b/proposals/206-directory-sources.txt
@@ -1,3 +1,4 @@
+```
Filename: 206-directory-sources.txt
Title: Preconfigured directory sources for bootstrapping
Author: Nick Mathewson
@@ -87,3 +88,4 @@ Some notes on security:
+```
diff --git a/proposals/207-directory-guards.txt b/proposals/207-directory-guards.txt
index 8d21d3e..51dcdbf 100644
--- a/proposals/207-directory-guards.txt
+++ b/proposals/207-directory-guards.txt
@@ -1,3 +1,4 @@
+```
Filename: 207-directory-guards.txt
Title: Directory guards
Author: Nick Mathewson
@@ -52,3 +53,4 @@ Open questions and notes:
+```
diff --git a/proposals/208-ipv6-exits-redux.txt b/proposals/208-ipv6-exits-redux.txt
index 32fb09c..fd0adfa 100644
--- a/proposals/208-ipv6-exits-redux.txt
+++ b/proposals/208-ipv6-exits-redux.txt
@@ -1,3 +1,4 @@
+```
Filename: 208-ipv6-exits-redux.txt
Title: IPv6 Exits Redux
Author: Nick Mathewson
@@ -125,3 +126,4 @@ Implemented-In: 0.2.4.7-alpha
This makes proposal 205 especially necessary here.
+```
diff --git a/proposals/209-path-bias-tuning.txt b/proposals/209-path-bias-tuning.txt
index 7d02422..fcdaf78 100644
--- a/proposals/209-path-bias-tuning.txt
+++ b/proposals/209-path-bias-tuning.txt
@@ -1,3 +1,4 @@
+```
Filename: 209-path-bias-tuning.txt
Title: Tuning the Parameters for the Path Bias Defense
Author: Mike Perry
@@ -286,3 +287,4 @@ Implementation Notes: Differences between proposal and current source
3. https://gitweb.torproject.org/torflow.git/tree/HEAD:/CircuitAnalysis/PathBias
4. https://github.com/meejah/txtorcon/blob/exit_scanner/apps/exit_scanner/failure-rate-scanner.py
5. See 2.4.1 of path-spec.txt for further details on circuit timeout calculations.
+```
diff --git a/proposals/210-faster-headless-consensus-bootstrap.txt b/proposals/210-faster-headless-consensus-bootstrap.txt
index 380a9ac..3bf8760 100644
--- a/proposals/210-faster-headless-consensus-bootstrap.txt
+++ b/proposals/210-faster-headless-consensus-bootstrap.txt
@@ -1,3 +1,4 @@
+```
Filename: 210-faster-headless-consensus-bootstrap.txt
Title: Faster Headless Consensus Bootstrapping
Author: Mike Perry, Tim Wilson-Brown, Peter Palfrader
@@ -236,3 +237,4 @@ Reliability Analysis
among a larger number of directory mirrors. In addition, if all the
authorities are blocked, current clients will inevitably fail, as they
do not have a list of directory mirrors.
+```
diff --git a/proposals/211-mapaddress-tor-status.txt b/proposals/211-mapaddress-tor-status.txt
index 28be3bb..5dbe445 100644
--- a/proposals/211-mapaddress-tor-status.txt
+++ b/proposals/211-mapaddress-tor-status.txt
@@ -1,3 +1,4 @@
+```
Filename: 211-mapaddress-tor-status.txt
Title: Internal Mapaddress for Tor Configuration Testing
Author: Mike Perry
@@ -143,3 +144,4 @@ Security Considerations
1. http://www.hpenterprisesecurity.com/vulncat/en/vulncat/dotnet/javascript_hijacking_vulnerable_framework.html
+```
diff --git a/proposals/212-using-old-consensus.txt b/proposals/212-using-old-consensus.txt
index 3fd9839..621466e 100644
--- a/proposals/212-using-old-consensus.txt
+++ b/proposals/212-using-old-consensus.txt
@@ -1,3 +1,4 @@
+```
Filename: 212-using-old-consensus.txt
Title: Increase Acceptable Consensus Age
Author: Mike Perry
@@ -107,3 +108,4 @@ Implementation Notes
still attempting to fetch new ones.
1. https://trac.torproject.org/projects/tor/ticket/7126
+```
diff --git a/proposals/213-remove-stream-sendmes.txt b/proposals/213-remove-stream-sendmes.txt
index f2b8b34..18b51f3 100644
--- a/proposals/213-remove-stream-sendmes.txt
+++ b/proposals/213-remove-stream-sendmes.txt
@@ -1,3 +1,4 @@
+```
Filename: 213-remove-stream-sendmes.txt
Title: Remove stream-level sendmes from the design
Author: Roger Dingledine
@@ -150,3 +151,4 @@ Status: Dead
since it lacks any stream-level pushback for streams that are blocking
on writes. Nicely done!
+```
diff --git a/proposals/214-longer-circids.txt b/proposals/214-longer-circids.txt
index b5bd88a..54675ac 100644
--- a/proposals/214-longer-circids.txt
+++ b/proposals/214-longer-circids.txt
@@ -1,3 +1,4 @@
+```
Filename: 214-longer-circids.txt
Title: Allow 4-byte circuit IDs in a new link protocol
Author: Nick Mathewson
@@ -92,3 +93,4 @@ Implemented-In: 0.2.4.11-alpha
implementation in branch "wide_circ_ids" in my public repository.
Be afraid! More testing is needed!
+```
diff --git a/proposals/215-update-min-consensus-ver.txt b/proposals/215-update-min-consensus-ver.txt
index 899a943..c6fba59 100644
--- a/proposals/215-update-min-consensus-ver.txt
+++ b/proposals/215-update-min-consensus-ver.txt
@@ -1,3 +1,4 @@
+```
Filename: 215-update-min-consensus-ver.txt
Title: Let the minimum consensus method change with time
Author: Nick Mathewson
@@ -93,3 +94,4 @@ Implemented-In: 0.2.6.1-alpha
at all." That's harder to program, though.
+```
diff --git a/proposals/216-ntor-handshake.txt b/proposals/216-ntor-handshake.txt
index f76e81c..a96dd83 100644
--- a/proposals/216-ntor-handshake.txt
+++ b/proposals/216-ntor-handshake.txt
@@ -1,3 +1,4 @@
+```
Filename: 216-ntor-handshake.txt
Title: Improved circuit-creation key exchange
Author: Nick Mathewson
@@ -211,3 +212,4 @@ Test vectors for HKDF-SHA256:
b4dc21d69363e2895321c06184879d94b18f0784
11be70b767c7fc40679a9440a0c95ea83a23efbf
+```
diff --git a/proposals/217-ext-orport-auth.txt b/proposals/217-ext-orport-auth.txt
index 3734924..6a61a65 100644
--- a/proposals/217-ext-orport-auth.txt
+++ b/proposals/217-ext-orport-auth.txt
@@ -1,3 +1,4 @@
+```
Filename: 217-ext-orport-auth.txt
Title: Tor Extended ORPort Authentication
Author: George Kadianakis
@@ -175,3 +176,4 @@ http://archives.seul.org/or/announce/Sep-2007/msg00000.html
[1]:
https://gitweb.torproject.org/torspec.git/blob/79f488c32c43562522e5592f2c19952dc7681a65:/control-spec.txt#l1069
+```
diff --git a/proposals/218-usage-controller-events.txt b/proposals/218-usage-controller-events.txt
index 76c64cd..f709550 100644
--- a/proposals/218-usage-controller-events.txt
+++ b/proposals/218-usage-controller-events.txt
@@ -1,3 +1,4 @@
+```
Filename: 218-usage-controller-events.txt
Title: Controller events to better understand connection/circuit usage
Author: Rob Jansen, Karsten Loesing
@@ -219,3 +220,4 @@ Implemented-In: 0.2.5.2-alpha
as small as possible. Still, we should make sure that memory
requirements won't grow significantly on busy relays.
+```
diff --git a/proposals/219-expanded-dns.txt b/proposals/219-expanded-dns.txt
index 7298b78..86b3f1a 100644
--- a/proposals/219-expanded-dns.txt
+++ b/proposals/219-expanded-dns.txt
@@ -1,3 +1,4 @@
+```
Filename: 219-expanded-dns.txt
Title: Support for full DNS and DNSSEC resolution in Tor
Authors: Ondrej Mikle
@@ -346,3 +347,4 @@ Status: Needs-Revision
References:
[1] https://www.ietf.org/mail-archive/web/dane/current/msg02823.html
+```
diff --git a/proposals/220-ecc-id-keys.txt b/proposals/220-ecc-id-keys.txt
index 21b6dac..a6e6b54 100644
--- a/proposals/220-ecc-id-keys.txt
+++ b/proposals/220-ecc-id-keys.txt
@@ -1,3 +1,4 @@
+```
Filename: 220-ecc-id-keys.txt
Title: Migrate server identity keys to Ed25519
Authors: Nick Mathewson
@@ -683,3 +684,4 @@ A.6. Related changes
keys. This will improve link security, and deliver better
fingerprinting resistence. See proposal 179 for an older discussion
of this issue.
+```
diff --git a/proposals/221-stop-using-create-fast.txt b/proposals/221-stop-using-create-fast.txt
index 7903a39..2fa2209 100644
--- a/proposals/221-stop-using-create-fast.txt
+++ b/proposals/221-stop-using-create-fast.txt
@@ -1,3 +1,4 @@
+```
Filename: 221-stop-using-create-fast.txt
Title: Stop using CREATE_FAST
Authors: Nick Mathewson
@@ -88,3 +89,4 @@ Status: Closed
reliable signal, since "FastFirstHopPK 0" is easy enough to type, and
the source code is easy enough to edit. Proposal 163 and its
successors have better ideas here anyway.
+```
diff --git a/proposals/222-remove-client-timestamps.txt b/proposals/222-remove-client-timestamps.txt
index b2a2ae9..3af19d1 100644
--- a/proposals/222-remove-client-timestamps.txt
+++ b/proposals/222-remove-client-timestamps.txt
@@ -1,3 +1,4 @@
+```
Filename: 222-remove-client-timestamps.txt
Title: Stop sending client timestamps
Authors: Nick Mathewson
@@ -248,3 +249,4 @@ Implementors might want to make this feature optional and
on-by-default, just in case some higher-level application protocol
really does depend on it.
==================================================================
+```
diff --git a/proposals/223-ace-handshake.txt b/proposals/223-ace-handshake.txt
index 5e333bb..70d34f4 100644
--- a/proposals/223-ace-handshake.txt
+++ b/proposals/223-ace-handshake.txt
@@ -1,3 +1,4 @@
+```
Filename: 223-ace-handshake.txt
Title: Ace: Improved circuit-creation key exchange
Author: Esfandiar Mohammadi, Aniket Kate, Michael Backes
@@ -110,3 +111,4 @@ See also:
http://www.infsec.cs.uni-saarland.de/~mohammadi/ace/ace.html
for implementations, academic paper, and benchmarking code.
+```
diff --git a/proposals/224-rend-spec-ng.txt b/proposals/224-rend-spec-ng.txt
index 1dfe87b..e1cba7f 100644
--- a/proposals/224-rend-spec-ng.txt
+++ b/proposals/224-rend-spec-ng.txt
@@ -1,3 +1,4 @@
+```
Filename: 224-rend-spec-ng.txt
Title: Next-Generation Hidden Services in Tor
Author: David Goulet, George Kadianakis, Nick Mathewson
@@ -2368,3 +2369,4 @@ Appendix E. Managing authorized client data [CLIENT-AUTH-MGMT]
[XXX what happens when people use both the control port interface and the
filesystem interface?]
+```
diff --git a/proposals/225-strawman-shared-rand.txt b/proposals/225-strawman-shared-rand.txt
index f124174..6d71327 100644
--- a/proposals/225-strawman-shared-rand.txt
+++ b/proposals/225-strawman-shared-rand.txt
@@ -1,3 +1,4 @@
+```
Filename: 225-strawman-shared-rand.txt
Title: Strawman proposal: commit-and-reveal shared rng
Author: Nick Mathewson
@@ -112,3 +113,4 @@ Superseded-by: 250
(TODO: should this be its own spec? If so, does it have to use our
regular metaformat or can it use something less sucky?)
+```
diff --git a/proposals/226-bridgedb-database-improvements.txt b/proposals/226-bridgedb-database-improvements.txt
index dd52ae6..d239a4a 100644
--- a/proposals/226-bridgedb-database-improvements.txt
+++ b/proposals/226-bridgedb-database-improvements.txt
@@ -1,3 +1,4 @@
+```
Filename: 226-bridgedb-database-improvements.txt
Title: "Scalability and Stability Improvements to BridgeDB: Switching to a
Distributed Database System and RDBMS"
@@ -256,3 +257,4 @@ Status: Reserve
[15]: http://redis.io/commands/evalsha
[16]: http://www.restmq.com/
[17]: https://www.mediawiki.org/wiki/Redis
+```
diff --git a/proposals/227-vote-on-package-fingerprints.txt b/proposals/227-vote-on-package-fingerprints.txt
index 8839941..8b0b472 100644
--- a/proposals/227-vote-on-package-fingerprints.txt
+++ b/proposals/227-vote-on-package-fingerprints.txt
@@ -1,3 +1,4 @@
+```
Filename: 227-vote-on-package-fingerprints.txt
Title: Include package fingerprints in consensus documents
Author: Nick Mathewson, Mike Perry
@@ -145,3 +146,4 @@ Implemented-In: 0.2.6.3-alpha
tool.
+```
diff --git a/proposals/228-cross-certification-onionkeys.txt b/proposals/228-cross-certification-onionkeys.txt
index 64fe5f6..50413d3 100644
--- a/proposals/228-cross-certification-onionkeys.txt
+++ b/proposals/228-cross-certification-onionkeys.txt
@@ -1,3 +1,4 @@
+```
Filename: 228-cross-certification-onionkeys.txt
Title: Cross-certifying identity keys with onion keys
Author: Nick Mathewson
@@ -166,3 +167,4 @@ C. Implementation notes
* An ntor onion key.
+```
diff --git a/proposals/229-further-socks5-extensions.txt b/proposals/229-further-socks5-extensions.txt
index 5661536..390750f 100644
--- a/proposals/229-further-socks5-extensions.txt
+++ b/proposals/229-further-socks5-extensions.txt
@@ -1,3 +1,4 @@
+```
Filename: 229-further-socks5-extensions.txt
Title: Further SOCKS5 extensions
Author: Yawning Angel
@@ -252,3 +253,4 @@ Note: These are good ideas, but it's better not to hack SOCKS any further
* check it into git
* clean text a little, fix redundancy
* ask some questions
+```
diff --git a/proposals/230-rsa1024-relay-id-migration.txt b/proposals/230-rsa1024-relay-id-migration.txt
index 3a997fe..92e72d8 100644
--- a/proposals/230-rsa1024-relay-id-migration.txt
+++ b/proposals/230-rsa1024-relay-id-migration.txt
@@ -1,3 +1,4 @@
+```
Filename: 230-rsa1024-relay-id-migration.txt
Title: How to change RSA1024 relay identity keys
Authors: Nick Mathewson
@@ -83,3 +84,4 @@ Note: Obsoleted by Ed25519 ID keys; superseded by 240 and 256.
the descriptor.
+```
diff --git a/proposals/231-migrate-authority-rsa1024-ids.txt b/proposals/231-migrate-authority-rsa1024-ids.txt
index 0388cf0..af5c6af 100644
--- a/proposals/231-migrate-authority-rsa1024-ids.txt
+++ b/proposals/231-migrate-authority-rsa1024-ids.txt
@@ -1,3 +1,4 @@
+```
Filename: 231-migrate-authority-rsa1024-ids.txt
Title: Migrating authority RSA1024 identity keys
Authors: Nick Mathewson
@@ -68,3 +69,4 @@ Note: Obsoleted by Ed25519 ID keys; superseded by 240 and 256.
but not include them in votes or the consensus; or if they are
included, don't assign them flags that will get them used.
+```
diff --git a/proposals/232-pluggable-transports-through-proxy.txt b/proposals/232-pluggable-transports-through-proxy.txt
index 03cee07..53b1524 100644
--- a/proposals/232-pluggable-transports-through-proxy.txt
+++ b/proposals/232-pluggable-transports-through-proxy.txt
@@ -1,3 +1,4 @@
+```
Filename: 232-pluggable-transports-through-proxy.txt
Title: Pluggable Transport through SOCKS proxy
Author: Arturo Filastò
@@ -77,3 +78,4 @@ Specifications: Tor Pluggable Transport communication
from its stdout and it is configured to use both a normal proxy and
a pluggable transport it should kill the transport proxy.
+```
diff --git a/proposals/233-quicken-tor2web-mode.txt b/proposals/233-quicken-tor2web-mode.txt
index fd002c0..2821f36 100644
--- a/proposals/233-quicken-tor2web-mode.txt
+++ b/proposals/233-quicken-tor2web-mode.txt
@@ -1,3 +1,4 @@
+```
Filename: 233-quicken-tor2web-mode.txt
Title: Making Tor2Web mode faster
Author: Virgil Griffith, Fabio Pietrosanti, Giovanni Pellerano
@@ -33,3 +34,4 @@ Status: Rejected
[1] Tor2web mode: https://trac.torproject.org/projects/tor/ticket/2553
[2] Self-rendezvous: https://trac.torproject.org/projects/tor/ticket/9685
+```
diff --git a/proposals/234-remittance-addresses.txt b/proposals/234-remittance-addresses.txt
index 712c1ed..e49830d 100644
--- a/proposals/234-remittance-addresses.txt
+++ b/proposals/234-remittance-addresses.txt
@@ -1,3 +1,4 @@
+```
Filename: 234-remittance-addresses.txt
Title: Adding remittance field to directory specification
Author: Virgil Griffith, Leif Ryge, Rob Jansen
@@ -38,3 +39,4 @@ Note: Rejected. People are doing this with ContactInfo lines.
(left-most) one of each currency is published in the directory
consensus.
+```
diff --git a/proposals/235-kill-named-flag.txt b/proposals/235-kill-named-flag.txt
index 238315a..17688ed 100644
--- a/proposals/235-kill-named-flag.txt
+++ b/proposals/235-kill-named-flag.txt
@@ -1,3 +1,4 @@
+```
Filename: 235-kill-named-flag.txt
Title: Stop assigning (and eventually supporting) the Named flag
Authors: Sebastian Hahn
@@ -51,3 +52,4 @@ Status: Closed
4. Open questions
None.
+```
diff --git a/proposals/236-single-guard-node.txt b/proposals/236-single-guard-node.txt
index 7db8a67..50c734b 100644
--- a/proposals/236-single-guard-node.txt
+++ b/proposals/236-single-guard-node.txt
@@ -1,3 +1,4 @@
+```
Filename: 236-single-guard-node.txt
Title: The move to a single guard node
Author: George Kadianakis, Nicholas Hopper
@@ -304,3 +305,4 @@ References:
[6]: https://trac.torproject.org/projects/tor/ticket/9001
[7]: https://trac.torproject.org/projects/tor/ticket/10969
+```
diff --git a/proposals/237-directory-servers-for-all.txt b/proposals/237-directory-servers-for-all.txt
index 130bd32..a25352f 100644
--- a/proposals/237-directory-servers-for-all.txt
+++ b/proposals/237-directory-servers-for-all.txt
@@ -1,3 +1,4 @@
+```
Filename: 237-directory-servers-for-all.txt
Title: All relays are directory servers
Author: Matthew Finkel
@@ -131,3 +132,4 @@ Future Considerations:
Is V2Dir a good name for this? It's the name we currently use, but
that's a silly reason to continue using it.
+```
diff --git a/proposals/238-hs-relay-stats.txt b/proposals/238-hs-relay-stats.txt
index 9134003..7b263bd 100644
--- a/proposals/238-hs-relay-stats.txt
+++ b/proposals/238-hs-relay-stats.txt
@@ -1,3 +1,4 @@
+```
Filename: 238-hs-relay-stats.txt
Title: Better hidden service stats from Tor relays
Author: George Kadianakis, David Goulet, Karsten Loesing, Aaron Johnson
@@ -291,3 +292,4 @@ Status: Closed
[ONIONS-LAPLACE-GRAPH]: https://raw.githubusercontent.com/corcra/pioton/master/vis/laplacePDF_mu0.0_b26.67.png
https://raw.githubusercontent.com/corcra/pioton/master/vis/laplaceCDF_mu0.0_b26.67.png
+```
diff --git a/proposals/239-consensus-hash-chaining.txt b/proposals/239-consensus-hash-chaining.txt
index 0c259dd..72738a2 100644
--- a/proposals/239-consensus-hash-chaining.txt
+++ b/proposals/239-consensus-hash-chaining.txt
@@ -1,3 +1,4 @@
+```
Filename: 239-consensus-hash-chaining.txt
Title: Consensus Hash Chaining
Author: Nick Mathewson, Andrea Shepard
@@ -97,3 +98,4 @@ Status: Open
* Clients MAY offer the option to retain previous consensuses in
memory only to allow for validation without the potential disk
leak.
+```
diff --git a/proposals/240-auth-cert-revocation.txt b/proposals/240-auth-cert-revocation.txt
index ae7d4b8..1128671 100644
--- a/proposals/240-auth-cert-revocation.txt
+++ b/proposals/240-auth-cert-revocation.txt
@@ -1,3 +1,4 @@
+```
Filename: 240-auth-cert-revocation.txt
Title: Early signing key revocation for directory authorities
Author: Nick Mathewson
@@ -46,3 +47,4 @@ Status: Open
of certificate B, and certificate B revokes the key of certificate A.
Instead, I am inclined to say that this is a MUST NOT.
+```
diff --git a/proposals/241-suspicious-guard-turnover.txt b/proposals/241-suspicious-guard-turnover.txt
index 004feb1..16ccfb4 100644
--- a/proposals/241-suspicious-guard-turnover.txt
+++ b/proposals/241-suspicious-guard-turnover.txt
@@ -1,3 +1,4 @@
+```
Filename: 241-suspicious-guard-turnover.txt
Title: Resisting guard-turnover attacks
Author: Aaron Johnson, Nick Mathewson
@@ -180,3 +181,4 @@ Appendix B. Acknowledgements
Appendix C. Desirable revisions
Incorporate ideas from proposal 156.
+```
diff --git a/proposals/242-better-families.txt b/proposals/242-better-families.txt
index 5f4ac47..c2edb54 100644
--- a/proposals/242-better-families.txt
+++ b/proposals/242-better-families.txt
@@ -1,3 +1,4 @@
+```
Filename: 242-better-families.txt
Title: Better performance and usability for the MyFamily option
Author: Nick Mathewson
@@ -95,3 +96,4 @@ Superseded-by: 321-happy-families.md
It's possible that families are a bad idea entirely; see ticket
#6676.
+```
diff --git a/proposals/243-hsdir-flag-need-stable.txt b/proposals/243-hsdir-flag-need-stable.txt
index 035550b..1ed0245 100644
--- a/proposals/243-hsdir-flag-need-stable.txt
+++ b/proposals/243-hsdir-flag-need-stable.txt
@@ -1,3 +1,4 @@
+```
Filename: 243-hsdir-flag-need-stable.txt
Title: Give out HSDir flag only to relays with Stable flag
Author: George Kadianakis
@@ -82,3 +83,4 @@ Implemented-in: 0.2.7
With the upcoming keyblinding scheme (#8106) and non-deterministic
HSDir selection (#8244), are there any other criteria that we
should use when assigning HSDir flags?
+```
diff --git a/proposals/244-use-rfc5705-for-tls-binding.txt b/proposals/244-use-rfc5705-for-tls-binding.txt
index 41ebfc1..faa148c 100644
--- a/proposals/244-use-rfc5705-for-tls-binding.txt
+++ b/proposals/244-use-rfc5705-for-tls-binding.txt
@@ -1,3 +1,4 @@
+```
Filename: 244-use-rfc5705-for-tls-binding.txt
Title: Use RFC5705 Key Exporting in our AUTHENTICATE calls
Author: Nick Mathewson
@@ -44,3 +45,4 @@ Implemented-In: 0.3.0.1-alpha
* The label string "EXPORTER FOR TOR TLS CLIENT BINDING " + TYPE
* The context value equal to the client's Ed25519 identity key
* The length 32.
+```
diff --git a/proposals/245-tap-out.txt b/proposals/245-tap-out.txt
index 4a9afd8..6edc3f9 100644
--- a/proposals/245-tap-out.txt
+++ b/proposals/245-tap-out.txt
@@ -1,3 +1,4 @@
+```
Filename: 245-tap-out.txt
Title: Deprecating and removing the TAP circuit extension protocol
Author: Nick Mathewson
@@ -94,3 +95,4 @@ Status: Needs-Revision
(For reference, the functions to patch would be
rend_client_get_random_intro_impl and find_rp_for_intro.)
+```
diff --git a/proposals/246-merge-hsdir-and-intro.txt b/proposals/246-merge-hsdir-and-intro.txt
index 0a70aea..e9aa780 100644
--- a/proposals/246-merge-hsdir-and-intro.txt
+++ b/proposals/246-merge-hsdir-and-intro.txt
@@ -1,3 +1,4 @@
+```
Filename: 246-merge-hsdir-and-intro.txt
Title: Merging Hidden Service Directories and Introduction Points
Author: John Brooks, George Kadianakis
@@ -302,3 +303,4 @@ Change history:
References:
[1] : https://lists.torproject.org/pipermail/tor-dev/2016-January/010203.html
+```
diff --git a/proposals/247-hs-guard-discovery.txt b/proposals/247-hs-guard-discovery.txt
index a41e025..a42161b 100644
--- a/proposals/247-hs-guard-discovery.txt
+++ b/proposals/247-hs-guard-discovery.txt
@@ -1,3 +1,4 @@
+```
Filename: 247-hs-guard-discovery.txt
Title: Defending Against Guard Discovery Attacks using Vanguards
Authors: George Kadianakis and Mike Perry
@@ -757,3 +758,4 @@ CDF_table_323()
----------------------
1. https://onionbalance.readthedocs.org/en/latest/design.html#overview
+```
diff --git a/proposals/248-removing-rsa-identities.txt b/proposals/248-removing-rsa-identities.txt
index eaabe41..3f05df3 100644
--- a/proposals/248-removing-rsa-identities.txt
+++ b/proposals/248-removing-rsa-identities.txt
@@ -1,3 +1,4 @@
+```
Filename: 248-removing-rsa-identities.txt
Title: Remove all RSA identity keys
Authors: Nick Mathewson
@@ -86,3 +87,4 @@ Status: Needs-Revision
make the phase 2 and phase 3 changes.
+```
diff --git a/proposals/249-large-create-cells.txt b/proposals/249-large-create-cells.txt
index 4be3e26..fdc80e2 100644
--- a/proposals/249-large-create-cells.txt
+++ b/proposals/249-large-create-cells.txt
@@ -1,3 +1,4 @@
+```
Filename: 249-large-create-cells.txt
Title: Allow CREATE cells with >505 bytes of handshake data
Authors: Nick Mathewson, Isis Lovecruft
@@ -276,3 +277,4 @@ Appendix B. Acknowledgements
This research was supported in part by NSF grants CNS-1111539,
CNS-1314637, CNS-1526306, CNS-1619454, and CNS-1640548.
+```
diff --git a/proposals/250-commit-reveal-consensus.txt b/proposals/250-commit-reveal-consensus.txt
index c9711aa..f9821e9 100644
--- a/proposals/250-commit-reveal-consensus.txt
+++ b/proposals/250-commit-reveal-consensus.txt
@@ -1,3 +1,4 @@
+```
Filename: 250-commit-reveal-consensus.txt
Title: Random Number Generation During Tor Voting
Authors: David Goulet, George Kadianakis
@@ -640,3 +641,4 @@ References:
[RNGMESSAGING]:
https://moderncrypto.org/mail-archive/messaging/2015/002032.html
+```
diff --git a/proposals/251-netflow-padding.txt b/proposals/251-netflow-padding.txt
index 39cc795..c7a2ef4 100644
--- a/proposals/251-netflow-padding.txt
+++ b/proposals/251-netflow-padding.txt
@@ -1,3 +1,4 @@
+```
Filename: 251-netflow-padding.txt
Title: Padding for netflow record resolution reduction
Authors: Mike Perry
@@ -363,3 +364,4 @@ Appendix A: Padding Cell Timeout Distribution Statistics
13. https://gitweb.torproject.org/torspec.git/tree/proposals/188-bridge-guards.txt
14. http://www.ntop.org/wp-content/uploads/2013/03/nProbe_UserGuide.pdf
15. http://infodoc.alcatel-lucent.com/html/0_add-h-f/93-0073-10-01/7750_SR_OS_Router_Configuration_Guide/Cflowd-CLI.html
+```
diff --git a/proposals/252-single-onion.txt b/proposals/252-single-onion.txt
index ddd78ea..c9b4c24 100644
--- a/proposals/252-single-onion.txt
+++ b/proposals/252-single-onion.txt
@@ -1,3 +1,4 @@
+```
Filename: 252-single-onion.txt
Title: Single Onion Services
Author: John Brooks, Paul Syverson, Roger Dingledine
@@ -257,3 +258,4 @@ Superseded-by: 260
Tor circuit. In speech we sometimes use the even briefer, 'two-nion' and
'one-ion' respectively.
+```
diff --git a/proposals/253-oob-hmac.txt b/proposals/253-oob-hmac.txt
index 9e9e1d7..c7abbd9 100644
--- a/proposals/253-oob-hmac.txt
+++ b/proposals/253-oob-hmac.txt
@@ -1,3 +1,4 @@
+```
Filename: 253-oob-hmac.txt
Title: Out of Band Circuit HMACs
Authors: Mike Perry
@@ -270,3 +271,4 @@ AES-NI[2].
1. https://lists.torproject.org/pipermail/tor-dev/2012-March/003347.html
2. http://archives.seul.org/tor/dev/Mar-2015/msg00137.html
+```
diff --git a/proposals/254-padding-negotiation.txt b/proposals/254-padding-negotiation.txt
index 5ab5341..84b1d1b 100644
--- a/proposals/254-padding-negotiation.txt
+++ b/proposals/254-padding-negotiation.txt
@@ -1,3 +1,4 @@
+```
Filename: 254-padding-negotiation.txt
Title: Padding Negotiation
Authors: Mike Perry
@@ -416,3 +417,4 @@ close the circuit upon detecting this activity.
1. https://gitweb.torproject.org/torspec.git/tree/proposals/251-netflow-padding.txt
2. https://www.cs.kau.se/pulls/hot/thebasketcase-wtfpad/
3. https://www.cs.kau.se/pulls/hot/thebasketcase-ape/
+```
diff --git a/proposals/255-hs-load-balancing.txt b/proposals/255-hs-load-balancing.txt
index 16657d0..136969d 100644
--- a/proposals/255-hs-load-balancing.txt
+++ b/proposals/255-hs-load-balancing.txt
@@ -1,3 +1,4 @@
+```
Filename: 255-hs-load-balancing.txt
Title: Controller features to allow for load-balancing hidden services
Author: Tom van der Woerdt
@@ -156,3 +157,4 @@ the controller. The developer of the tor implementation should not
have to choose between a round-robin algorithm and something that could
pull CPU load averages from a centralized monitoring system.
+```
diff --git a/proposals/256-key-revocation.txt b/proposals/256-key-revocation.txt
index bbccaf9..e512471 100644
--- a/proposals/256-key-revocation.txt
+++ b/proposals/256-key-revocation.txt
@@ -1,3 +1,4 @@
+```
Filename: 256-key-revocation.txt
Title: Key revocation for relays and authorities
Authors: Nick Mathewson
@@ -240,3 +241,4 @@ Status: Reserve
NOT trust any signing key certificate with a matching key.
+```
diff --git a/proposals/257-hiding-authorities.txt b/proposals/257-hiding-authorities.txt
index 9c32f90..cdb49d9 100644
--- a/proposals/257-hiding-authorities.txt
+++ b/proposals/257-hiding-authorities.txt
@@ -1,3 +1,4 @@
+```
Filename: 257-hiding-authorities.txt
Title: Refactoring authorities and making them more isolated from the net
Authors: Nick Mathewson, Andrea Shepard
@@ -211,3 +212,4 @@ A.1. Check-then-start TLS
(We shouldn't do this for all the TLS in Tor: only for the cases
where we want to restrict the users of a given TLS server.)
+```
diff --git a/proposals/258-dirauth-dos.txt b/proposals/258-dirauth-dos.txt
index 91ffd37..aa65d79 100644
--- a/proposals/258-dirauth-dos.txt
+++ b/proposals/258-dirauth-dos.txt
@@ -1,3 +1,4 @@
+```
Filename: 258-dirauth-dos.txt
Title: Denial-of-service resistance for directory authorities
Author: Andrea Shepard
@@ -109,3 +110,4 @@ Status: Dead
Widely distributed DoS attacks with many source IPs may still be
able to avoid raising any single DIRIND_ONEHOP or
DIRIND_DIRECT_CONN counter above threshold.
+```
diff --git a/proposals/259-guard-selection.txt b/proposals/259-guard-selection.txt
index 30bdcfa..76ee9b5 100644
--- a/proposals/259-guard-selection.txt
+++ b/proposals/259-guard-selection.txt
@@ -1,3 +1,4 @@
+```
Filename: 259-guard-selection.txt
Title: New Guard Selection Behaviour
Author: Isis Lovecruft, George Kadianakis
@@ -302,3 +303,4 @@ This proposal was made obsolete by proposal #271.
-*- coding: utf-8 -*-
+```
diff --git a/proposals/260-rend-single-onion.txt b/proposals/260-rend-single-onion.txt
index c4f2617..08ca33a 100644
--- a/proposals/260-rend-single-onion.txt
+++ b/proposals/260-rend-single-onion.txt
@@ -1,3 +1,4 @@
+```
Filename: 260-rend-single-onion.txt
Title: Rendezvous Single Onion Services
Author: Tim Wilson-Brown, John Brooks, Aaron Johnson, Rob Jansen, George Kadianakis, Paul Syverson, Roger Dingledine
@@ -460,3 +461,4 @@ splitting described in section 8. Here are some initial ideas.
be more comfortable enabling submission over an onion service, due to the
additional security benefits.
+```
diff --git a/proposals/261-aez-crypto.txt b/proposals/261-aez-crypto.txt
index f9c652e..1a6c108 100644
--- a/proposals/261-aez-crypto.txt
+++ b/proposals/261-aez-crypto.txt
@@ -1,3 +1,4 @@
+```
Filename: 261-aez-crypto.txt
Title: AEZ for relay cryptography
Author: Nick Mathewson
@@ -280,3 +281,4 @@ A.3. Performance notes: what if we don't have AESNI?
Preliminary results are a bit disappointing, though, so I'll
need to invetigate alternatives as well.]
+```
diff --git a/proposals/262-rekey-circuits.txt b/proposals/262-rekey-circuits.txt
index f639d1d..9f933f0 100644
--- a/proposals/262-rekey-circuits.txt
+++ b/proposals/262-rekey-circuits.txt
@@ -1,3 +1,4 @@
+```
Filename: 262-rekey-circuits.txt
Title: Re-keying live circuits with new cryptographic material
Author: Nick Mathewson
@@ -132,3 +133,4 @@ Status: Reserve
in the presence of traffic analysis.
+```
diff --git a/proposals/263-ntru-for-pq-handshake.txt b/proposals/263-ntru-for-pq-handshake.txt
index 6a3353e..f4d97d4 100644
--- a/proposals/263-ntru-for-pq-handshake.txt
+++ b/proposals/263-ntru-for-pq-handshake.txt
@@ -1,3 +1,4 @@
+```
Filename: 263-ntru-for-pq-handshake.txt
Title: Request to change key exchange protocol for handshake v1.2
Author: John SCHANCK, William WHYTE and Zhenfei ZHANG
@@ -313,3 +314,4 @@ This proposal was made obsolete by proposal #269.
+```
diff --git a/proposals/264-subprotocol-versions.txt b/proposals/264-subprotocol-versions.txt
index 75a1c8f..9ccb803 100644
--- a/proposals/264-subprotocol-versions.txt
+++ b/proposals/264-subprotocol-versions.txt
@@ -1,3 +1,4 @@
+```
Filename: 264-subprotocol-versions.txt
Title: Putting version numbers on the Tor subprotocols
Author: Nick Mathewson
@@ -151,9 +152,7 @@ Implemented-In: 0.2.9.4-alpha
versions we expect to continue supporting.]]
These lines should be voted on. A majority of votes is sufficient to
- make a protocol un-supported.
-
- and should require a supermajority of
+ make a protocol un-supported and it should require a supermajority of
authorities (2/3) to make a protocol required. The required protocols
should not be torrc-configurable, but rather should be hardwired in the
Tor code.
@@ -301,7 +300,7 @@ Implemented-In: 0.2.9.4-alpha
Adding new protocol types is pretty cheap, given compression.
-A.1. Inferring missing proto lines.
+A.1. Inferring missing proto lines
The directory authorities no longer allow versions of Tor before
0.2.4.18-rc. But right now, there is no version of Tor in the
@@ -549,3 +548,4 @@ A.3. Example integration with other open proposals
New Relay protocol version.
+```
diff --git a/proposals/265-load-balancing-with-overhead.txt b/proposals/265-load-balancing-with-overhead.txt
index e79d0a1..43110ba 100644
--- a/proposals/265-load-balancing-with-overhead.txt
+++ b/proposals/265-load-balancing-with-overhead.txt
@@ -1,9 +1,33 @@
+```
Filename: 265-load-balancing-with-overhead.txt
Title: Load Balancing with Overhead Parameters
Authors: Mike Perry
Created: 01 January 2016
-Status: Accepted
-Target: 0.2.9.x
+Status: Open
+Target: arti-dirauth
+
+NOTE: This is one way to address several load balancing problems in Tor,
+including padding overhead and Exit+Guard issues. However, before attempting
+this, we should see if we can simplify the equations further by changing how
+we assign Guard, Fast and Stable flags in the first place. If we assign Guard
+flags such that Guards are properly allocated wrt Middle and Fast, and avoid
+assigning Guard to Exit, this will become simpler. Unfortunately, this is
+literally impossible to fix with C-Tor. In adition to numerous overrides and
+disparate safety checks that prevent changes, several bugs mean that Guard,
+Stable, and Fast flags are randomly assigned: See:
+ https://gitlab.torproject.org/tpo/core/tor/-/issues/40230
+ https://gitlab.torproject.org/tpo/core/tor/-/issues/40395
+ https://gitlab.torproject.org/tpo/core/tor/-/issues/19162
+ https://gitlab.torproject.org/tpo/core/tor/-/issues/40733
+ https://gitlab.torproject.org/tpo/network-health/analysis/-/issues/45
+ https://gitlab.torproject.org/tpo/core/torspec/-/issues/100
+ https://gitlab.torproject.org/tpo/core/torspec/-/issues/160
+ https://gitlab.torproject.org/tpo/core/torspec/-/issues/158
+
+Other approaches to flag equations that have been proposed:
+ https://github.com/frochet/wf_proposal/blob/master/waterfilling-balancing-with-max-diversity.txt
+ https://petsymposium.org/popets/2023/popets-2023-0127.pdf
+
0. Motivation
@@ -336,3 +360,4 @@ combined = solve(
Wme, Wmg, Wgg, Wee)
pprint(combined)
+```
diff --git a/proposals/266-removing-current-obsolete-clients.txt b/proposals/266-removing-current-obsolete-clients.txt
index bc3592b..c266ce1 100644
--- a/proposals/266-removing-current-obsolete-clients.txt
+++ b/proposals/266-removing-current-obsolete-clients.txt
@@ -1,3 +1,4 @@
+```
Filename: 266-removing-current-obsolete-clients.txt
Title: Removing current obsolete clients from the Tor network
Author: Nick Mathewson
@@ -110,7 +111,7 @@ Superseded-by: 264, 272.
2.1. Dropping connections based on link protocols.
- Tor versions before before 0.2.3.6-alpha use a renegotiation-based
+ Tor versions before 0.2.3.6-alpha use a renegotiation-based
handshake instead of our current handshake. We could detect these
handshakes and close the connection at the relay side if the client
attempts to renegotiate.
@@ -137,7 +138,7 @@ Superseded-by: 264, 272.
behavior would probably be the same, though.)
If we throttled connections rather than closing them, we'd only get
- one connnection per authority per hour, but authorities would have to
+ one connection per authority per hour, but authorities would have to
keep open a potentially huge number of sockets.
2.2. Blocking circuit creation under certain circumstances
@@ -210,7 +211,7 @@ A. How to "pull the switch."
TIME 0:
Implement the client/relay side of proposal 264, backported
- to every currently existant Tor version that we still
+ to every currently extant Tor version that we still
support.
At the same time, add support for the new consensus type to
@@ -227,7 +228,7 @@ A. How to "pull the switch."
LATER:
- At some point after nearly all clients and relays hav
+ At some point after nearly all clients and relays have
upgraded to the versions released at Time 0 or later, we
could make the switchover to publishing the new consensus
type.
@@ -259,3 +260,4 @@ B. Next steps.
http://meetbot.debian.net/tor-dev/2016/tor-dev.2016-02-12-15.01.log.html
has a more full discussion of the above ideas.
+```
diff --git a/proposals/267-tor-consensus-transparency.txt b/proposals/267-tor-consensus-transparency.txt
index 117b76a..f5ea26e 100644
--- a/proposals/267-tor-consensus-transparency.txt
+++ b/proposals/267-tor-consensus-transparency.txt
@@ -1,3 +1,4 @@
+```
Filename: 267-tor-consensus-transparency.txt
Title: Tor Consensus Transparency
Author: Linus Nordberg
@@ -361,3 +362,4 @@ C. References
[RFC4627] https://tools.ietf.org/html/rfc4627
[rfc6962-bis-12] https://datatracker.ietf.org/doc/draft-ietf-trans-rfc6962-bis/12
[CT] https://https://www.certificate-transparency.org/
+```
diff --git a/proposals/268-guard-selection.txt b/proposals/268-guard-selection.txt
index 3417b54..2d50790 100644
--- a/proposals/268-guard-selection.txt
+++ b/proposals/268-guard-selection.txt
@@ -1,3 +1,4 @@
+```
Filename: 268-guard-selection.txt
Title: New Guard Selection Behaviour
Author: Isis Lovecruft, George Kadianakis, [Ola Bini]
@@ -507,3 +508,4 @@ Status: Obsolete
version we can't recognize or it was chosen more than GUARD_LIFETIME ago.
-*- coding: utf-8 -*-
+```
diff --git a/proposals/269-hybrid-handshake.txt b/proposals/269-hybrid-handshake.txt
index 4ab7e19..0f32944 100644
--- a/proposals/269-hybrid-handshake.txt
+++ b/proposals/269-hybrid-handshake.txt
@@ -1,3 +1,4 @@
+```
Filename: 269-hybrid-handshake.txt
Title: Transitionally secure hybrid handshakes
Author: John Schanck, William Whyte, Zhenfei Zhang,
@@ -420,3 +421,4 @@ A2. Instantiation with NewHope
PK := B | A_SEED
KEM_ENC(PK) -> NEWHOPE_ENCAPS(PK)
KEM_DEC(C, sk) -> NEWHOPE_DECAPS(C, sk)
+```
diff --git a/proposals/270-newhope-hybrid-handshake.txt b/proposals/270-newhope-hybrid-handshake.txt
index 52f6b50..6ad2e18 100644
--- a/proposals/270-newhope-hybrid-handshake.txt
+++ b/proposals/270-newhope-hybrid-handshake.txt
@@ -1,3 +1,4 @@
+```
Filename: 270-newhope-hybrid-handshake.txt
Title: RebelAlliance: A Post-Quantum Secure Hybrid Handshake Based on NewHope
Author: Isis Lovecruft, Peter Schwabe
@@ -762,3 +763,4 @@ Depends: prop#220 prop#249 prop#264 prop#270
§C. Test Vectors
+```
diff --git a/proposals/271-another-guard-selection.txt b/proposals/271-another-guard-selection.txt
index 38da000..dc6ec46 100644
--- a/proposals/271-another-guard-selection.txt
+++ b/proposals/271-another-guard-selection.txt
@@ -1,3 +1,4 @@
+```
Filename: 271-another-guard-selection.txt
Title: Another algorithm for guard selection
Author: Isis Lovecruft, George Kadianakis, Ola Bini, Nick Mathewson
@@ -887,3 +888,4 @@ TODO. Still non-addressed issues [Section:TODO]
Suggestion: Treat it as a preference when adding to
{CONFIRMED_GUARDS}, but not otherwise.
+```
diff --git a/proposals/272-valid-and-running-by-default.txt b/proposals/272-valid-and-running-by-default.txt
index 210a631..4ec056b 100644
--- a/proposals/272-valid-and-running-by-default.txt
+++ b/proposals/272-valid-and-running-by-default.txt
@@ -1,3 +1,4 @@
+```
Filename: 272-valid-and-running-by-default.txt
Title: Listed routers should be Valid, Running, and treated as such
Created: 26 Aug 2016
@@ -58,3 +59,4 @@ B. Does this solve the zombie problem?
most ancient consensus-understanding Tors stop fetching descriptors
and using the network. More testing needed though.
+```
diff --git a/proposals/273-exit-relay-pinning.txt b/proposals/273-exit-relay-pinning.txt
index 4a83a00..40e5abf 100644
--- a/proposals/273-exit-relay-pinning.txt
+++ b/proposals/273-exit-relay-pinning.txt
@@ -1,3 +1,4 @@
+```
Filename: 273-exit-relay-pinning.txt
Title: Exit relay pinning for web services
Author: Philipp Winter, Tobias Pulls, Roya Ensafi, and Nick Feamster
@@ -221,3 +222,4 @@ Target: n/a
policy over several exit relays, spread over time. In doing so, we
are making assumptions on the number of visits the website sees.
Is there a better solution that isn't significantly more complex?
+```
diff --git a/proposals/274-rotate-onion-keys-less.txt b/proposals/274-rotate-onion-keys-less.txt
index 09f5ea5..5625eb3 100644
--- a/proposals/274-rotate-onion-keys-less.txt
+++ b/proposals/274-rotate-onion-keys-less.txt
@@ -1,3 +1,4 @@
+```
Filename: 274-rotate-onion-keys-less.txt
Title: Rotate onion keys less frequently
Author: Nick Mathewson
@@ -111,3 +112,4 @@ Implemented-In: 0.3.1.1-alpha
previous onion key for an additional onion-key-grace-period-days
days after it is replaced.
+```
diff --git a/proposals/275-md-published-time-is-silly.txt b/proposals/275-md-published-time-is-silly.txt
index 12a762d..1cff90d 100644
--- a/proposals/275-md-published-time-is-silly.txt
+++ b/proposals/275-md-published-time-is-silly.txt
@@ -1,10 +1,11 @@
+```
Filename: 275-md-published-time-is-silly.txt
Title: Stop including meaningful "published" time in microdescriptor consensus
Author: Nick Mathewson
Created: 20-Feb-2017
Status: Closed
Target: 0.3.1.x-alpha
-Implemented-In: 0.4.7.3-alpha
+Implemented-In: 0.4.8.1-alpha
0. Status:
@@ -126,3 +127,4 @@ Implemented-In: 0.4.7.3-alpha
+```
diff --git a/proposals/276-lower-bw-granularity.txt b/proposals/276-lower-bw-granularity.txt
index 156639e..bcd80c0 100644
--- a/proposals/276-lower-bw-granularity.txt
+++ b/proposals/276-lower-bw-granularity.txt
@@ -1,3 +1,4 @@
+```
Filename: 276-lower-bw-granularity.txt
Title: Report bandwidth with lower granularity in consensus documents
Author: Nick Mathewson
@@ -77,3 +78,4 @@ Target: 0.3.1.x-alpha
be safe?
Would a time-aware smoothing mechanism work better?
+```
diff --git a/proposals/277-detect-id-sharing.txt b/proposals/277-detect-id-sharing.txt
index 7837615..e19f7ee 100644
--- a/proposals/277-detect-id-sharing.txt
+++ b/proposals/277-detect-id-sharing.txt
@@ -1,3 +1,4 @@
+```
Filename: 277-detect-id-sharing.txt
Title: Detect multiple relay instances running with same ID
Author: Nick Mathewson
@@ -57,3 +58,4 @@ Target: 0.3.??
+```
diff --git a/proposals/278-directory-compression-scheme-negotiation.txt b/proposals/278-directory-compression-scheme-negotiation.txt
index 6f509fc..6d80d39 100644
--- a/proposals/278-directory-compression-scheme-negotiation.txt
+++ b/proposals/278-directory-compression-scheme-negotiation.txt
@@ -1,3 +1,4 @@
+```
Filename: 278-directory-compression-scheme-negotiation.txt
Title: Directory Compression Scheme Negotiation
Author: Alexander Færøy
@@ -207,3 +208,4 @@ Implemented-In: 0.3.1.1-alpha
This research was supported in part by NSF grants CNS-1111539,
CNS-1314637, CNS-1526306, CNS-1619454, and CNS-1640548.
+```
diff --git a/proposals/279-naming-layer-api.txt b/proposals/279-naming-layer-api.txt
index 1a56ecd..1d22662 100644
--- a/proposals/279-naming-layer-api.txt
+++ b/proposals/279-naming-layer-api.txt
@@ -1,3 +1,4 @@
+```
Filename: 279-naming-layer-api.txt
Title: A Name System API for Tor Onion Services
Author: George Kadianakis, Yawning Angel, David Goulet
@@ -522,3 +523,4 @@ Appendix A.2: Example plugins [PLUGINEXAMPLES]
f) OnioNS
g) Namecoin/Blockstart
+```
diff --git a/proposals/280-privcount-in-tor.txt b/proposals/280-privcount-in-tor.txt
index fd5a011..2944419 100644
--- a/proposals/280-privcount-in-tor.txt
+++ b/proposals/280-privcount-in-tor.txt
@@ -1,3 +1,4 @@
+```
Filename: 280-privcount-in-tor.txt
Title: Privacy-Preserving Statistics with Privcount in Tor
Author: Nick Mathewson, Tim Wilson-Brown
@@ -335,3 +336,4 @@ Superseded-By: 288
want to expand this scheme to work with anonymous data collectors,
such as Tor clients.
+```
diff --git a/proposals/281-bulk-md-download.txt b/proposals/281-bulk-md-download.txt
index c561aa0..8f624d9 100644
--- a/proposals/281-bulk-md-download.txt
+++ b/proposals/281-bulk-md-download.txt
@@ -1,3 +1,4 @@
+```
Filename: 281-bulk-md-download.txt
Title: Downloading microdescriptors in bulk
Author: Nick Mathewson
@@ -98,3 +99,4 @@ Status: Reserve
Caches supporting this download protocol need to advertise
support of a new DirCache subprotocol version.
+```
diff --git a/proposals/282-remove-named-from-consensus.txt b/proposals/282-remove-named-from-consensus.txt
index 7fc28f0..b37e855 100644
--- a/proposals/282-remove-named-from-consensus.txt
+++ b/proposals/282-remove-named-from-consensus.txt
@@ -1,9 +1,10 @@
+```
Filename: 282-remove-named-from-consensus.txt
Title: Remove "Named" and "Unnamed" handling from consensus voting
Author: Nick Mathewson
Created: 12-Sep-2017
Status: Accepted
-Target: 0.3.3.x
+Target: arti-dirauth
1. Summary
@@ -22,3 +23,4 @@ Target: 0.3.3.x
the negotiated method is M or later, then the Named and Unnamed
flags are handled as if any they were any other consensus flags.
+```
diff --git a/proposals/283-ipv6-in-micro-consensus.txt b/proposals/283-ipv6-in-micro-consensus.txt
index 1d29f78..f5846ef 100644
--- a/proposals/283-ipv6-in-micro-consensus.txt
+++ b/proposals/283-ipv6-in-micro-consensus.txt
@@ -1,3 +1,4 @@
+```
Filename: 283-ipv6-in-micro-consensus.txt
Title: Move IPv6 ORPorts from microdescriptors to the microdesc consensus
Author: Tim Wilson-Brown (teor), Nick Mathewson
@@ -186,3 +187,4 @@ Ticket: #20916
Consensus-health implements a ReachableIPv6 pseudo-flag for authorities
and relays:
https://consensus-health.torproject.org/
+```
diff --git a/proposals/284-hsv3-control-port.txt b/proposals/284-hsv3-control-port.txt
index 1ff20bb..6bef07a 100644
--- a/proposals/284-hsv3-control-port.txt
+++ b/proposals/284-hsv3-control-port.txt
@@ -1,3 +1,4 @@
+```
Filename: 284-hsv3-control-port.txt
Title: Hidden Service v3 Control Port
Author: David Goulet
@@ -191,3 +192,4 @@ Status: Closed
an "HSAddress". This field is extended to support v3 address:
HSAddress = 16*Base32Character / 56*Base32Character / "UNKNOWN"
+```
diff --git a/proposals/285-utf-8.txt b/proposals/285-utf-8.txt
index c393e46..453a8db 100644
--- a/proposals/285-utf-8.txt
+++ b/proposals/285-utf-8.txt
@@ -1,8 +1,11 @@
+```
Filename: 285-utf-8.txt
Title: Directory documents should be standardized as UTF-8
Author: Nick Mathewson
Created: 13 November 2017
Status: Accepted
+Target: arti-dirauth
+Ticket: https://gitlab.torproject.org/tpo/core/tor/-/issues/40131
1. Summary and motivation
@@ -113,3 +116,4 @@ Status: Accepted
* Well-Formed UTF-8 Byte Sequences: Table 3-7, page 126.
* Byte order mark: C11, page 83; D94, page 130.
* UTF-8 encoding scheme: D96, pages 130.
+```
diff --git a/proposals/286-hibernation-api.txt b/proposals/286-hibernation-api.txt
index 796cfa8..e76773e 100644
--- a/proposals/286-hibernation-api.txt
+++ b/proposals/286-hibernation-api.txt
@@ -1,3 +1,4 @@
+```
Filename: 286-hibernation-api.txt
Title: Controller APIs for hibernation access on mobile
Author: Nick Mathewson
@@ -195,3 +196,4 @@ Notes: This proposal was useful for our early thinking, but a simpler
StartIdle -- Boolean. If set to 1, Tor begins in IDLE mode.
+```
diff --git a/proposals/287-reduce-lifetime.txt b/proposals/287-reduce-lifetime.txt
index 06e87d0..e37ead9 100644
--- a/proposals/287-reduce-lifetime.txt
+++ b/proposals/287-reduce-lifetime.txt
@@ -1,3 +1,4 @@
+```
Filename: 287-reduce-lifetime.txt
Title: Reduce circuit lifetime without overloading the network
Author: Fernando Fernandez Mancera
@@ -103,3 +104,4 @@ Enhancing Tor's Performance using Real-time Traffic Classification
[https://www.cypherpunks.ca/~iang/pubs/difftor-ccs.pdf] (It's not exactly about
that, but they talk about circuit lifetime and the ten minutes problem a few
times. Also it's an interesting paper.)
+```
diff --git a/proposals/288-privcount-with-shamir.txt b/proposals/288-privcount-with-shamir.txt
index 109c743..7315d4c 100644
--- a/proposals/288-privcount-with-shamir.txt
+++ b/proposals/288-privcount-with-shamir.txt
@@ -1,3 +1,4 @@
+```
Filename: 288-privcount-with-shamir.txt
Title: Privacy-Preserving Statistics with Privcount in Tor (Shamir version)
Author: Nick Mathewson, Tim Wilson-Brown, Aaron Johnson
@@ -565,3 +566,4 @@ Appendix Z. Remaining client-side uncertainties
How data is uploaded to DCs?
What to say about persistence on the DC side?
+```
diff --git a/proposals/289-authenticated-sendmes.txt b/proposals/289-authenticated-sendmes.txt
index e09b882..ebb1e3c 100644
--- a/proposals/289-authenticated-sendmes.txt
+++ b/proposals/289-authenticated-sendmes.txt
@@ -1,3 +1,4 @@
+```
Filename: 289-authenticated-sendmes.txt
Title: Authenticating sendme cells to mitigate bandwidth attacks
Author: Rob Jansen, Roger Dingledine, David Goulet
@@ -493,3 +494,4 @@ Implemented-In: 0.4.1.1-alpha
This research was supported in part by NSF grants CNS-1111539,
CNS-1314637, CNS-1526306, CNS-1619454, and CNS-1640548.
+```
diff --git a/proposals/290-deprecate-consensus-methods.txt b/proposals/290-deprecate-consensus-methods.txt
index 979559c..832426e 100644
--- a/proposals/290-deprecate-consensus-methods.txt
+++ b/proposals/290-deprecate-consensus-methods.txt
@@ -1,3 +1,4 @@
+```
Filename: 290-deprecate-consensus-methods.txt
Title: Continuously update consensus methods
Author: Nick Mathewson
@@ -75,3 +76,4 @@ B. Client and relay compatibility notes
not represent backward-incompatible changes in how they generate
their consensuses.
+```
diff --git a/proposals/291-two-guard-nodes.txt b/proposals/291-two-guard-nodes.txt
index 43885e3..9b89eae 100644
--- a/proposals/291-two-guard-nodes.txt
+++ b/proposals/291-two-guard-nodes.txt
@@ -1,9 +1,10 @@
+```
Filename: 291-two-guard-nodes.txt
Title: The move to two guard nodes
Author: Mike Perry
Created: 2018-03-22
Supersedes: Proposal 236
-Status: Needs-Revision
+Status: Finished
0. Background
@@ -154,7 +155,7 @@ Status: Needs-Revision
However, while removing path restrictions will solve the immediate
problem, it will not address other instances where Tor temporarily opts
- use a second guard due to congestion, OOM, or failure of its primary
+ to use a second guard due to congestion, OOM, or failure of its primary
guard, and we're still running into bugs where this can be adversarially
controlled or just happen randomly[5].
@@ -254,3 +255,4 @@ References:
12. https://trac.torproject.org/projects/tor/ticket/10969
13. https://www.freehaven.net/anonbib/cache/wpes12-cogs.pdf
14. https://gitweb.torproject.org/torspec.git/tree/proposals/247-hs-guard-discovery.txt
+```
diff --git a/proposals/292-mesh-vanguards.txt b/proposals/292-mesh-vanguards.txt
index 5341213..7e579c8 100644
--- a/proposals/292-mesh-vanguards.txt
+++ b/proposals/292-mesh-vanguards.txt
@@ -1,8 +1,9 @@
+```
Filename: 292-mesh-vanguards.txt
Title: Mesh-based vanguards
Authors: George Kadianakis and Mike Perry
Created: 2018-05-08
-Status: Accepted
+Status: Closed
Supersedes: 247
0. Motivation
@@ -534,3 +535,4 @@ CDF_table_33()
----------------------
1. https://onionbalance.readthedocs.org/en/latest/design.html#overview
+```
diff --git a/proposals/293-know-when-to-publish.txt b/proposals/293-know-when-to-publish.txt
index c6fd1aa..2ca4222 100644
--- a/proposals/293-know-when-to-publish.txt
+++ b/proposals/293-know-when-to-publish.txt
@@ -1,3 +1,4 @@
+```
Filename: 293-know-when-to-publish.txt
Title: Other ways for relays to know when to publish
Author: Nick Mathewson
@@ -59,3 +60,4 @@ Implemented-In: 0.4.0.1-alpha
published time in consensus documents accurate -- we can start
setting it to some time in the distant future, per proposal 275.
+```
diff --git a/proposals/294-tls-1.3.txt b/proposals/294-tls-1.3.txt
index c9bae79..e195b2f 100644
--- a/proposals/294-tls-1.3.txt
+++ b/proposals/294-tls-1.3.txt
@@ -1,3 +1,4 @@
+```
Filename: 294-tls-1.3.txt
Title: TLS 1.3 Migration
Authors: Isis Lovecruft
@@ -338,3 +339,4 @@ A. References
https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set1_groups.html
[TLS-1.3_SIGNATURE_ALGOS]:
https://tlswg.github.io/tls13-spec/draft-ietf-tls-tls13.html#signature-algorithms
+```
diff --git a/proposals/295-relay-crypto-with-adl.txt b/proposals/295-relay-crypto-with-adl.txt
index 7f8fc42..bf8fd77 100644
--- a/proposals/295-relay-crypto-with-adl.txt
+++ b/proposals/295-relay-crypto-with-adl.txt
@@ -1,3 +1,4 @@
+```
Filename: 295-relay-crypto-with-adl.txt
Title: Using ADL for relay cryptography (solving the crypto-tagging attack)
Author: Tomer Ashur, Orr Dunkelman, Atul Luykx
@@ -561,3 +562,4 @@ Status: Open
No changes are required to the authentication process when the relay
cell is sent backwards.
+```
diff --git a/proposals/296-expose-bandwidth-files.txt b/proposals/296-expose-bandwidth-files.txt
index f853604..c61dc68 100644
--- a/proposals/296-expose-bandwidth-files.txt
+++ b/proposals/296-expose-bandwidth-files.txt
@@ -1,9 +1,11 @@
+```
Filename: 296-expose-bandwidth-files.txt
Title: Have Directory Authorities expose raw bandwidth list files
Author: Tom Ritter
Created: 11-December-2017
-Status: Open
+Status: Closed
Ticket: https://trac.torproject.org/projects/tor/ticket/21377
+Implemented-In: 0.4.0.1-alpha
1. Introduction
@@ -83,3 +85,4 @@ Applications that parse the document should follow the bandwidth list file
specification in bandwidth-file-spec.txt.
If a new bandwidth list format version is added, the applications MAY need
to upgrade to that version.
+```
diff --git a/proposals/297-safer-protover-shutdowns.txt b/proposals/297-safer-protover-shutdowns.txt
index 59fbac1..96d6f62 100644
--- a/proposals/297-safer-protover-shutdowns.txt
+++ b/proposals/297-safer-protover-shutdowns.txt
@@ -1,3 +1,4 @@
+```
Filename: 297-safer-protover-shutdowns.txt
Title: Relaxing the protover-based shutdown rules
Author: Nick Mathewson
@@ -104,3 +105,4 @@ IMPLEMENTATION NOTE:
+```
diff --git a/proposals/298-canonical-families.txt b/proposals/298-canonical-families.txt
index a96ab8d..4576d63 100644
--- a/proposals/298-canonical-families.txt
+++ b/proposals/298-canonical-families.txt
@@ -1,3 +1,4 @@
+```
Filename: 298-canonical-families.txt
Title: Putting family lines in canonical form
Author: Nick Mathewson
@@ -61,3 +62,4 @@ Implemented-In: 0.4.0.1-alpha
+```
diff --git a/proposals/299-ip-failure-count.txt b/proposals/299-ip-failure-count.txt
index 8c2319f..1078e6d 100644
--- a/proposals/299-ip-failure-count.txt
+++ b/proposals/299-ip-failure-count.txt
@@ -1,3 +1,4 @@
+```
Filename: 299-ip-failure-count.txt
Title: Preferring IPv4 or IPv6 based on IP Version Failure Count
Author: Neel Chauhan
@@ -222,3 +223,4 @@ Ticket: https://trac.torproject.org/projects/tor/ticket/27491
Thank you teor for aiding me with the implementation of Happy Eyeballs in
Tor. This would not have been possible if it weren't for you.
+```
diff --git a/proposals/300-walking-onions.txt b/proposals/300-walking-onions.txt
index 3df9f44..5ab3a7a 100644
--- a/proposals/300-walking-onions.txt
+++ b/proposals/300-walking-onions.txt
@@ -1,3 +1,4 @@
+```
Filename: 300-walking-onions.txt
Title: Walking Onions: Scaling and Saving Bandwidth
Author: Nick Mathewson
@@ -511,3 +512,4 @@ A.2. Additional ideas
but it might be worth looking at harder.
+```
diff --git a/proposals/301-dont-vote-on-package-fingerprints.txt b/proposals/301-dont-vote-on-package-fingerprints.txt
index 8e8b63a..e4f5c03 100644
--- a/proposals/301-dont-vote-on-package-fingerprints.txt
+++ b/proposals/301-dont-vote-on-package-fingerprints.txt
@@ -1,8 +1,9 @@
+```
Filename: 301-dont-vote-on-package-fingerprints.txt
Title: Don't include package fingerprints in consensus documents
Author: Iain R. Learmonth
Created: 2019-02-21
-Status: Open
+Status: Closed
Ticket: #28465
0. Abstract
@@ -71,3 +72,4 @@ B. Acknowledgements
Thanks to teor and Nick Mathewson for their comments and
suggestions on this proposal.
+```
diff --git a/proposals/302-padding-machines-for-onion-clients.txt b/proposals/302-padding-machines-for-onion-clients.txt
index cd24298..52710b0 100644
--- a/proposals/302-padding-machines-for-onion-clients.txt
+++ b/proposals/302-padding-machines-for-onion-clients.txt
@@ -1,3 +1,4 @@
+```
Filename: 302-padding-machines-for-onion-clients.txt
Title: Hiding onion service clients using padding
Author: George Kadianakis, Mike Perry
@@ -303,3 +304,4 @@ A. Acknowledgements
[1]: "Understanding Tor Usage with Privacy-Preserving Measurement"
by Akshaya Mani, T Wilson-Brown, Rob Jansen, Aaron Johnson, and Micah Sherr
In Proceedings of the Internet Measurement Conference 2018 (IMC 2018).
+```
diff --git a/proposals/303-protover-removal-policy.txt b/proposals/303-protover-removal-policy.txt
index 54fcead..c2d5697 100644
--- a/proposals/303-protover-removal-policy.txt
+++ b/proposals/303-protover-removal-policy.txt
@@ -1,3 +1,4 @@
+```
Filename: 303-protover-removal-policy.txt
Title: When and how to remove support for protocol versions
Author: Nick Mathewson
@@ -60,3 +61,4 @@ Status: Open
_recommended_ for clients for at least 18 months.
+```
diff --git a/proposals/304-socks5-extending-hs-error-codes.txt b/proposals/304-socks5-extending-hs-error-codes.txt
index d8ff7d5..8866fa1 100644
--- a/proposals/304-socks5-extending-hs-error-codes.txt
+++ b/proposals/304-socks5-extending-hs-error-codes.txt
@@ -1,3 +1,4 @@
+```
Filename: 304-socks5-extending-hs-error-codes.txt
Title: Extending SOCKS5 Onion Service Error Codes
Author: David Goulet, George Kadianakis
@@ -107,3 +108,4 @@ References:
[PROP229] https://gitweb.torproject.org/torspec.git/tree/proposals/229-further-socks5-extensions.txt
[RFC1928] https://www.ietf.org/rfc/rfc1928.txt
+```
diff --git a/proposals/305-establish-intro-dos-defense-extention.txt b/proposals/305-establish-intro-dos-defense-extention.txt
index e377f3e..e1b0256 100644
--- a/proposals/305-establish-intro-dos-defense-extention.txt
+++ b/proposals/305-establish-intro-dos-defense-extention.txt
@@ -1,3 +1,4 @@
+```
Filename: 305-establish-intro-dos-defense-extention.txt
Title: ESTABLISH_INTRO Cell DoS Defense Extension
Author: David Goulet, George Kadianakis
@@ -199,3 +200,4 @@ References:
[1] https://lists.torproject.org/pipermail/tor-dev/2019-May/013837.html
[2] https://trac.torproject.org/15516
+```
diff --git a/proposals/306-ipv6-happy-eyeballs.txt b/proposals/306-ipv6-happy-eyeballs.txt
index c5c9ddf..86a1445 100644
--- a/proposals/306-ipv6-happy-eyeballs.txt
+++ b/proposals/306-ipv6-happy-eyeballs.txt
@@ -1,3 +1,4 @@
+```
Filename: 306-ipv6-happy-eyeballs.txt
Title: A Tor Implementation of IPv6 Happy Eyeballs
Author: Neel Chauhan
@@ -344,3 +345,4 @@ Ticket: https://trac.torproject.org/projects/tor/ticket/29801
[P299-TRAC]: https://trac.torproject.org/projects/tor/ticket/29801
[TEOR-P306-REP]: https://lists.torproject.org/pipermail/tor-dev/2019-July/013919.html
+```
diff --git a/proposals/307-onionbalance-v3.txt b/proposals/307-onionbalance-v3.txt
index baaa717..fb44cb3 100644
--- a/proposals/307-onionbalance-v3.txt
+++ b/proposals/307-onionbalance-v3.txt
@@ -1,3 +1,4 @@
+```
Filename: 307-onionbalance-v3.txt
Title: Onion Balance Support for Onion Service v3
Author: Nick Mathewson
@@ -183,3 +184,4 @@ A. Acknowledgments
in this problem space.
This research was supported by NSF grants CNS-1526306 and CNS-1619454.
+```
diff --git a/proposals/308-counter-galois-onion.txt b/proposals/308-counter-galois-onion.txt
index e1f48bc..4714e8d 100644
--- a/proposals/308-counter-galois-onion.txt
+++ b/proposals/308-counter-galois-onion.txt
@@ -1,11 +1,20 @@
+```
Filename: 308-counter-galois-onion.txt
Title: Counter Galois Onion: A New Proposal for Forward-Secure Relay Cryptography
Authors: Jean Paul Degabriele, Alessandro Melloni, Martijn Stam
Created: 13 Sep 2019
Last-Modified: 13 Sep 2019
-Status: Open
+Status: Superseded
+ NOTE: This proposal is superseded by an improved version of the
+ Counter Galois Onion design based on the authors' forthcoming
+ paper, "Counter Galois Onion: Fast, Forward-Secure, and
+ Non-Malleable Onion Encryption for Tor". The improved proposal
+ will be publicly available once the paper is closer to being
+ ready for publication.
+ -nickm
+
1. Background and Motivation
@@ -548,3 +557,4 @@ Misuse-Resistant Authenticated Encryption", RFC 8452, April 2019.
[ST13] Thomas Shrimpton, R. Seth Terashima, "A Modular Framework for
Building Variable-Input Length Tweakable Ciphers", ASIACRYPT 2013.
+```
diff --git a/proposals/309-optimistic-socks-in-tor.txt b/proposals/309-optimistic-socks-in-tor.txt
index d22a1a0..7f9272d 100644
--- a/proposals/309-optimistic-socks-in-tor.txt
+++ b/proposals/309-optimistic-socks-in-tor.txt
@@ -1,3 +1,4 @@
+```
Filename: 309-optimistic-socks-in-tor.txt
Title: Optimistic SOCKS Data
Author: Tom Ritter
@@ -76,3 +77,4 @@ Ticket: #5915
References:
[RFC1928] https://www.ietf.org/rfc/rfc1928.txt
+```
diff --git a/proposals/310-bandaid-on-guard-selection.txt b/proposals/310-bandaid-on-guard-selection.txt
index 2001994..94477a1 100644
--- a/proposals/310-bandaid-on-guard-selection.txt
+++ b/proposals/310-bandaid-on-guard-selection.txt
@@ -1,3 +1,4 @@
+```
Filename: 310-bandaid-on-guard-selection.txt
Title: Towards load-balancing in Prop 271
Author: Florentin Rochet, Aaron Johnson et al.
@@ -93,3 +94,4 @@ Status: Closed
force clients onto compromised guards, using relays that are part of the
history if they're still available (in sampled order), and by tracking its
size. This should maintain the initial goals of Prop 271.
+```
diff --git a/proposals/311-relay-ipv6-reachability.txt b/proposals/311-relay-ipv6-reachability.txt
index 11282c3..2ad7f46 100644
--- a/proposals/311-relay-ipv6-reachability.txt
+++ b/proposals/311-relay-ipv6-reachability.txt
@@ -1,3 +1,4 @@
+```
Filename: 311-relay-ipv6-reachability.txt
Title: Tor Relay IPv6 Reachability
Author: teor, Nick Mathewson
@@ -836,3 +837,4 @@ References:
[Tor Specification]:
https://gitweb.torproject.org/torspec.git/tree/tor-spec.txt
+```
diff --git a/proposals/312-relay-auto-ipv6-addr.txt b/proposals/312-relay-auto-ipv6-addr.txt
index 712175e..a82e239 100644
--- a/proposals/312-relay-auto-ipv6-addr.txt
+++ b/proposals/312-relay-auto-ipv6-addr.txt
@@ -1,3 +1,4 @@
+```
Filename: 312-relay-auto-ipv6-addr.txt
Title: Tor Relay Automatic IPv6 Address Discovery
Author: teor, Nick Mathewson, s7r
@@ -1563,3 +1564,4 @@ References:
[Tor Supported Platforms]:
https://trac.torproject.org/projects/tor/wiki/org/teams/NetworkTeam/SupportedPlatforms#OSSupportlevels
+```
diff --git a/proposals/313-relay-ipv6-stats.txt b/proposals/313-relay-ipv6-stats.txt
index ae02a33..c637dad 100644
--- a/proposals/313-relay-ipv6-stats.txt
+++ b/proposals/313-relay-ipv6-stats.txt
@@ -1,3 +1,4 @@
+```
Filename: 313-relay-ipv6-stats.txt
Title: Tor Relay IPv6 Statistics
Author: teor, Karsten Loesing, Nick Mathewson
@@ -405,3 +406,4 @@ References:
[Tor Specification]:
https://gitweb.torproject.org/torspec.git/tree/tor-spec.txt
+```
diff --git a/proposals/315-update-dir-required-fields.txt b/proposals/315-update-dir-required-fields.txt
index 1761a03..875d8a0 100644
--- a/proposals/315-update-dir-required-fields.txt
+++ b/proposals/315-update-dir-required-fields.txt
@@ -1,3 +1,4 @@
+```
Filename: 315-update-dir-required-fields.txt
Title: Updating the list of fields required in directory documents
Author: Nick Mathewson
@@ -129,3 +130,4 @@ Notes:
become required:
* pr
+```
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/317-secure-dns-name-resolution.txt b/proposals/317-secure-dns-name-resolution.txt
index ad2b7e6..55db19f 100644
--- a/proposals/317-secure-dns-name-resolution.txt
+++ b/proposals/317-secure-dns-name-resolution.txt
@@ -1,3 +1,4 @@
+```
Filename: 317-secure-dns-name-resolution.txt
Title: Improve security aspects of DNS name resolution
Author: Christian Hofer
@@ -218,3 +219,4 @@ Performance and scalability:
onion service in a performant manner it is always possible to fallback to
clearweb nameservers by changing a configuration setting.
+```
diff --git a/proposals/319-wide-everything.md b/proposals/319-wide-everything.md
index 0de6676..06173ed 100644
--- a/proposals/319-wide-everything.md
+++ b/proposals/319-wide-everything.md
@@ -3,9 +3,11 @@ Filename: 319-wide-everything.md
Title: RELAY_FRAGMENT cells
Author: Nick Mathewson
Created: 11 May 2020
-Status: Open
+Status: Obsolete
```
+(Proposal superseded by proposal 340)
+
(This proposal is part of the Walking Onions spec project.)
# Introduction
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/324-rtt-congestion-control.txt b/proposals/324-rtt-congestion-control.txt
index 78b6789..c601980 100644
--- a/proposals/324-rtt-congestion-control.txt
+++ b/proposals/324-rtt-congestion-control.txt
@@ -1,8 +1,9 @@
+```
Filename: 324-rtt-congestion-control.txt
Title: RTT-based Congestion Control for Tor
Author: Mike Perry
Created: 02 July 2020
-Status: Open
+Status: Finished
0. Motivation [MOTIVATION]
@@ -144,37 +145,43 @@ measured by the RTT estimator, and if these heurtics detect a stall or a jump,
we do not use that value to update RTT or BDP, nor do we update any congestion
control algorithm information that round.
-If the time delta is 0, that is always treated as a clock stall.
+If the time delta is 0, that is always treated as a clock stall, the RTT is
+not used, congestion control is not updated, and this fact is cached globally.
-If we have measured at least 'cc_bwe_min' RTT values or we have successfully
-exited slow start, then every sendme ACK, the new candidate RTT is compared to
-the stored EWMA RTT. If the new RTT is either 5000 times larger than the EWMA
-RTT, or 5000 times smaller than the stored EWMA RTT, then we do not record that
-estimate, and do not update BDP or the congestion control algorithms for that
-SENDME ack.
+If the circuit does not yet have an EWMA RTT or it is still in Slow Start, then
+no further checks are performed, and the RTT is used.
-Moreover, if a clock stall is detected by *any* circuit, this fact is
-cached, and this cached value is used on circuits for which we do not
-have enough data to compute the above heueristics. This cached value is
-also exported for use by the edge connection rate calculations done by
-[XON_ADVISORY].
+If the circuit has stored an EWMA RTT and has exited Slow Start, then every
+sendme ACK, the new candidate RTT is compared to the stored EWMA RTT. If the
+new RTT is 5000 times larger than the EWMA RTT, then the circuit does not
+record that estimate, and does not update BDP or the congestion control
+algorithms for that SENDME ack. If the new RTT is 5000 times smaller than the
+EWMA RTT, then the circuit uses the globally cached value from above (ie: it
+assumes the clock is stalled *only* if there was previously *also* a 0-delta RTT).
+
+If both ratio checks pass, the globally cached clock stall state is set to
+false (no stall), and the RTT value is used.
2.1.2. N_EWMA Smoothing [N_EWMA_SMOOTHING]
-Both RTT estimation and SENDME BDP estimation require smoothing, to
-reduce the effects of packet jitter.
+RTT estimation requires smoothing, to reduce the effects of packet jitter.
This smoothing is performed using N_EWMA[27], which is an Exponential
Moving Average with alpha = 2/(N+1):
- N_EWMA = BDP*2/(N+1) + N_EWMA_prev*(N-1)/(N+1).
+ N_EWMA = RTT*2/(N+1) + N_EWMA_prev*(N-1)/(N+1)
+ = (RTT*2 + N_EWMA_prev*(N-1))/(N+1).
+
+Note that the second rearranged form MUST be used in order to ensure that
+rounding errors are handled in the same manner as other implementations.
-Flow control rate limiting uses this function
+Flow control rate limiting uses this function.
-For both RTT and SENDME BDP estimation, N is the number of SENDME acks
-between congestion window updates, divided by the value of consensus
-parameter 'cc_ewma_cwnd_pct', and then capped at a max of 'cc_ewma_max',
-but always at least 2:
+During Slow Start, N is set to `cc_ewma_ss`, for RTT estimation.
+
+After Slow Start, N is the number of SENDME acks between congestion window
+updates, divided by the value of consensus parameter 'cc_ewma_cwnd_pct', and
+then capped at a max of 'cc_ewma_max', but always at least 2:
N = MAX(MIN(CWND_UPDATE_RATE(cc)*cc_ewma_cwnd_pct/100, cc_ewma_max), 2);
@@ -239,12 +246,11 @@ have been given different names than in those two mails. The third algorithm,
[TOR_NOLA], simply uses the latest BDP estimate directly as its congestion
window.
-These algorithms will be evaluated by running Shadow simulations, to
-help determine parameter ranges, but experimentation on the live network
-will be required to determine which of these algorithms performs best
-when in competition with our current SENDME behavior, as used by real
-network traffic. This experimentation and tuning is detailed in section
-[EVALUATION].
+These algorithms were evaluated by running Shadow simulations, to help
+determine parameter ranges, and with experimentation on the live network.
+After this testing, we have converged on using [TOR_VEGAS], and RTT-based BDP
+estimation using the congestion window. We leave the algorithms in place
+for historical reference.
All of these algorithms have rules to update 'cwnd' - the current congestion
window, which starts out at a value controlled by consensus parameter
@@ -263,7 +269,6 @@ The 'deliver_window' field is still used to decide when to send a SENDME. In C
tor, the deliver window is initially set at 1000, but it never gets below 900,
because authenticated sendmes (Proposal 289) require that we must send only
one SENDME at a time, and send it immediately after 100 cells are received.
-This property turns out to be very useful for [BDP_ESTIMATION].
Implementation of different algorithms should be very simple - each
algorithm should have a different update function depending on the selected algorithm,
@@ -300,22 +305,23 @@ is circuit-scoped.
At a high-level, there are three main ways to estimate the Bandwidth-Delay
Product: by using the current congestion window and RTT, by using the inflight
-cells and RTT, and by measuring SENDME arrival rate.
+cells and RTT, and by measuring SENDME arrival rate. After extensive shadow
+simulation and live testing, we have arrived at using the congestion window
+RTT based estimator, but we will describe all three for background.
All three estimators are updated every SENDME ack arrival.
-The SENDME arrival rate is the most accurate way to estimate BDP, but it
-requires averaging over multiple SENDME acks to do so. The congestion window
-and inflight estimates rely on the congestion algorithm more or less correctly
-tracking an approximation of the BDP, and then use current and minimum RTT to
-compensate for overshoot.
-
-The SENDME estimator tends to be accurate after ~3-5 SENDME acks. The cwnd and
-inflight estimators tend to be accurate once the congestion window exceeds
-BDP.
+The SENDME arrival rate is the most direct way to estimate BDP, but it
+requires averaging over multiple SENDME acks to do so. Unfortunatetely,
+this approach suffers from what is called "ACK compression", where returning
+SENDMEs build up in queues, causing over-estimation of the BDP.
-We specify all three because they are all useful in various cases. These cases
-are broken up and combined to form the Piecewise BDP estimator.
+The congestion window and inflight estimates rely on the congestion algorithm
+more or less correctly tracking an approximation of the BDP, and then use
+current and minimum RTT to compensate for overshoot. These estimators tend to
+under-estimate BDP, especially when the congestion window is below the BDP.
+This under-estimation is corrected for by the increase of the congestion
+window in congestion control algorithm rules.
3.1.1. SENDME arrival BDP estimation
@@ -372,6 +378,8 @@ in Shadow simulation, due to ack compression.
3.1.2. Congestion Window BDP Estimation
+This is the BDP estimator we use.
+
Assuming that the current congestion window is at or above the current BDP,
the bandwidth estimate is the current congestion window size divided by the
RTT estimate:
@@ -387,6 +395,13 @@ Simplifying:
BDP = cwnd * RTT_min / RTT_current_ewma
+The RTT_min for this calculation comes from the minimum RTT_current_ewma seen
+in the lifetime of this circuit. If the congestion window falls to
+`cc_cwnd_min` after slow start, implementations MAY choose to reset RTT_min
+for use in this calculation to either the RTT_current_ewma, or a
+percentile-weighted average between RTT_min and RTT_current_ewma, specified by
+`cc_rtt_reset_pct`. This helps with escaping starvation conditions.
+
The net effect of this estimation is to correct for any overshoot of
the cwnd over the actual BDP. It will obviously underestimate BDP if cwnd
is below BDP.
@@ -405,12 +420,17 @@ and all circuit queues have drained without blocking the local orconn, we stop
updating this BDP estimate, because there are not sufficient inflight cells
to properly estimate BDP.
+While the research literature for Vegas says that inflight estimators
+performed better due to the ability to avoid overhsoot, we had better
+performance results using other methods to control overshot. Hence, we do not
+use the inflight BDP estimator.
+
3.1.4. Piecewise BDP estimation
-The piecewise BDP estimation is used to help respond more quickly in the event
-the local OR connection is blocked, which indicates congestion somewhere along
-the path from the client to the guard (or between Exit and Middle). In this
-case, it takes the minimum of the inflight and SENDME estimators.
+A piecewise BDP estimation could be used to help respond more quickly in the
+event the local OR connection is blocked, which indicates congestion somewhere
+along the path from the client to the guard (or between Exit and Middle). In
+this case, it takes the minimum of the inflight and SENDME estimators.
When the local OR connection is not blocked, this estimator uses the max of
the SENDME and cwnd estimator values.
@@ -512,6 +532,9 @@ each time we get a SENDME (aka sendme_process_circuit_level()):
TCP Vegas control algorithm estimates the queue lengths at relays by
subtracting the current BDP estimate from the current congestion window.
+After extensive shadow simulation and live testing, we have settled on this
+congestion control algorithm for use in Tor.
+
Assuming the BDP estimate is accurate, any amount by which the congestion
window exceeds the BDP will cause data to queue.
@@ -529,63 +552,151 @@ original cwnd estimator. So while this capability to change the BDP estimator
remains in the C implementation, we do not expect it to be used.
However, it was useful to use a local OR connection block at the time of
-SENDME ack arrival, as an immediate congestion signal.
+SENDME ack arrival, as an immediate congestion signal. Note that in C-Tor,
+this orconn_block state is not derived from any socket info, but instead is a
+heuristic that declares an orconn as blocked if any circuit cell queue
+exceeds the 'cellq_high' consensus parameter.
(As an additional optimization, we could also use the ECN signal described in
ideas/xxx-backward-ecn.txt, but this is not implemented. It is likely only of
any benefit during Slow Start, and even that benefit is likely small.)
-Congestion signals from RTT, blocked OR connections, or ECN are processed only
-once per congestion window. This is achieved through the next_cc_event flag,
-which is initialized to a cwnd worth of SENDME acks, and is decremented
-each ack. Congestion signals are only evaluated when it reaches 0.
-
-Here is the complete pseudocode for TOR_VEGAS, which is run every time
-an endpoint receives a SENDME ack:
-
- # Update acked cells
- inflight -= cc_sendme_inc
+During Slow Start, we use RFC3742 Limited Slow Start[32], which checks the
+congestion signals from RTT, blocked OR connections, or ECN every single
+SENDME ack. It also provides a `cc_sscap_*` parameter for each path length,
+which reduces the congestion window increment rate after it is crossed, as
+per the rules in RFC3742:
+ rfc3742_ss_inc(cwnd):
+ if cwnd <= cc_ss_cap_pathtype:
+ # Below the cap, we increment as per cc_cwnd_inc_pct_ss percent:
+ return round(cc_cwnd_inc_pct_ss*cc_sendme_inc/100)
+ else:
+ # This returns an increment equivalent to RFC3742, rounded,
+ # with a minimum of inc=1.
+ # From RFC3742:
+ # K = int(cwnd/(0.5 max_ssthresh));
+ # inc = int(MSS/K);
+ return MAX(round((cc_sendme_inc*cc_ss_cap_pathtype)/(2*cwnd)), 1);
+
+During both Slow Start, and Steady State, if the congestion window is not full,
+we never increase the congestion window. We can still decrease it, or exit slow
+start, in this case. This is done to avoid causing overshoot. The original TCP
+Vegas addressed this problem by computing BDP and queue_use from inflight,
+instead of cwnd, but we found that approach to have signficantly worse
+performance.
+
+Because C-Tor is single-threaded, multiple SENDME acks may arrive during one
+processing loop, before edge connections resume reading. For this reason,
+we provide two heuristics to provide some slack in determining the full
+condition. The first is to allow a gap between inflight and cwnd,
+parameterized as 'cc_cwnd_full_gap' multiples of 'cc_sendme_inc':
+ cwnd_is_full(cwnd, inflight):
+ if inflight + 'cc_cwnd_full_gap'*'cc_sendme_inc' >= cwnd:
+ return true
+ else
+ return false
+The second heuristic immediately resets the full state if it falls below
+'cc_cwnd_full_minpct' full:
+ cwnd_is_nonfull(cwnd, inflight):
+ if 100*inflight < 'cc_cwnd_full_minpct'*cwnd:
+ return true
+ else
+ return false
+
+This full status is cached once per cwnd if 'cc_cwnd_full_per_cwnd=1';
+otherwise it is cached once per cwnd update. These two helper functions
+determine the number of acks in each case:
+ SENDME_PER_CWND(cwnd):
+ return ((cwnd + 'cc_sendme_inc'/2)/'cc_sendme_inc')
+ CWND_UPDATE_RATE(cwnd, in_slow_start):
+ # In Slow Start, update every SENDME
+ if in_slow_start:
+ return 1
+ else: # Otherwise, update as per the 'cc_inc_rate' (31)
+ return ((cwnd + 'cc_cwnd_inc_rate'*'cc_sendme_inc'/2)
+ / ('cc_cwnd_inc_rate'*'cc_sendme_inc'));
+
+Shadow experimentation indicates that 'cc_cwnd_full_gap=2' and
+'cc_cwnd_full_per_cwnd=0' minimizes queue overshoot, where as
+'cc_cwnd_full_per_cwnd=1' and 'cc_cwnd_full_gap=1' is slightly better
+for performance. Since there may be a difference between Shadow and live,
+we leave this parmeterization in place.
+
+Here is the complete pseudocode for TOR_VEGAS with RFC3742, which is run every
+time an endpoint receives a SENDME ack. All variables are scoped to the
+circuit, unless prefixed by an underscore (local), or in single quotes
+(consensus parameters):
+
+ # Decrement counters that signal either an update or cwnd event
if next_cc_event:
next_cc_event--
+ if next_cwnd_event:
+ next_cwnd_event--
# Do not update anything if we detected a clock stall or jump,
# as per [CLOCK_HEURISTICS]
if clock_stalled_or_jumped:
+ inflight -= 'cc_sendme_inc'
return
+ if BDP > cwnd:
+ _queue_use = 0
+ else:
+ _queue_use = cwnd - BDP
+
+ if cwnd_is_full(cwnd, inflight):
+ cwnd_full = 1
+ else if cwnd_is_nonfull(cwnd, inflight):
+ cwnd_full = 0
+
+ if in_slow_start:
+ if _queue_use < 'cc_vegas_gamma' and not orconn_blocked:
+ # Only increase cwnd if the cwnd is full
+ if cwnd_full:
+ _inc = rfc3742_ss_inc(cwnd);
+ cwnd += _inc
+
+ # If the RFC3742 increment drops below steady-state increment
+ # over a full cwnd worth of acks, exit slow start.
+ if _inc*SENDME_PER_CWND(cwnd) <= 'cc_cwnd_inc'*'cc_cwnd_inc_rate':
+ in_slow_start = 0
+ else: # Limit hit. Exit Slow start (even if cwnd not full)
+ in_slow_start = 0
+ cwnd = BDP + 'cc_vegas_gamma'
+
+ # Provide an emergency hard-max on slow start:
+ if cwnd >= 'cc_ss_max':
+ cwnd = 'cc_ss_max'
+ in_slow_start = 0
+ else if next_cc_event == 0:
+ if _queue_use > 'cc_vegas_delta':
+ cwnd = BDP + 'cc_vegas_delta' - 'cc_cwnd_inc'
+ elif _queue_use > cc_vegas_beta or orconn_blocked:
+ cwnd -= 'cc_cwnd_inc'
+ elif cwnd_full and _queue_use < 'cc_vegas_alpha':
+ # Only increment if queue is low, *and* the cwnd is full
+ cwnd += 'cc_cwnd_inc'
+
+ cwnd = MAX(cwnd, 'cc_circwindow_min')
+
+ # Specify next cwnd and cc update
if next_cc_event == 0:
- if BDP > cwnd:
- queue_use = 0
- else:
- queue_use = cwnd - BDP
-
- if in_slow_start:
- if queue_use < cc_vegas_gamma and not orconn_blocked:
- # Increment by slow start %, or at least 2 sendme_inc's worth
- cwnd = cwnd + MAX(cwnd * cc_cwnd_inc_pct_ss, 2*cc_sendme_inc)
- # If our BDP estimator thinks the BDP is still larger, use that
- cwnd = MAX(cwnd, BDP)
- else:
- cwnd = BDP + cc_vegas_gamma
- in_slow_start = 0
- else:
- if queue_use > cc_vegas_delta:
- cwnd = BDP + cc_vegas_delta - cc_cwnd_inc
- elif queue_use > cc_vegas_beta or orconn_blocked:
- cwnd -= cc_cwnd_inc
- elif queue_use < cc_vegas_alpha:
- cwnd += cc_cwnd_inc
-
- cwnd = MAX(cwnd, cc_circwindow_min)
+ next_cc_event = CWND_UPDATE_RATE(cwnd)
+ if next_cwnd_event == 0:
+ next_cwnd_event = SENDME_PER_CWND(cwnd)
+
+ # Determine if we need to reset the cwnd_full state
+ # (Parameterized)
+ if 'cc_cwnd_full_per_cwnd' == 1:
+ if next_cwnd_event == SENDME_PER_CWND(cwnd):
+ cwnd_full = 0
+ else:
+ if next_cc_event == CWND_UPDATE_RATE(cwnd):
+ cwnd_full = 0
- # Count the number of sendme acks until next update of cwnd,
- # rounded to nearest integer
- if in_slow_start:
- next_cc_event = round(cwnd / cc_sendme_inc)
- else
- # Never increment faster in slow start, only steady state.
- next_cc_event = round(cwnd / (cc_cwnd_inc_rate * cc_sendme_inc))
+ # Update acked cells
+ inflight -= 'cc_sendme_inc'
3.4. Tor NOLA: Direct BDP tracker [TOR_NOLA]
@@ -715,6 +826,12 @@ struct xon_cell {
u32 kbps_ewma;
}
+Parties SHOULD treat XON or XOFF cells with unrecognized versions as a
+protocol violation.
+
+In `xon_cell`, a zero value for `kbps_ewma` means that the stream's rate is
+unlimited. Parties should therefore not send "0" to mean "do not send data".
+
4.1.1. XON/XOFF behavior
If the length of an edge outbuf queue exceeds the size provided in the
@@ -1071,7 +1188,7 @@ We will calibrate the Shadow simulator so that it has similar CDFs for all of
these metrics as the live network, without using congestion control.
Then, we will want to inspect CDFs of these three metrics for various
-congestion control algorithms and parameters.
+congestion control algorithms and parameters.
The live network testing will also spot-check performance characteristics of
a couple algorithm and parameter sets, to ensure we see similar results as
@@ -1103,7 +1220,7 @@ These are sorted in order of importance to tune, most important first.
- Description:
Specifies which congestion control algorithm clients should
use, as an integer.
- - Range: [0,3] (0=fixed, 1=Westwood, 2=Vegas, 3=NOLA)
+ - Range: 0 or 2 (0=fixed windows, 2=Vegas)
- Default: 2
- Tuning Values: [2,3]
- Tuning Notes:
@@ -1112,6 +1229,8 @@ These are sorted in order of importance to tune, most important first.
values, and even the optimal algorithm itself, will likely depend
upon how much fixed sendme traffic is in competition. See the
algorithm-specific parameters for additional tuning notes.
+ As of Tor 0.4.8, Vegas is the default algorithm, and support
+ for algorithms 1 (Westwood) and 3 (NOLA) have been removed.
- Shadow Tuning Results:
Westwood exhibited responsiveness problems, drift, and overshoot.
NOLA exhibited ack compression resulting in over-estimating the
@@ -1143,7 +1262,7 @@ These are sorted in order of importance to tune, most important first.
cc_sendme_inc:
- Description: Specifies how many cells a SENDME acks
- - Range: [1, 255]
+ - Range: [1, 254]
- Default: 31
- Tuning Values: 25,33,50
- Tuning Notes:
@@ -1157,7 +1276,7 @@ These are sorted in order of importance to tune, most important first.
cells that fit in a TLS frame. Much of the rest of Tor has
processing values at 32 cells, as well.
- Consensus Update Notes:
- This value MUST only be changed by a factor of 2, every 4 hours.
+ This value MUST only be changed by +/- 1, every 4 hours.
If greater changes are needed, they MUST be spread out over
multiple consensus updates.
@@ -1270,6 +1389,25 @@ These are sorted in order of importance to tune, most important first.
congestion, to avoid overloading slow relays. Values of 10 or 20
were best.
+ cc_ewma_ss:
+ - Description: This specifies the N in N_EWMA smoothing of RTT during
+ Slow Start.
+ - Range: [2, INT32_MAX]
+ - Default: 2
+ - Tuning Values: [2,4]
+ - Shadow Tuning Results:
+ Setting this to 2 helped reduce overshoot during Slow Start.
+
+ cc_rtt_reset_pct:
+ - Description: Describes a percentile average between RTT_min and
+ RTT_current_ewma, for use to reset RTT_min, when the
+ congestion window hits cwnd_min.
+ - Range: [0, 100]
+ - Default: 100
+ - Shadow Tuning Results:
+ cwnd_min is not hit in Shadow simulations, but it can be hit
+ on the live network while under DoS conditions, and with cheaters.
+
cc_cwnd_inc:
- Description: How much to increment the congestion window by during
steady state, every cwnd.
@@ -1299,14 +1437,6 @@ These are sorted in order of importance to tune, most important first.
allocation, though. Values of 50-100 will be explored after
examining Shadow Guard Relay Utilization.
- cc_bdp_alg:
- - Description: The BDP estimation algorithm to use.
- - Range: [0,7]
- - Default: 7 (Piecewise EWMA)
- - Tuning Notes:
- We don't expect to need to tune this.
- - Shadow Tuning Results:
- We leave this as-is, but disable it in Vegas instead, below.
6.5.2. Westwood parameters
@@ -1365,50 +1495,93 @@ These are sorted in order of importance to tune, most important first.
6.5.3. Vegas Parameters
- cc_vegas_alpha_{exit,onion,sos,vg,sbws}:
- cc_vegas_beta_{exit,onion,sos,vg,sbws}:
- cc_vegas_gamma_{exit,onion,sos,vg,sbws}:
- cc_vegas_delta_{exit,onion,sos,vg,sbws}:
+ cc_vegas_alpha_{exit,onion,sbws}:
+ cc_vegas_beta_{exit,onion,sbws}:
+ cc_vegas_gamma_{exit,onion,sbws}:
+ cc_vegas_delta_{exit,onion,sbws}:
- Description: These parameters govern the number of cells
that [TOR_VEGAS] can detect in queue before reacting.
- Range: [0, 1000] (except delta, which has max of INT32_MAX)
- Defaults:
- alpha: path_len*2*31-31
- beta: path_len*2*31
- gamma: path_len*2*31
- delta: path_len*2*31 + 2*31
+ # OUTBUF_CELLS=62
+ cc_vegas_alpha_exit (3*OUTBUF_CELLS)
+ cc_vegas_beta_exit (4*OUTBUF_CELLS)
+ cc_vegas_gamma_exit (3*OUTBUF_CELLS)
+ cc_vegas_delta_exit (5*OUTBUF_CELLS)
+ cc_vegas_alpha_onion (3*OUTBUF_CELLS)
+ cc_vegas_beta_onion (6*OUTBUF_CELLS)
+ cc_vegas_gamma_onion (4*OUTBUF_CELLS)
+ cc_vegas_delta_onion (7*OUTBUF_CELLS)
- Tuning Notes:
The amount of queued cells that Vegas should tolerate is heavily
dependent upon competing congestion control algorithms. The specified
defaults are necessary to compete against current fixed SENDME traffic,
- but are much larger than neccessary otherwise. As the number of
- clients using fixed windows is reduced (or circwindow is lowered), we
- can reduce these parameters, which will result in less overall queuing
- and congestion on the network.
+ but are much larger than neccessary otherwise. These values also
+ need a large-ish range between alpha and beta, to allow some degree of
+ variance in traffic, as per [33]. The tuning of these parameters
+ happened in two tickets[34,35]. The onion service parameters were
+ set on the basis that they should increase the queue until as much
+ queue delay as Exits, but tolerate up to 6 hops of outbuf delay.
+ Lack of visibility into onion service congestion window on the live
+ network prevented confirming this.
- Shadow Tuning Results:
We found that the best values for 3-hop Exit circuits was to set
- beta and gamma to the size of the outbufs times the number of hops.
- This has the effect that Vegas detects congestion and backs off
- when this much queue delay is detected. Alpha is set to one TLS
- record/sendme_inc below this value. If the queue length is detected
- to be below that, we increase the congestion window. We still
- need to verify that the path length multiplier still holds for
- other types of circuits, specifically onion services.
-
- cc_vegas_bdp_mix:
- - Description: This parameter allows us to specify a weighted percent
- average between the cwnd BDP estimator and the piecewise
- estimator.
- - Range: [0, 100]
- - Default: 100 (use 100% CWND estimator)
- - Tuning Notes:
- The original Vegas literature specified the CWND estimator, but
- the Piecewise estimator is very likely more suited for our use
- case. This parameter allows us to average them. We're unlikely to
- need it.
+ alpha and gamma to the size of the outbufs times the number of
+ hops. Beta is set to one TLS record/sendme_inc above this value.
+
+ cc_sscap_{exit,onion,sbws}:
+ - Description: These parameters describe the RFC3742 'cap', after which
+ congestion window increments are reduced. INT32_MAX disables
+ RFC3742.
+ - Range: [100, INT32_MAX]
+ - Defaults:
+ sbws: 400
+ exit: 600
+ onion: 475
- Shadow Tuning Results:
- Because the BDP estimator had ack compression and over-estimation,
- we the CWND estimator.
+ We picked these defaults based on the average congestion window
+ seen in Shadow sims for exits and onion service circuits.
+
+ cc_ss_max:
+ - Description: This parameter provides a hard-max on the congestion
+ window in slow start.
+ - Range: [500, INT32_MAX]
+ - Default: 5000
+ - Shadow Tuning Results:
+ The largest congestion window seen in Shadow is ~3000, so this was
+ set as a safety valve above that.
+
+ cc_cwnd_full_gap:
+ - Description: This parameter defines the integer number of
+ 'cc_sendme_inc' multiples of gap allowed between inflight and
+ cwnd, to still declare the cwnd full.
+ - Range: [0, INT16_MAX]
+ - Default: 4
+ - Shadow Tuning Results:
+ Low values resulted in a slight loss of performance, and increased
+ variance in throughput. Setting this at 4 seemed to achieve a good
+ balance betwen throughput and queue overshoot.
+
+ cc_cwnd_full_minpct:
+ - Description: This paramter defines a low watermark in percent. If
+ inflight falls below this percent of cwnd, the congestion window
+ is immediately declared non-full.
+ - Range: [0, 100]
+ - Default: 25
+
+ cc_cwnd_full_per_cwnd:
+ - Description: This parameter governs how often a cwnd must be
+ full, in order to allow congestion window increase. If it is 1,
+ then the cwnd only needs to be full once per cwnd worth of acks.
+ If it is 0, then it must be full once every cwnd update (ie:
+ every SENDME).
+ - Range: [0, 1]
+ - Default: 1
+ - Shadow Tuning Results:
+ A value of 0 resulted in a slight loss of performance, and increased
+ variance in throughput. The optimal number here likely depends on
+ edgeconn inbuf size, edgeconn kernel buffer size, and eventloop
+ behavior.
6.5.4. NOLA Parameters
@@ -1445,7 +1618,7 @@ These are sorted in order of importance to tune, most important first.
This threshold plus the sender's cwnd must be greater than the
cc_xon_rate value, or a rate cannot be computed. Unfortunately,
unless it is sent, the receiver does not know the cwnd. Therefore,
- this value should always be higher than cc_xon_rate minus
+ this value should always be higher than cc_xon_rate minus
'cc_cwnd_min' (100) minus the xon threshhold value (0).
cc_xon_rate
@@ -1483,7 +1656,7 @@ These are sorted in order of importance to tune, most important first.
- Tuning Notes:
Setting this higher will smooth over changes in the rate field,
and thus avoid XONs, but will reduce our reactivity to rate changes.
-
+
6.5.6. External Performance Parameters to Tune
@@ -1495,7 +1668,7 @@ These are sorted in order of importance to tune, most important first.
- Description: Specifies the percentage cutoff for the circuit build
timeout mechanism.
- Range: [60, 80]
- - Default: 80
+ - Default: 80
- Tuning Values: [70, 75, 80]
- Tuning Notes:
The circuit build timeout code causes Tor to use only the fastest
@@ -1976,7 +2149,7 @@ The client MUST reject an ntorv3 reply with field EXT_FIELD_TYPE=02, if the
client did not include EXT_FIELD_TYPE=01 in its handshake.
The client SHOULD reject a sendme_inc field value that differs from the
-current 'cc_sendme_inc' consensus parameter by more than a factor of 2, in
+current 'cc_sendme_inc' consensus parameter by more than +/- 1, in
either direction.
If a client rejects a handshake, it MUST close the circuit.
@@ -1987,8 +2160,7 @@ The pedantic reader will note that a rogue consensus can cause all clients
to decide to close circuits by changing 'cc_sendme_inc' by a large margin.
As a matter of policy, the directory authorities MUST NOT change
-'cc_sendme_inc' by more than a factor of two (2), within a four (4) hour
-window, for this reason.
+'cc_sendme_inc' by more than +/- 1.
In Shadow simulation, the optimal 'cc_sendme_inc' value to be ~31 cells, or
one (1) TLS record worth of cells. We do not expect to change this value
@@ -2133,3 +2305,13 @@ receive more data. It is sent to tell the sender to resume sending.
31. KIST: Kernel-Informed Socket Transport for Tor
https://matt.traudt.xyz/static/papers/kist-tops2018.pdf
+
+32. RFC3742 Limited Slow Start
+ https://datatracker.ietf.org/doc/html/rfc3742#section-2
+
+33. https://people.csail.mit.edu/venkatar/cc-starvation.pdf
+
+34. https://gitlab.torproject.org/tpo/core/tor/-/issues/40642
+
+35. https://gitlab.torproject.org/tpo/network-health/analysis/-/issues/49
+```
diff --git a/proposals/325-packed-relay-cells.md b/proposals/325-packed-relay-cells.md
index 6498d4c..7d0ffca 100644
--- a/proposals/325-packed-relay-cells.md
+++ b/proposals/325-packed-relay-cells.md
@@ -3,9 +3,11 @@ Filename: 325-packed-relay-cells.md
Title: Packed relay cells: saving space on small commands
Author: Nick Mathewson
Created: 10 July 2020
-Status: Open
+Status: Obsolete
```
+(Proposal superseded by proposal 340)
+
# Introduction
In proposal 319 I suggested a way to fragment long commands across
@@ -55,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
@@ -121,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
@@ -148,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 4f13835..8bc705a 100644
--- a/proposals/326-tor-relay-well-known-uri-rfc8615.md
+++ b/proposals/326-tor-relay-well-known-uri-rfc8615.md
@@ -1,6 +1,6 @@
```
Filename: 326-tor-relay-well-known-uri-rfc8615.md
-Title: The "tor-relay" Well-Known Resource Identifier
+Title: The "tor-relay" Well-Known Resource Identifier
Author: nusenu
Created: 14 August 2020
Status: Open
@@ -10,22 +10,23 @@ Status: Open
This is a specification for a well-known [registry](https://www.iana.org/assignments/well-known-uris/) entry according to [RFC8615](https://tools.ietf.org/html/rfc8615).
-This resource identifier can be used for serving and finding proofs related to [Tor](https://www.torproject.org/) relay contact information.
-It can also be used for autodiscovery of Tor relays run by a given entity, if the entity domain is known.
-It solves the issue that Tor relay contact information is an unidirectional and unverified claim by nature.
+This resource identifier can be used for serving and finding proofs related to [Tor](https://www.torproject.org/) relay and bridge contact information.
+It can also be used for autodiscovery of Tor relays run by a given entity, if the entity's domain is known.
+It solves the issue that Tor relay/bridge contact information is a unidirectional and unverified claim by nature.
This well-known URI aims to allow the verification of the unidirectional claim.
-It aims to reduce the risk of impersonation attacks, where a Tor relay claims to be operated by a certain entity, but actually isn't.
-The automated verification will also support the [visualization of relay groups](https://gitlab.torproject.org/tpo/metrics/relay-search/-/issues/40001).
+It aims to reduce the risk of impersonation attacks, where a Tor relay/bridge claims to be operated by a certain entity, but actually isn't.
+The automated verification will also support the [visualization of relay/bridge groups](https://gitlab.torproject.org/tpo/metrics/relay-search/-/issues/40001).
-* An initially (unverified) Tor relay contact information might claim to be related to an
-organization by pointing to its website: Tor relay contact information field -> website
-* The "tor-relay" URI allows for the verification of that claim by fetching the files containing Tor relay ID(s) under the specified URI,
-because attackers can not easily place these files at the given location.
+* An initially (unverified) Tor relay or bridge contact information might claim to be related to an
+organization by pointing to its website: Tor relay/bridge contact information field -> website
+* The "tor-relay" URI allows for the verification of that claim by fetching the files containing Tor relay ID(s) or hashed bridge fingerprints
+under the specified URI, because attackers can not easily place these files at the given location.
-* By publishing Tor relay IDs under this URI the website operator claims to be the responsible entity for these Tor relays.
-The verification of listed Tor relay IDs only succeeds if the claim can be verified bidirectionally (website -> relay and relay -> website).
+* By publishing Tor relay IDs or hashed bridge IDs under this URI the website operator claims to be the responsible entity for these Tor relays/bridges.
+The verification of listed Tor relay/bridge IDs only succeeds if the claim can be verified bidirectionally
+(website -> relay/bridge and relay/bridge -> website).
-* This URI is not related to Tor bridges or Tor onion services.
+* This URI is not related to Tor onion services.
* The URL MUST be HTTPS and use a valid TLS certificate from a generally trusted root CA. Plain HTTP MUST not be used.
@@ -34,13 +35,13 @@ The verification of listed Tor relay IDs only succeeds if the claim can be verif
## /.well-known/tor-relay/rsa-fingerprint.txt
* The file contains one or more Tor relay RSA SHA1 fingerprints operated by the entity in control of this website.
-* Each line contains one fingerprint.
+* 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.
-* The file MUST NOT contain fingerprints of Tor bridges (or hashes of bridge fingerprints).
* The content MUST be a media type of "text/plain".
Example file content:
@@ -55,9 +56,10 @@ The RSA SHA1 relay fingerprint can be found in the file named "fingerprint" loca
## /.well-known/tor-relay/ed25519-master-pubkey.txt
* The file contains one or more ed25519 Tor relay public master keys of relays operated by the entity in control of this website.
+* 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".
@@ -73,6 +75,27 @@ bHzOT41w56KHh+w6TYwUhN4KrGwPWQWJX04/+tw/+RU
The base64 encoded ed25519 public master key can be found in the file named "fingerprint-ed25519" located in the Tor data directory on the relay.
+## /.well-known/tor-relay/hashed-bridge-rsa-fingerprint.txt
+
+* 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]`.
+* Hashed fingerprints are not case-sensitive.
+* Each hashed fingerprint MUST appear at most once.
+* The file MUST not be larger than one MByte.
+* The file MUST NOT contain fingerprints of Tor relays.
+* The content MUST be a media type of "text/plain".
+
+Example file content:
+
+```
+# we operate these Tor bridges
+1234567890123456789012345678901234567ABC
+4234567890123456789012345678901234567890
+```
+
+The hashed Tor bridge fingerprint can be found in the file named "hashed-fingerprint" located in the Tor data directory on the bridge.
# Change Controller
diff --git a/proposals/327-pow-over-intro.txt b/proposals/327-pow-over-intro.txt
index fb58a7d..d267d3c 100644
--- a/proposals/327-pow-over-intro.txt
+++ b/proposals/327-pow-over-intro.txt
@@ -1,8 +1,9 @@
+```
Filename: 327-pow-over-intro.txt
Title: A First Take at PoW Over Introduction Circuits
Author: George Kadianakis, Mike Perry, David Goulet, tevador
Created: 2 April 2020
-Status: Draft
+Status: Closed
0. Abstract
@@ -13,12 +14,11 @@ Status: Draft
So far our attempts at limiting the impact of introduction flooding DoS
attacks on onion services has been focused on horizontal scaling with
- Onionbalance, optimizing the CPU usage of Tor and applying congestion control
- using rate limiting. While these measures move the goalpost forward, a core
- problem with onion service DoS is that building rendezvous circuits is a
- costly procedure both for the service and for the network. For more
- information on the limitations of rate-limiting when defending against DDoS,
- see [REF_TLS_1].
+ 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 [REF_TLS_1].
If we ever hope to have truly reachable global onion services, we need to
make it harder for attackers to overload the service with introduction
@@ -41,7 +41,7 @@ Status: Draft
This proposal is written to thwart specific attackers. A simple PoW proposal
cannot defend against all and every DoS attack on the Internet, but there are
- adverary models we can defend against.
+ adversary models we can defend against.
Let's start with some adversary profiles:
@@ -49,26 +49,26 @@ Status: Draft
The script-kiddie has a single computer and pushes it to its
limits. Perhaps it also has a VPS and a pwned server. We are talking about
- an attacker with total access to 10 Ghz of CPU and 10 GBs of RAM. We
+ 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.
+ 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
+ talking about an attacker with total access to 200 THz of CPU and 200 TB of
RAM. The upfront cost for this attacker is about $36k.
We hope that this proposal can help us defend against the script-kiddie
attacker and small botnets. To defend against a large botnet we would need
- more tools in our disposal (see [FUTURE_DESIGNS]).
+ more tools at our disposal (see [FUTURE_DESIGNS]).
1.2.2. User profiles [USER_MODEL]
@@ -78,16 +78,15 @@ Status: Draft
This is a standard laptop/desktop user who is trying to browse the
web. They don't know how these defences work and they don't care to
- configure or tweak them. They are gonna use the default values and if the
- site doesn't load, they are gonna close their browser and be sad at Tor.
- They run a 2Ghz computer with 4GB of RAM.
+ 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 tweak the default values and make their computer do
- expensive multi-minute PoW computations to get where they want to be.
+ on; they are willing to make their computer do expensive multi-minute PoW
+ computations to get where they want to be.
"The mobile user"
@@ -104,8 +103,8 @@ Status: Draft
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
+ 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.
@@ -135,33 +134,73 @@ Status: Draft
introduction phase of the onion service protocol.
The system described in this proposal is not meant to be on all the time, and
- should only be enabled by services when under duress. The percentage of
- clients receiving puzzles can also be configured based on the load of the
- service.
+ it can be entirely disabled for services that do not experience DoS attacks.
- In summary, the following steps are taken for the protocol to complete:
+ 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 [DESC_POW]
2) Client fetches descriptor and computes PoW [CLIENT_POW]
3) Client completes PoW and sends results in INTRO1 cell [INTRO1_POW]
- 4) Service verifies PoW and queues introduction based on PoW effort [SERVICE_VERIFY]
+ 4) Service verifies PoW and queues introduction based on PoW effort
+ [SERVICE_VERIFY]
+ 5) Requests are continuously drained from the queue, highest effort first,
+ subject to multiple constraints on speed [HANDLE_QUEUE]
2.2. Proof-of-work overview
-2.2.1. Primitives
-
- For our proof-of-work function we will use the 'equix' scheme by tevador
- [REF_EQUIX]. Equix is an assymetric PoW function based on Equihash<60,3>. It
- features lightning fast verification speed, and also aims to minimize the
- assymetry between CPU and GPU. Furthermore, it's designed for this particular
- use-case and hence cryptocurrency miners are not incentivized to make
- optimized ASICs for it.
-
- The Equix scheme provides two functions that will be used in this proposal:
- - equix_solve(seed, nonce, effort) which solves a puzzle instance.
- - equix_verify(seed, nonce, effort, solution) which verifies a puzzle solution.
-
- We tune equix in section [EQUIX_TUNING].
+2.2.1. Algorithm overview
+
+ For our proof-of-work function we will use the Equi-X scheme by tevador
+ [REF_EQUIX]. 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.
+
+ 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) Above the level of individual PoW handshakes, the client and service
+ form a closed-loop system that adjusts the effort of future handshakes.
+
+ The Equi-X scheme 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.
+
+ We tune Equi-X in section [EQUIX_TUNING].
2.2.2. Dynamic PoW
@@ -184,21 +223,31 @@ Status: Draft
2.2.3. PoW effort
- For our dynamic PoW system to work, we will need to be able to compare PoW
- tokens with each other. To do so we define a function:
+ 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 estimation system, it's quite useful if we
+ instead have a linear scale. We use the first 32 bits of a hashed version
+ of the Equi-X solution as compared to the full 32-bit range.
+
+ Conceptually we could define a function:
unsigned effort(uint8_t *token)
- which takes as its argument a hash output token, interprets it as a
+ 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:
- effort(00000001100010101101) = 11111111111111111111 / 00000001100010101101
+ effort(00000001100010101101) = 11111111111111111111
+ / 00000001100010101101
or the same in decimal:
effort(6317) = 1048575 / 6317 = 165.
- This definition of effort has the advantage of directly expressing the
- expected number of hashes that the client had to calculate to reach the
- effort. This is in contrast to the (cheaper) exponential effort definition of
- taking the number of leading zero bits.
+ 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.
3. Protocol specification
@@ -207,7 +256,8 @@ Status: Draft
This whole protocol starts with the service encoding the PoW parameters in
the 'encrypted' (inner) part of the v3 descriptor. As follows:
- "pow-params" SP type SP seed-b64 SP expiration-time NL
+ "pow-params" SP type SP seed-b64 SP suggested-effort
+ SP expiration-time NL
[At most once]
@@ -218,14 +268,16 @@ Status: Draft
without trailing padding.
suggested-effort: An unsigned integer specifying an effort value that
- clients should aim for when contacting the service. See
+ 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. See
[EFFORT_ESTIMATION] for more details here.
- expiration-time: A timestamp in "YYYY-MM-DD SP HH:MM:SS" format after
- which the above seed expires and is no longer valid as
- the input for PoW. It's needed so that the size of our
- replay cache does not grow infinitely. It should be
- set to RAND_TIME(now+7200, 900) seconds.
+ 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. It's needed
+ so that our replay cache does not grow infinitely. It
+ should be set to RAND_TIME(now+7200, 900) seconds.
The service should refresh its seed when expiration-time passes. The service
SHOULD keep its previous seed in memory and accept PoWs using it to avoid
@@ -239,7 +291,8 @@ Status: Draft
3.2. Client fetches descriptor and computes PoW [CLIENT_POW]
If a client receives a descriptor with "pow-params", it should assume that
- the service is expecting a PoW input as part of the introduction protocol.
+ the 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 and if it has, it needs to
@@ -247,25 +300,44 @@ Status: Draft
The client should then extract the <suggested-effort> field to configure its
PoW 'target' (see [REF_TARGET]). The client SHOULD NOT accept 'target' values
- that will cause an infinite PoW computation. {XXX: How to enforce this?}
+ that will cause unacceptably long PoW computation.
+
+ The client uses a "personalization string" P equal to the following
+ nul-terminated ASCII string: "Tor hs intro v1\0".
+
+ The client looks up `ID`, the current 32-byte blinded public ID
+ (KP_hs_blind_id) for the onion service.
To complete the PoW the client follows the following logic:
- a) Client selects a target effort E.
- b) Client generates a random 16-byte nonce N.
+ a) Client selects a target effort E, based on <suggested-effort> and past
+ connection attempt history.
+ b) Client generates a secure random 16-byte nonce N, as the starting
+ point for the solution search.
c) Client derives seed C by decoding 'seed-b64'.
- d) Client calculates S = equix_solve(C || N || E)
- e) Client calculates R = blake2b(C || N || E || S)
+ d) Client calculates S = equix_solve(P || ID || C || N || E)
+ e) Client calculates R = ntohl(blake2b_32(P || ID || C || N || E || S))
f) Client checks if R * E <= UINT32_MAX.
- f1) If yes, success! The client can submit N, E, the first 4 bytes of C
- and S.
+ f1) If yes, success! The client can submit N, E, the first 4 bytes of
+ C, and S.
f2) If no, fail! The client interprets N as a 16-byte little-endian
- integer, increments it by 1 and goes back to step d).
+ integer, increments it by 1 and goes back to step d).
+
+ 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 S as the solution
- of the Equix puzzle with N as the nonce, C as the seed. How quickly this
+ of the Equix-X puzzle with N as the nonce, C as the seed. How quickly this
happens depends solely on 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.
+
3.3. Client sends PoW in INTRO1 cell [INTRO1_POW]
Now that the client has an answer to the puzzle it's time to encode it into
@@ -277,7 +349,7 @@ Status: Draft
We propose a new EXT_FIELD_TYPE value:
- [01] -- PROOF_OF_WORK
+ [02] -- PROOF_OF_WORK
The EXT_FIELD content format is:
@@ -291,6 +363,7 @@ Status: Draft
POW_VERSION is 1 for the protocol specified in this proposal
POW_NONCE is the nonce 'N' from the section above
+ POW_EFFORT is the 32-bit integer effort value, in network byte order
POW_SEED is the first 4 bytes of the seed used
This will increase the INTRODUCE1 payload size by 43 bytes since the
@@ -302,10 +375,10 @@ Status: Draft
3.4. Service verifies PoW and handles the introduction [SERVICE_VERIFY]
When a service receives an INTRODUCE1 with the PROOF_OF_WORK extension, it
- should check its configuration on whether proof-of-work is required to
- complete the introduction. If it's not required, the extension SHOULD BE
- ignored. If it is required, the service follows the procedure detailed in
- this section.
+ 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
@@ -318,12 +391,12 @@ Status: Draft
a) Find a valid seed C that starts with POW_SEED. Fail if no such seed
exists.
- b) Fail if E = POW_EFFORT is lower than the minimum effort.
- c) Fail if N = POW_NONCE is present in the replay cache (see [REPLAY_PROTECTION[)
- d) Calculate R = blake2b(C || N || E || S)
- e) Fail if R * E > UINT32_MAX
- f) Fail if equix_verify(C || N || E, S) != EQUIX_OK
- g) Put the request in the queue with a priority of E
+ b) Fail if N = POW_NONCE is present in the replay cache
+ (see [REPLAY_PROTECTION])
+ c) Calculate R = ntohl(blake2b_32(P || ID || C || N || E || S))
+ d) Fail if R * E > UINT32_MAX
+ e) Fail if equix_verify(P || ID || C || N || E, S) != EQUIX_OK
+ f) Put the request in the queue with a priority of E
If any of these steps fail the service MUST ignore this introduction request
and abort the protocol.
@@ -338,7 +411,7 @@ Status: Draft
tuple. For this reason a replay protection mechanism must be employed.
The simplest way is to use a simple hash table to check whether a (seed,
- nonce) tuple has been used before for the actiev duration of a
+ 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.
@@ -348,7 +421,9 @@ Status: Draft
will flag some connections as replays even if they are not; with this false
positive probability increasing as the number of entries increase. However,
with the right parameter tuning this probability should be negligible and
- well handled by clients. {TODO: Figure bloom filter}
+ well handled by clients.
+
+ {TODO: Design and specify a suitable bloom filter for this purpose.}
3.4.2. The Introduction Queue [INTRO_QUEUE]
@@ -364,11 +439,11 @@ Status: Draft
structure. Each element in that priority queue is an introduction request,
and its priority is the effort put into its PoW:
- When a verified introduction comes through, the service uses the effort()
- function with the solution S as its input, and uses the output to place requests
- into the right position of the priority_queue: The bigger the effort, the
- more priority it gets in the queue. If two elements have the same effort, the
- older one has priority over the newer one.
+ When a verified introduction comes through, the service uses its included
+ effort commitment value to place each request into the right position of the
+ priority_queue: The bigger the effort, the more priority it gets in the
+ queue. If two elements have the same effort, the older one has priority over
+ the newer one.
3.4.2.2. Handling introductions from the introduction queue [HANDLE_QUEUE]
@@ -379,43 +454,103 @@ Status: Draft
3.4.3. PoW effort estimation [EFFORT_ESTIMATION]
- The service starts with a default suggested-effort value of 5000 (see
- [EQUIX_DIFFICULTY] section for more info).
+3.4.3.1. High-level description of the effort estimation process
+
+ The service starts with a default suggested-effort value of 0, which keeps
+ the PoW defenses dormant until we notice signs of overload.
+
+ The overall process of determining effort can be thought of as a set of
+ multiple coupled feedback loops. Clients perform their own effort
+ adjustments via [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 [CLIENT_TIMEOUT],
+ later clients will benefit from the service detecting this increased queued
+ effort and offering a larger suggested_effort.
+
+ Effort increases and decreases both have an intrinsic 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.
+
+3.4.3.2. Service-side effort estimation
+
+ Services keep an internal effort estimation which updates on a regular
+ periodic timer in response to measurements made on the queueing behavior
+ in the previous period. These internal effort changes can optionally trigger
+ client-visible suggested_effort changes when the difference is great enough
+ to warrant republishing to the HSDir.
+
+ This evaluation and update period is referred to as HS_UPDATE_PERIOD.
+ The service side effort estimation 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?}
+
+3.4.3.3. Per-period service state
+
+ During each update period, the service maintains some state:
- Then during its operation the service continuously keeps track of the
- received PoW cell efforts to inform its clients of the effort they should put
- in their introduction to get service. The service informs the clients by
- using the <suggested-effort> field in the descriptor.
+ 1. TOTAL_EFFORT, a sum of all effort values for rendezvous requests that
+ were successfully validated and enqueued.
- Everytime the service handles or trims an introduction request from the
- priority queue in [HANDLE_QUEUE], the service adds the request's effort to a
- sorted list.
+ 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.
- Then every HS_UPDATE_PERIOD seconds (which is controlled through a consensus
- parameter and has a default value of 300 seconds) and while the DoS feature
- is enabled, the service updates its <suggested-effort> value as follows:
+ 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.
- 1. Set TOTAL_EFFORT to the sum of the effort of all valid requests that
- have been received since the last HS descriptor update (this includes
- all handled requests, trimmed requests and requests still in the queue)
+ 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.
- 2. Set SUGGESTED_EFFORT = TOTAL_EFFORT / (SVC_BOTTOM_CAPACITY * HS_UPDATE_PERIOD).
- The denominator above is the max number of requests that the service
- could have handled during that time.
+3.4.3.4. Service AIMD conditions
- 3. Set <suggested-effort> to max(MIN_EFFORT, SUGGESTED_EFFORT).
+ 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:
- During the above procedure we use the following default values:
- - MIN_EFFORT = 1000, as the result of a simulation experiment [REF_TEVADOR_SIM]
- - SVC_BOTTOM_CAPACITY = 100, which is the number of introduction requests
- that can be handled by the service per second. This was computed in
- [POW_DIFFICULTY_TOR] as 180, but we reduced it to 100 to account for
- slower computers and networks.
+ 1. If MAX_TRIMMED_EFFORT > our previous internal suggested_effort,
+ always INCREASE. Requests that follow our latest advice are being
+ dropped.
- The above algorithm is meant to balance the suggested effort based on the
- effort of all received requests. It attempts to dynamically adjust the
- suggested effort so that it increases when an attack is received, and tones
- down when the attack has stopped.
+ 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 the 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
@@ -423,33 +558,17 @@ Status: Draft
to the service. The service still adds requests with lower effort than
suggested-effort to the priority queue in [ADD_QUEUE].
- Finally, the above algorithm will never reset back to zero suggested-effort,
- even if the attack is completely over. That's because in that case it would
- be impossible to determine the total computing power of connecting
- clients. Instead it will reset back to MIN_EFFORT, and the operator will have
- to manually shut down the anti-DoS mechanism.
-
- {XXX: SVC_BOTTOM_CAPACITY is static above and will not be accurate for all
- boxes. Ideally we should calculate SVC_BOTTOM_CAPACITY dynamically based on
- the resources of every onion service while the algorithm is running.}
+3.4.3.5. Updating descriptor with new suggested effort
-3.4.3.1. Updating descriptor with new suggested effort
+ The service descriptors may be updated for multiple reasons including
+ introduction point rotation common to all v3 onion services, the scheduled
+ seed rotations described in [DESC_POW], and updates to the effort suggestion.
+ Even though the internal effort estimate updates on a regular timer, we avoid
+ propagating those changes into the descriptor and the HSDir hosts unless
+ there is a significant change.
- Every HS_UPDATE_PERIOD seconds the service should upload a new descriptor
- with a new suggested-effort value.
-
- The service should avoid uploading descriptors too often to avoid overwheming
- the HSDirs. The service SHOULD NOT upload descriptors more often than
- HS_UPDATE_PERIOD. The service SHOULD NOT upload a new descriptor if the
- suggested-effort value changes by less than 15%.
-
- {XXX: Is this too often? Perhaps we can set different limits for when the
- difficulty goes up and different for when it goes down. It's more important
- to update the descriptor when the difficulty goes up.}
-
- {XXX: What attacks are possible here? Can the attacker intentionally hit this
- rate-limit and then influence the suggested effort so that clients do not
- learn about the new effort?}
+ If the PoW params otherwise match but the seed has changed by less than 15
+ percent, services SHOULD NOT upload a new descriptor.
4. Client behavior [CLIENT_BEHAVIOR]
@@ -462,8 +581,10 @@ Status: Draft
not allow the service to inform the client that the rendezvous is never gonna
occur.
- For this reason we need to define some client behaviors to work around these
- issues.
+ 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. Existing mechanisms
+ will discard an introduction point that's required too many retries.
4.1. Clients handling timeouts [CLIENT_TIMEOUT]
@@ -476,31 +597,35 @@ Status: Draft
If the rendezvous request times out, the client SHOULD fetch a new descriptor
for the service to make sure that it's using the right suggested-effort for
- the PoW and the right PoW seed. The client SHOULD NOT fetch service
- descriptors more often than every 'hs-pow-desc-fetch-rate-limit' seconds
- (which is controlled through a consensus parameter and has a default value of
- 600 seconds).
+ 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.
- {XXX: Is this too rare? Too often?}
+ On each retry, the client modifies its solver effort:
- When the client fetches a new descriptor, it should try connecting to the
- service with the new suggested-effort and PoW seed. If that doesn't work, it
- should double the effort and retry. The client should keep on
- doubling-and-retrying until it manages to get service, or its able to fetch a
- new descriptor again.
+ 1. If the effort is below (CLIENT_POW_EFFORT_DOUBLE_UNTIL = 1000)
+ it will be doubled.
- {XXX: This means that the client will keep on spinning and
- doubling-and-retrying for a service under this situation. There will never be
- a "Client connection timed out" page for the user. Is this good? Is this bad?
- Should we stop doubling-and-retrying after some iterations? Or should we
- throw a custom error page to the user, and ask the user to stop spinning
- whenever they want?}
+ 2. Otherwise, multiply the effort by (CLIENT_POW_RETRY_MULTIPLIER = 1.5).
-4.3. Other descriptor issues
+ 3. Constrain the new effort to be at least
+ (CLIENT_MIN_RETRY_POW_EFFORT = 8) and no greater than
+ (CLIENT_MAX_POW_EFFORT = 10000)
- Another race condition here is if the service enables PoW, while a client has
- a cached descriptor. How will the client notice that PoW is needed? Does it
- need to fetch a new descriptor? Should there be another feedback mechanism?
+ {TODO: These hardcoded limits should be replaced by timed limits and/or
+ an unlimited solver with robust cancellation. This is issue tor#40787}
5. Attacker strategies [ATTACK_META]
@@ -519,7 +644,8 @@ Status: Draft
that this attack is not possible: we tune this PoW parameter in section
[POW_TUNING_VERIFICATION].
-5.1.2. Overwhelm rendezvous capacity (aka "Overwhelm bottom half") [ATTACK_BOTTOM_HALF]
+5.1.2. Overwhelm rendezvous capacity (aka "Overwhelm bottom half")
+ [ATTACK_BOTTOM_HALF]
Given the way the introduction queue works (see [HANDLE_QUEUE]), a very
effective strategy for the attacker is to totally overwhelm the queue
@@ -557,7 +683,7 @@ Status: Draft
5.1.4. Gaming the effort estimation logic [ATTACK_EFFORT]
Another way to beat this system is for the attacker to game the effort
- estimation logic (see [EFFORT_ESTIMATION]). Essentialy, there are two attacks
+ estimation logic (see [EFFORT_ESTIMATION]). Essentially, there are two attacks
that we are trying to avoid:
- Attacker sets descriptor suggested-effort to a very high value effectively
@@ -587,14 +713,20 @@ Status: Draft
turn into a DoS vector of its own. We will do this tuning in a way that's
agnostic to the chosen PoW function.
- We will then move towards analyzing the default difficulty setting for our
- PoW system. That defines the expected time for clients to succeed in our
- system, and the expected time for attackers to overwhelm our system. Same as
- above we will do this in a way that's agnostic to the chosen PoW function.
+ We will then move towards analyzing the client starting difficulty setting
+ for our PoW system. That defines the expected time for clients to succeed in
+ our system, and the expected time for attackers to overwhelm our system. Same
+ as above we will do this in a way that's agnostic to the chosen PoW function.
+
+ Currently, we have hardcoded the initial client starting difficulty at 8,
+ but this may be too low to ramp up quickly to various on and off attack
+ patterns. A higher initial difficulty may be needed for these, depending on
+ their severity. This section gives us an idea of how large such attacks can
+ be.
Finally, using those two pieces we will tune our PoW function and pick the
- right default difficulty setting. At the end of this section we will know the
- resources that an attacker needs to overwhelm the onion service, the
+ right client starting difficulty setting. At the end of this section we will
+ know the resources that an attacker needs to overwhelm the onion service, the
resources that the service needs to verify introduction requests, and the
resources that legitimate clients need to get to the onion service.
@@ -603,7 +735,7 @@ Status: Draft
Verifying a PoW token is the first thing that a service does when it receives
an INTRODUCE2 cell and it's detailed in section [POW_VERIFY]. This
verification happens during the "top half" part of the process. Every
- milisecond spent verifying PoW adds overhead to the already existing "top
+ millisecond spent verifying PoW adds overhead to the already existing "top
half" part of handling an introduction cell. Hence we should be careful to
add minimal overhead here so that we don't enable attacks like [ATTACK_TOP_HALF].
@@ -665,17 +797,17 @@ Status: Draft
The difficulty setting of our PoW basically dictates how difficult it should
be to get a success in our PoW system. An attacker who can get many successes
- per second can pull a successfull [ATTACK_BOTTOM_HALF] attack against our
+ per second can pull a successful [ATTACK_BOTTOM_HALF] attack against our
system.
In classic PoW systems, "success" is defined as getting a hash output below
the "target". However, since our system is dynamic, we define "success" as an
abstract high-effort computation.
- Our system is dynamic but we still need a default difficulty settings that
- will define the metagame and be used for bootstrapping the system. The client
- and attacker can still aim higher or lower but for UX purposes and for
- analysis purposes we do need to define a default difficulty.
+ Our system is dynamic but 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 we do need
+ to define a starting difficulty, to minimize retries by clients.
6.2.1. Analysis based on adversary power
@@ -729,16 +861,13 @@ Status: Draft
successes per second, then a legitimate client with a single box should be
expected to spend 1 seconds getting a single success.
- With the above table we can create some profiles for default values of our
- PoW difficulty. So for example, we can use the last case as the default
- parameter for Tor Browser, and then create three more profiles for more
- expensive cases, scaling up to the first case which could be hardest since
- the client is expected to spend 15 minutes for a single introduction.
+ With the above table we can create some profiles for starting values of our
+ PoW difficulty.
6.2.2. Analysis based on Tor's performance [POW_DIFFICULTY_TOR]
To go deeper here, we can use the performance measurements from
- [TOR_MEASUREMENTS] to get a more specific intuition on the default
+ [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
@@ -771,7 +900,7 @@ Status: Draft
64 high-effort introduction cells per second to succeed in a
[ATTACK_BOTTOM_HALF] attack.
- We can use this table to specify a default difficulty that won't allow our
+ We can use this table to specify a starting difficulty that won't allow our
target adversary to succeed in an [ATTACK_BOTTOM_HALF] attack.
Of course, when it comes to this table, the same disclaimer as in section
@@ -780,26 +909,6 @@ Status: Draft
since they depend on auxiliary processing overheads, and on the network's
capacity.
-6.3. Tuning equix difficulty [EQUIX_DIFFICULTY]
-
- The above two sections were not depending on a particular PoW scheme. They
- gave us an intuition on the values we are aiming for in terms of verification
- speed and PoW difficulty. Now we need to make things concrete:
-
- As described in section [EFFORT_ESTIMATION] we start the service with a
- default suggested-effort value of 5000. Given the benchmarks of EquiX
- [REF_EQUIX] this should take about 2 to 3 seconds on a modern CPU.
-
- With this default difficulty setting and given the table in
- [POW_DIFFICULTY_ANALYSIS] this means that an attacker with 50 boxes will be
- able to get about 20 successful PoWs per second, and an attacker with 100
- boxes about 40 successful PoWs per second.
-
- Then using the table in [POW_DIFFICULTY_TOR] we can see that the number of
- attacker's successes is not enough to overwhelm the service through an
- [ATTACK_BOTTOM_HALF] attack. That is, an attacker would need to do about 152
- introductions per second to overwhelm the service, whereas they can only do
- 40 with 100 boxes.
7. Discussion
@@ -807,35 +916,13 @@ Status: Draft
This proposal has user facing UX consequences.
- Here is some UX improvements that don't need user-input:
-
- - Primarily, there should be a way for Tor Browser to display to users that
- additional time (and resources) will be needed to access a service that is
- under attack. Depending on the design of the system, it might even be
- possible to estimate how much time it will take.
-
- And here are a few UX approaches that will need user-input and have an
- increasing engineering difficulty. Ideally this proposal will not need
- user-input and the default behavior should work for almost all cases.
-
- a) Tor Browser needs a "range field" which the user can use to specify how
- much effort they want to spend in PoW if this ever occurs while they are
- browsing. The ranges could be from "Easy" to "Difficult", or we could try
- to estimate time using an average computer. This setting is in the Tor
- Browser settings and users need to find it.
-
- b) We start with a default effort setting, and then we use the new onion
- errors (see #19251) to estimate when an onion service connection has
- failed because of DoS, and only then we present the user a "range field"
- which they can set dynamically. Detecting when an onion service connection
- has failed because of DoS can be hard because of the lack of feedback (see
- [CLIENT_BEHAVIOR])
-
- c) We start with a default effort setting, and if things fail we
- automatically try to figure out an effort setting that will work for the
- user by doing some trial-and-error connections with different effort
- values. Until the connection succeeds we present a "Service is
- overwhelmed, please wait" message to the user.
+ 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.
7.2. Future work [FUTURE_WORK]
@@ -850,7 +937,7 @@ Status: Draft
This proposal suffers from various UX issues because there is no end-to-end
mechanism for an onion service to inform the client about its introduction
request. If we had end-to-end introduction ACKs many of the problems from
- [CLIENT_BEHAVIOR] would be aleviated. The problem here is that end-to-end
+ [CLIENT_BEHAVIOR] 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.
@@ -863,7 +950,7 @@ Status: Draft
7.2.2. Future designs [FUTURE_DESIGNS]
This is just the beginning in DoS defences for Tor and there are various
- futured designs and schemes that we can investigate. Here is a brief summary
+ 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
@@ -1090,7 +1177,7 @@ A.4.1 Tor measurements [TOR_MEASUREMENTS]
There is an average of 2.42 INTRODUCE2 cells per mainloop event and so we
divide that by the full mainloop event mean time to get the time for one
- cell. From that we substract the "bottom half" mean time to get how much
+ cell. From that we subtract the "bottom half" mean time to get how much
the "top half" takes:
=> 13.43 / (7931 / 3279) = 5.55
@@ -1121,9 +1208,10 @@ 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
[REF_TEVADOR_2]: https://lists.torproject.org/pipermail/tor-dev/2020-June/014358.html
- [REF_TEVADOR_SIM]: https://github.com/tevador/scratchpad/blob/master/tor-pow/effort_sim.md
+ [REF_TEVADOR_SIM]: https://github.com/mikeperry-tor/scratchpad/blob/master/tor-pow/effort_sim.py#L57
+```
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/329-traffic-splitting.txt b/proposals/329-traffic-splitting.txt
index 85d704b..e03d3aa 100644
--- a/proposals/329-traffic-splitting.txt
+++ b/proposals/329-traffic-splitting.txt
@@ -1,15 +1,18 @@
+```
Filename: 329-traffic-splitting.txt
Title: Overcoming Tor's Bottlenecks with Traffic Splitting
Author: David Goulet, Mike Perry
Created: 2020-11-25
-Status: Draft
+Status: Finished
0. Status
This proposal describes the Conflux [CONFLUX] system developed by
Mashael AlSabah, Kevin Bauer, Tariq Elahi, and Ian Goldberg. It aims at
improving Tor client network performance by dynamically splitting
- traffic between two circuits.
+ traffic between two circuits. We have made several additional improvements
+ to the original Conflux design, by making use of congestion control
+ information, as well as updates from Multipath TCP literature.
1. Overview
@@ -19,11 +22,11 @@ Status: Draft
In order to understand our improvements to Conflux, it is important to
properly conceptualize what is involved in the design of multipath
algorithms in general.
-
+
The design space is broken into two orthogonal parts: congestion control
algorithms that apply to each path, and traffic scheduling algorithms
that decide which packets to send on each path.
-
+
MPTCP specifies 'coupled' congestion control (see [COUPLED]). Coupled
congestion control updates single-path congestion control algorithms to
account for shared bottlenecks between the paths, so that the combined
@@ -31,45 +34,48 @@ Status: Draft
happen to be shared between the multiple paths. Various ways of
accomplishing this have been proposed and implemented in the Linux
kernel.
-
+
Because Tor's congestion control only concerns itself with bottlenecks in
Tor relay queues, and not with any other bottlenecks (such as
intermediate Internet routers), we can avoid this complexity merely by
specifying that any paths that are constructed SHOULD NOT share any
- relays. In this way, we can proceed to use the exact same congestion
- control as specified in Proposal 324, for each path.
-
- For this reason, this proposal will focus on the traffic scheduling
- algorithms, rather than coupling. We propose three candidate algorithms
- that have been studied in the literature, and will compare their
- performance using simulation and consensus parameters.
+ relays (except for the exit). This assumption is valid, because non-relay
+ bottlenecks are managed by TCP of client-to-relay and relay-to-relay OR
+ connections, and not Tor's circuit-level congestion control. In this way,
+ we can proceed to use the exact same congestion control as specified in
+ [PROP324], for each path.
+
+ For this reason, this proposal will focus on protocol specification, and
+ the traffic scheduling algorithms, rather than coupling. Note that the
+ scheduling algorithms are currently in flux, and will be subject to
+ change as we tune them in Shadow, on the live network, and for future
+ UDP implementation (see [PROP339]). This proposal will be kept up to
+ date with the current implementation.
1.2. Divergence from the initial Conflux design
The initial [CONFLUX] paper doesn't provide any indications on how to
handle the size of out-of-order cell queue, which we consider a
potential dangerous memory DoS vector (see [MEMORY_DOS]). It also used
- RTT as the sole heuristic for selecting which circuit to send on, which
+ RTT as the sole heuristic for selecting which circuit to send on (which
may vary depending on the geographical locations of the participant
- relays, without considering their actual available circuit capacity
+ relays), without considering their actual available circuit capacity
(which will be available to us via Proposal 324). Additionally, since
the publication of [CONFLUX], more modern packet scheduling algorithms
have been developed, which aim to reduce out-of-order queue size.
-
+
We propose mitigations for these issues using modern scheduling
algorithms, as well as implementations options for avoiding the
out-of-order queue at Exit relays. Additionally, we consider resumption,
side channel, and traffic analysis risks and benefits in [RESUMPTION],
[SIDE_CHANNELS] and [TRAFFIC_ANALYSIS].
+1.3. Design Overview
+
+ The following section describes the Conflux design.
-2. Design
+ The circuit construction is as follows:
- The following section describes the Conflux design. Each sub-section is
- a building block to the multipath design that Conflux proposes.
-
- The circuit construction is as follow:
-
Primary Circuit (lower RTT)
+-------+ +--------+
|Guard 1|----->|Middle 1|----------+
@@ -81,7 +87,7 @@ Status: Draft
|Guard 2|----->|Middle 2|----------+
+-------+ +--------+
Secondary Circuit (higher RTT)
-
+
Both circuits are built using current Tor path selection, however they
SHOULD NOT share the same Guard relay, or middle relay. By avoiding
using the same relays in these positions in the path, we ensure
@@ -89,380 +95,573 @@ Status: Draft
'coupled' congestion control algorithms from the MPTCP
literature[COUPLED]. This both simplifies design, and improves
performance.
-
+
Then, the OP needs to link the two circuits together, as described in
- [LINKING_CIRCUITS], [LINKING_EXIT], and [LINKING_SERVICE].
-
- For ease of explanation, the primary circuit is the circuit with lower
- RTT, and the secondary circuit is the circuit with higher RTT. Initial
- RTT is measured during circuit linking, as described in
- [LINKING_CIRCUITS]. RTT is continually measured using SENDME timing, as
- in Proposal 324. This means that during use, the primary circuit and
- secondary circuit may switch roles, depending on unrelated network
- congestion caused by other Tor clients.
-
+ [CONFLUX_HANDSHAKE].
+
+ For ease of explanation, the primary circuit is the circuit that is
+ more desirable to use, as per the scheduling algorithm, and the secondary
+ circuit is used after the primary is blocked by congestion control. Note
+ that for some algorithms, this selection becomes fuzzy, but all of them
+ favor the circuit with lower RTT, at the beginning of transmission.
+
+ Note also that this notion of primary vs secondary is a local property
+ of the current sender: each endpoint may have different notions of
+ primary, secondary, and current sending circuit. They also may use
+ different scheduling algorithms to determine this.
+
+ Initial RTT is measured during circuit linking, as described in
+ [CONFLUX_HANDSHAKE]. After the initial link, RTT is continually measured
+ using SENDME timing, as in Proposal 324. This means that during use,
+ the primary circuit and secondary circuit may switch roles, depending on
+ unrelated network congestion caused by other Tor clients.
+
We also support linking onion service circuits together. In this case,
only two rendezvous circuits are linked. Each of these RP circuits will
be constructed separately, and then linked. However, the same path
constraints apply to each half of the circuits (no shared relays between
the legs). If, by chance, the service and the client sides end up
sharing some relays, this is not catastrophic. Multipath TCP researchers
- we have consulted (see [ACKNOWLEDGEMENTS]), believe Tor's congestion
+ we have consulted (see [ACKNOWLEDGMENTS]), believe Tor's congestion
control from Proposal 324 to be sufficient in this rare case.
-
- Only two circuits SHOULD be linked together. However, implementations
- SHOULD make it easy for researchers to *test* more than two paths, as
- this has been shown to assist in traffic analysis resistance[WTF_SPLIT].
- At minimum, this means not hardcoding only two circuits in the
- implementation.
-
+
+ In the algorithms we recommend here, only two circuits will be linked
+ together at a time. However, implementations SHOULD support more than
+ two paths, as this has been shown to assist in traffic analysis
+ resistance[WTF_SPLIT], and will also be useful for maintaining a desired
+ target RTT, for UDP VoIP applications.
+
If the number of circuits exceeds the current number of guard relays,
guard relays MAY be re-used, but implementations SHOULD use the same
number of Guards as paths.
-
+
Linked circuits MUST NOT be extended further once linked (ie:
'cannibalization' is not supported).
+
+2. Protocol Mechanics
+
2.1. Advertising support for conflux
+2.1.1 Relay
+
We propose a new protocol version in order to advertise support for
circuit linking on the relay side:
-
- "Relay=4" -- Relay supports an 2 byte sequence number in a RELAY cell
- header used for multipath circuit which are linked with the
- new RELAY_CIRCUIT_LINK relay cell command.
-
- XXX: Advertise this in onion service descriptor.
- XXX: Onion service descriptor can advertise more than two circuits?
+
+ "Conflux=1" -- Relay supports Conflux as in linking circuits together using
+ the new LINK, LINKED and SWITCH relay command.
+
+2.1.2 Onion Service
+
+ We propose to add a new line in order to advertise conflux support in the
+ encrypted section of the onion service descriptor:
+
+ "conflux" SP max-num-circ SP desired-ux NL
+
+ The "max-num-circ" value indicate the maximum number of rendezvous
+ circuits that are allowed to be linked together.
+
+ We let the service specify the conflux algorithm to use, when sending data
+ to the service. Some services may prefer latency, where as some may prefer
+ throughput. However, clients also have the ability to request their own UX
+ for data that the service sends, in the LINK handshake below, in part
+ because the high-throughput algorithms will require more out-of-order queue
+ memory, which may be infeasible on mobile.
The next section describes how the circuits are linked together.
-2.2. Linking circuits [LINKING_CIRCUITS]
+2.2. Conflux Handshake [CONFLUX_HANDSHAKE]
To link circuits, we propose new relay commands that are sent on both
circuits, as well as a response to confirm the join, and an ack of this
response. These commands create a 3way handshake, which allows each
endpoint to measure the initial RTT of each leg upon link, without
needing to wait for any data.
-
+
All three stages of this handshake are sent on *each* circuit leg to be
linked.
-
- To save round trips, these cells SHOULD be combined with the initial
- RELAY_BEGIN cell on the faster circuit leg, using Proposal 325. See
- [LINKING_EXIT] and [LINKING_SERVICE] for more details on setup in each
- case.
-
- There are other ways to do this linking that we have considered, but
- they seem not to be significantly better than this method, especially
- since we can use Proposal 325 to eliminate the RTT cost of this setup
- before sending data. For those other ideas, see [ALTERNATIVE_LINKING]
- and [ALTERNATIVE_RTT], in the appendix.
-
+
+ When packed cells are a reality (proposal 340), these cells SHOULD be
+ combined with the initial RELAY_BEGIN cell on the faster circuit leg.
+ This combination also allows better enforcement against side channels.
+ (See [SIDE_CHANNELS]).
+
+ There are other ways to do this linking that we have considered, but they
+ seem not to be significantly better than this method, especially since we can
+ use Proposal 340 to eliminate the RTT cost of this setup before sending data.
+ For those other ideas, see [ALTERNATIVE_LINKING] and [ALTERNATIVE_RTT], in
+ the appendix.
+
The first two parts of the handshake establish the link, and enable
resumption:
-
- 16 -- RELAY_CIRCUIT_LINK
-
- Sent from the OP to the exit/service in order to link
- circuits together at the end point.
-
- 17 -- RELAY_CIRCUIT_LINKED
-
- Sent from the exit/service to the OP, to confirm the circuits
- were linked.
-
- These cells have the following contents:
-
+
+ 19 -- RELAY_CONFLUX_LINK
+
+ Sent from the OP to the exit/service in order to link circuits
+ together at the end point.
+
+ 20 -- RELAY_CONFLUX_LINKED
+
+ Sent from the exit/service to the OP, to confirm the circuits were
+ linked.
+
+ The contents of these two cells is exactly the same. They have the following
+ contents:
+
VERSION [1 byte]
PAYLOAD [variable, up to end of relay payload]
-
+
The VERSION tells us which circuit linking mechanism to use. At this
point in time, only 0x01 is recognized and is the one described by the
Conflux design.
-
+
For version 0x01, the PAYLOAD contains:
-
+
NONCE [32 bytes]
LAST_SEQNO_SENT [8 bytes]
LAST_SEQNO_RECV [8 bytes]
-
- XXX: Should we let endpoints specify their preferred [SCHEDULING] alg
- here, to override consensus params? This has benefits: eg low-memory
- mobile clients can ask for an alg that is better for their reorder
- queues. But it also has complexity risk, if the other endpoint does not
- want to support it, because of its own memory issues.
-
+ DESIRED_UX [1 byte]
+
The NONCE contains a random 256-bit secret, used to associate the two
circuits together. The nonce MUST NOT be shared outside of the circuit
transmission, or data may be injected into TCP streams. This means it
MUST NOT be logged to disk.
-
+
The two sequence number fields are 0 upon initial link, but non-zero in
- the case of a resumption attempt (See [RESUMPTION]).
-
- If either circuit does not receive a RELAY_CIRCUIT_LINKED response, both
+ the case of a reattach or resumption attempt (See [CONFLUX_SET_MANAGEMENT]
+ and [RESUMPTION]).
+
+ The DESIRED_UX field allows the endpoint to request the UX properties
+ it wants. The other endpoint SHOULD select the best known scheduling
+ algorithm, for these properties. The endpoints do not need to agree
+ on which UX style they prefer.
+
+ The UX properties are:
+
+ 0 - NO_OPINION
+ 1 - MIN_LATENCY
+ 2 - LOW_MEM_LATENCY
+ 3 - HIGH_THROUGHPUT
+ 4 - LOW_MEM_THROUGHPUT
+
+ The algorithm choice is performed by to the *sender* of data, (ie: the
+ receiver of the PAYLOAD). The receiver of data (sender of the PAYLOAD)
+ does not need to be aware of the exact algorithm in use, but MAY enforce
+ expected properties (particularly low queue usage, in the case of requesting
+ either LOW_MEM_LATENCY or LOW_MEM_THROUGHPUT). The receiver MAY close the
+ entire conflux set if these properties are violated.
+
+ If either circuit does not receive a RELAY_CONFLUX_LINKED response, both
circuits MUST be closed.
-
+
The third stage of the handshake exists to help the exit/service measure
initial RTT, for use in [SCHEDULING]:
-
- 18 -- RELAY_CIRCUIT_LINKED_RTT_ACK
-
- Sent from the OP to the exit/service, to provide initial RTT
- measurement for the exit/service.
-
- For timeout of the handshake, clients SHOULD use the normal SOCKS/stream
- timeout already in use for RELAY_BEGIN.
-
- These three relay commands (RELAY_CIRCUIT_LINK, RELAY_CIRCUIT_LINKED,
- and RELAY_CIRCUIT_LINKED_RTT_ACK) are send on *each* leg, to allow each
- endpoint to measure the initial RTT of each leg.
+
+ 21 -- RELAY_CONFLUX_LINKED_ACK
+
+ Sent from the OP to the exit/service, to provide initial RTT
+ measurement for the exit/service.
+
+ These three relay commands are sent on *each* leg, to allow each endpoint to
+ measure the initial RTT of each leg.
+
+ The client SHOULD abandon and close circuit if the LINKED message takes too
+ long to arrive. This timeout MUST be no larger than the normal SOCKS/stream
+ timeout in use for RELAY_BEGIN, but MAY be the Circuit Build Timeout value,
+ instead. (The C-Tor implementation currently uses Circuit Build Timeout).
+
+ See [SIDE_CHANNELS] for rules for when to reject unexpected handshake cells.
2.2. Linking Circuits from OP to Exit [LINKING_EXIT]
- To link exit circuits, two circuits to the same exit are built. The
- client records the circuit build time of each.
-
- If the circuits are being built on-demand, for immediate use, the
- circuit with the lower build time SHOULD use Proposal 325 to append its
- first RELAY cell to the RELAY_COMMAND_LINK, on the circuit with the
- lower circuit build time. The exit MUST respond on this same leg. After
- that, actual RTT measurements MUST be used to determine future
- transmissions, as specified in [SCHEDULING].
-
- The RTT times between RELAY_COMMAND_LINK and RELAY_COMMAND_LINKED are
- measured by the client, to determine each circuit RTT to determine
- primary vs secondary circuit use, and for packet scheduling. Similarly,
- the exit measures the RTT times between RELAY_COMMAND_LINKED and
- RELAY_COMMAND_LINKED_RTT_ACK, for the same purpose.
-
+ To link exit circuits, two circuits to the same exit are built, with
+ additional restrictions such that they do not share Guard or Middle
+ relays. This restriction applies via specific relay identity keys,
+ and not IP addresses, families, or networks. (This is because the purpose
+ of it is to avoid sharing a bottleneck *inside* relay circuit queues;
+ bottlenecks caused by a shared network are handled by TCP's congestion
+ control on the OR conns).
+
+ Bridges also are subject to the same constraint as Guard relays;
+ the C-Tor codebase emits a warn if only one bridge is configured, unless
+ that bridge has transport "snowflake". Snowflake is exempt from this
+ Guard restriction because it is actually backed by many bridges. In the
+ bridge case, we only warn, and do not refuse to build conflux circuits,
+ because it is not catastrophic that Bridges are shared, it is just
+ sub-optimal for performance and congestion.
+
+ When each circuit is opened, we ensure that congestion control
+ has been negotiated. If congestion control negotiation has failed, the
+ circuit MUST be closed. After this, the linking handshake begins.
+
+ The RTT times between RELAY_CONFLUX_LINK and RELAY_CONFLUX_LINKED are
+ measured by the client, to determine primary vs secondary circuit use,
+ and for packet scheduling. Similarly, the exit measures the RTT times
+ between RELAY_CONFLUX_LINKED and RELAY_CONFLUX_LINKED_ACK, for the same
+ purpose.
+
+ Because of the race between initial data and the RELAY_CONFLUX_LINKED_ACK
+ cell, conditions can arise where an Exit needs to send data before the
+ slowest circuit delivers this ACK. In these cases, it should prefer sending
+ data on the circuit that has delivered the ACK (which will arrive immediately
+ prior to any data from the client). This circuit will be the lower RTT
+ circuit anyway, but the code needs to handle the fact that in this case,
+ there won't yet be an RTT for the second circuit.
+
2.3. Linking circuits to an onion service [LINKING_SERVICE]
-
+
For onion services, we will only concern ourselves with linking
rendezvous circuits.
-
+
To join rendezvous circuits, clients make two introduce requests to a
service's intropoint, causing it to create two rendezvous circuits, to
meet the client at two separate rendezvous points. These introduce
requests MUST be sent to the same intropoint (due to potential use of
onionbalance), and SHOULD be sent back-to-back on the same intro
- circuit. They MAY be combined with Proposal 325.
-
- The first rendezvous circuit to get joined SHOULD use Proposal 325 to
+ circuit. They MAY be combined with Proposal 340. (Note that if we do not
+ use Prop340, we will have to raise the limit on number of intros per
+ client circuit to 2, here, at intropoints).
+
+ When rendezvous circuits are built, they should use the same Guard,
+ Bridge, and Middle restrictions as specified in 2.2, for Exits. These
+ restrictions SHOULD also take into consideration all Middles in the path,
+ including the rendezvous point. All relay identities should be unique
+ (again, except for when the Snowflake transport is in use). The one
+ special case here is if the chosen rendezvous points by a client
+ are the same as the service's guards. In this case, the service SHOULD
+ NOT use different guards, but instead stick with the guards it has.
+ The reason for this is that we do not want to create the ability
+ for a client to force a service to use different guards.
+
+ The first rendezvous circuit to get joined SHOULD use Proposal 340 to
append the RELAY_BEGIN command, and the service MUST answer on this
circuit, until RTT can be measured.
-
+
Once both circuits are linked and RTT is measured, packet scheduling
MUST be used, as per [SCHEDULING].
-
-2.4. Congestion Control Application [CONGESTION_CONTROL]
-
- The SENDMEs for congestion control are performed per-leg. As data
- arrives, regardless of its ordering, it is counted towards SENDME
- delivery. In this way, 'cwnd - package_window' of each leg always
- reflects the available data to send on each leg. This is important for
+
+2.4. Conflux Set Management [CONFLUX_SET_MANAGEMENT]
+
+ When managing legs, it is useful to separate sets that have completed the
+ link handshake from legs that are still performing the handshake. Linked
+ sets MAY have additional unlinked legs on the way, but these should not
+ be used for sending data until the handshake is complete.
+
+ It is also useful to enforce various additional conditions on the handshake,
+ depending on if [RESUMPTION] is supported, and if a leg has been launched
+ because of an early failure, or due to a desire for replacement.
+
+2.4.1. Pre-Building Sets
+
+ In C-Tor, conflux is only used via circuit prebuilding. Pre-built conflux
+ sets are preferred over other pre-built circuits, but if the pre-built pool
+ ends up empty, normal pre-built circuits are used. If those run out, regular
+ non-conflux circuits are built. In other words, in C-Tor, conflux sets are
+ never built on-demand, but this is strictly an implementation decision, to
+ simplify dealing with the C-Tor codebase
+
+ The consensus parameter 'cfx_max_prebuilt_set' specifies the number of
+ sets to pre-build.
+
+ During upgrade, the consensus parameter 'cfx_low_exit_threshold' will be
+ used, so that if there is a low amount of conflux-supporting exits, only
+ one conflux set will be built.
+
+2.4.2. Set construction
+
+ When a set is launched, legs begin the handshake in the unlinked state.
+ As handshakes complete, finalization is attempted, to create a linked set.
+ On the client, this finalization happens upon receipt of the LINKED cell.
+ On the exit/service, this finalization happens upon *sending* the LINKED_ACK.
+
+ The initiator of this handshake considers the set fully linked once the
+ RELAY_CONFLUX_LINKED_ACK is sent (roughly upon receipt of the LINKED cell).
+ Because of the potential race between LINKED_ACK, and initial data sent by
+ the client, the receiver of the handshake must consider a leg linked at
+ the time of *sending* a LINKED_ACK cell.
+
+ This means that exit legs may not have an RTT measurement, if data on the
+ faster leg beats the LINKED_ACK on the slower leg. The implementation MUST
+ account for this, by treating unmeasured legs as having infinite RTT.
+
+ When attempting to finalize a set, this finalization should not complete
+ if any unlinked legs are still pending.
+
+2.4.3. Closing circuits
+
+ For circuits that are unlinked, the origin SHOULD immediately relaunch a new
+ leg when it is closed, subject to the limits in [SIDE_CHANNELS].
+
+ In C-Tor, we do not support arbitrary resumption. Therefore, we perform
+ some additional checks upon closing circuits, to decide if we should
+ immediately tear down the entire set:
+ - If the closed leg was the current sending leg, close the set
+ - If the closed leg had the highest non-zero last_seq_recv/sent, close the set
+ - If data was in progress on a closed leg (inflight > cc_sendme_inc), then
+ all legs must be closed
+
+2.4.4. Reattaching Legs
+
+ While C-Tor does not support arbitrary resumption, new legs *can* be
+ attached, so long as there is no risk of data loss from a closed leg.
+ This enables latency probing, which will be important for UDP VoIP.
+
+ Currently, the C-Tor codebase checks for data loss by verifying that
+ the LINK/LINKED cell has a lower last_seq_sent than all current
+ legs' maximum last_seq_recv, and a lower last_seq_recv than all
+ current legs last_seq_sent.
+
+ This check is performed on finalization, not the receipt of first
+ handshake cell. This gives the data additional time to arrive.
+
+2.5. Congestion Control Application [CONGESTION_CONTROL]
+
+ The SENDMEs for congestion control are performed per-leg. As soon as
+ data arrives, regardless of its ordering, it is counted towards SENDME
+ delivery. In this way, 'cwnd - inflight' of each leg always reflects
+ the available data to send on each leg. This is important for
[SCHEDULING].
-
+
The Congestion control Stream XON/XOFF can be sent on either leg, and
applies to the stream's transmission on both legs.
-
-2.5. Sequencing [SEQUENCING]
-
+
+ In C-Tor, streams used to become blocked as soon as the OR conn
+ of their circuit was blocked. Because conflux can send on the other
+ circuit, which uses a different OR conn, this form of stream blocking
+ has been decoupled from the OR conn status, and only happens when
+ congestion control has decided that all circuits are blocked (congestion
+ control becomes blocked when either 'cwnd - inflight <= 0', *or* when
+ the local OR conn is blocked, so if all local OR conns of a set are
+ blocked, then the stream will block that way).
+
+ Note also that because congestion control only covers RELAY_COMMAND_DATA
+ cells, for all algorithms, a special case must be made such that if no
+ circuit is available to send on due to congestion control blocking,
+ commands other than RELAY_COMMAN_DATA MUST be sent on the current
+ circuit, even if the cell scheduler believes that no circuit is available.
+ Depending on the code structure of Arti, this special case may or may
+ not be necessary. It arises in C-Tor because nothing can block the
+ sending of arbitrary non-DATA relay command cells.
+
+2.6. Sequencing [SEQUENCING]
+
With multiple paths for data, the problem of data re-ordering appears.
In other words, cells can arrive out of order from the two circuits
where cell N + 1 arrives before the cell N.
-
+
Handling this reordering operates after congestion control for each
circuit leg, but before relay cell command processing or stream data
delivery.
-
+
For the receiver to be able to reorder the receiving cells, a sequencing
scheme needs to be implemented. However, because Tor does not drop or
reorder packets inside of a circuit, this sequence number can be very
small. It only has to signal that a cell comes after those arriving on
another circuit.
-
- To achieve this, we add a small sequence number to the common relay
- header for all relay cells on linked circuits. This sequence number is
- meant to signal the number of cells sent on the *other* leg, so that
- each endpoint knows how many cells are still in-flight on another leg.
- It is different from the absolute sequence number used in
- [LINKING_CIRCUITS] and [RESUMPTION], but can be derived from that
- number, using relative arithmetic.
-
- Relay command [1 byte]
- Recognized [2 bytes]
- StreamID [2 bytes]
- Digest [4 bytes]
- Length [2 bytes]
- > LongSeq [1 bit] # If this bit is set, use 31 bits for Seq
- > Sequencing [7 or 31 bits]
- Data [Remainder]
-
- The sequence number is only set for the first cell after the endpoint
- switches legs. In this case, LongSeq is set to 1, and the Sequencing
- field is 31 more bits. Otherwise it is a 1 byte 0 value.
-
- These fields MUST be present on ALL end-to-end relay cells on each leg
- that come from the endpoint, following a RELAY_CIRCUIT_LINK command.
-
- They are absent on 'leaky pipe' RELAY_COMMAND_DROP and
- RELAY_COMMAND_PADDING_NEGOTIATED cells that come from middle relays, as
- opposed to the endpoint, to support padding.
-
- When an endpoint switches legs, on the first cell in a new leg, LongSeq
- is set to 1, and the following 31 bits represent the *total* number of
- cells sent on the *other* leg, before the switch. The receiver MUST wait
- for that number of cells to arrive from the previous leg before
- delivering that cell.
-
- XXX: In the rare event that we send more than 2^31 cells (~1TB) on a
- single leg, do we force a switch of legs, or expand the field further?
-
- An alternative method of sequencing, that assumes that the endpoint
- knows when it is going to switch, the cell before it switches, is
- specified in [ALTERNATIVE_SEQUENCING]. Note that that method requires
- only 1 byte for sequence number and switch signaling, but requires that
- the sender know that it is planning to switch, the cell before it
- switches. (This is possible with [BLEST_TOR], but [LOWRTT_TOR] can
- switch based on RTT change, so it may be one cell late in that case).
-
-2.6. Resumption [RESUMPTION]
+
+ To achieve this, we propose a new relay command used to indicate a switch to
+ another leg:
+
+ 22 -- RELAY_CONFLUX_SWITCH
+
+ Sent from a sending endpoint when switching leg in an
+ already linked circuit construction. This message is sent on the leg
+ that will be used for new traffic, and tells the receiver the size of
+ the gap since the last data (if any) sent on that leg.
+
+ The cell payload format is:
+
+ SeqNum [4 bytes]
+
+ The "SeqNum" value is a relative sequence number, which is the difference
+ between the last absolute sequence number sent on the new leg and the last
+ absolute sequence number sent on all other legs prior to the switch. In this
+ way, the endpoint knows what to increment its local absolute sequence number
+ by, before cells start to arrive.
+
+ To achieve this, the sender must maintain the last absolute sequence sent for
+ each leg, and the receiver must maintain the last absolute sequence number
+ received for each leg.
+
+ As an example, let's say we send 10 cells on the first leg, so our absolute
+ sequence number is 10. If we then switch to the second leg, it is trivial to
+ see that we should send a SWITCH with 10 as the relative sequence number, to
+ indicate that regardless of the order in which the first cells are received,
+ subsequent cells on the second leg should start counting at 10.
+
+ However, if we then send 21 cells on this leg, our local absolute sequence
+ number as the sender is 31. So when we switch back to the first leg, where
+ the last absolute sequence sent was 10, we must send a SWITCH cell with 21,
+ so that when the first leg receives subsequent cells, it assigns those cells
+ an absolute sequence number starting at 31.
+
+ In the rare event that we send more than 2^31 cells (~1TB) on a single leg,
+ the leg should be switched in order to reset that relative sequence number to
+ fit within 4 bytes.
+
+ For a discussion of rules to rate limit the usage of SWITCH as a side
+ channel, see [SIDE_CHANNELS].
+
+2.7. Resumption [RESUMPTION]
In the event that a circuit leg is destroyed, they MAY be resumed.
-
+ Full resumption is not supported in C-Tor, but is possible to implement,
+ at the expense of always storing roughly a congestion window of
+ already-transmitted data on each endpoint, in the worst case. Simpler
+ forms of resumption, where there is no data loss, are supported. This
+ is important to support latency probing, for ensuring UDP VoIP minimum
+ RTT requirements are met (roughly 300-500ms, depending on VoIP
+ implementation).
+
Resumption is achieved by re-using the NONCE to the same endpoint
(either [LINKING_EXIT] or [LINKING_SERVICE]). The resumed path need
not use the same middle and guard relays as the destroyed leg(s), but
SHOULD NOT share any relays with any existing legs(s).
-
- To provide resumption, endpoints store an absolute 64bit cell counter of
- the last cell they have sent on a conflux pair (their LAST_SEQNO_SENT),
- as well the last sequence number they have delivered in-order to edge
- connections corresponding to a conflux pair (their LAST_SEQNO_RECV).
- Additionally, endpoints MAY store the entire contents of unacked
- inflight cells (ie the 'package_window' from proposal 324), for each
- leg, along with information corresponding to those cells' absolute
- sequence numbers.
-
- These 64 bit absolute counters can wrap without issue, as congestion
- windows will never grow to 2^64 cells until well past the Singularity.
- However, it is possible that extremely long, bulk circuits could exceed
- 2^64 total sent or received cells, so endpoints SHOULD handle wrapped
- sequence numbers for purposes of computing retransmit information. (But
- even this case is unlikely to happen within the next decade or so).
-
- Upon resumption, the LAST_SEQNO_SENT and LAST_SEQNO_RECV fields are used
- to convey the sequence numbers of the last cell the relay sent and
- received on that leg. The other endpoint can use these sequence numbers
- to determine if it received the in-flight data or not, or sent more data
- since that point, up to and including this absolute sequence number. If
- LAST_SEQNO_SENT has not been received, the endpoint MAY transmit the
- missing data, if it still has it buffered.
-
- Because both endpoints get information about the other side's absolute
- SENT sequence number, they will know exactly how many re-transmitted
- packets to expect, if the circuit is successfully resumed.
+
+ If data loss has been detected upon a link handshake, resumption can be
+ achieved by sending a switch cell, which is immediately followed by the
+ missing data. Roughly, each endpoint must check:
+ - if cell.last_seq_recv <
+ min(max(legs.last_seq_sent),max(closed_legs.last_seq_sent)):
+ - send a switch cell immediately with missing data:
+ (last_seq_sent - cell.last_seq_recv)
+
+ If an endpoint does not have this missing data due to memory pressure,
+ that endpoint MUST destroy *both* legs, as this represents unrecoverable
+ data loss.
Re-transmitters MUST NOT re-increment their absolute sent fields
while re-transmitting.
-
- If it does not have this missing data due to memory pressure, that
- endpoint MUST destroy *both* legs, as this represents unrecoverable
- data loss.
-
- Otherwise, the new circuit can be re-joined, and its RTT can be compared
- to the remaining circuit to determine if the new leg is primary or
- secondary.
-
+
It is even possible to resume conflux circuits where both legs have been
collapsed using this scheme, if endpoints continue to buffer their
unacked package_window data for some time after this close. However, see
[TRAFFIC_ANALYSIS] for more details on the full scope of this issue.
-
+
If endpoints are buffering package_window data, such data should be
given priority to be freed in any oomkiller invocation. See [MEMORY_DOS]
for more oomkiller information.
+2.8. Data transmission
+
+ Most cells in Tor are circuit-specific, and should only be sent on a
+ circuit, even if that circuit is part of a conflux set. Cells that
+ are not multiplexed do not count towards the conflux sequence numbers.
+
+ However, in addition to the obvious RELAY_COMMAND_DATA, a subset of cells
+ MUST ALSO be multiplexed, so that their ordering is preserved when they
+ arrive at the other end. These cells do count towards conflux sequence
+ numbers, and are handled in the out-of-order queue, to preserve ordered
+ delivery:
+ RELAY_COMMAND_BEGIN
+ RELAY_COMMAND_DATA
+ RELAY_COMMAND_END
+ RELAY_COMMAND_CONNECTED
+ RELAY_COMMAND_RESOLVE
+ RELAY_COMMAND_RESOLVED
+ RELAY_COMMAND_XOFF
+ RELAY_COMMAND_XON
+
+ Currently, this set is the same as the set of cells that have stream ID,
+ but the property that leads to this requirement is not stream usage by
+ itself, it is that these cells must be ordered with respect to all data
+ on the circuit. It is not impossible that future relay commands could be
+ invented that don't have stream IDs, but yet must still arrive in order
+ with respect to circuit data cells. Prop#253 is one possible example of
+ such a thing (though we won't be implementing that proposal).
+
3. Traffic Scheduling [SCHEDULING]
In order to load balance the traffic between the two circuits, the
original conflux paper used only RTT. However, with Proposal 324, we
will have accurate information on the instantaneous available bandwidth
- of each circuit leg, as 'cwnd - package_window' (see Section 3 of
- Proposal 324).
-
- Some additional RTT optimizations are also useful, to improve
- responsiveness and minimize out-of-order queue sizes.
-
+ of each circuit leg, as 'cwnd - inflight' (see Section 3 of
+ Proposal 324). We also have the TCP block state of the local OR
+ connection.
+
We specify two traffic schedulers from the multipath literature and
- adapt them to Tor: [LOWRTT_TOR] and [BLEST_TOR]. [LOWRTT_TOR] also has
- three variants, with different trade offs.
-
- However, see the [TRAFFIC_ANALYSIS] sections of this proposal for
+ adapt them to Tor: [MINRTT_TOR], and [LOWRTT_TOR]. Additionally,
+ we create low-memory variants of these that aim to minimize the
+ out-of-order queue size at the receiving endpoint.
+
+ Additionally, see the [TRAFFIC_ANALYSIS] sections of this proposal for
important details on how this selection can be changed, to reduce
website traffic fingerprinting.
-3.1. LowRTT Scheduling [LOWRTT_TOR]
-
- This scheduling algorithm is based on the original [CONFLUX] paper, with
- ideas from [MPTCP]'s minRTT/LowRTT scheduler.
-
- In this algorithm, endpoints send cells on the circuit with lower RTT
- (primary circuit). This continues while the congestion window on the
- circuit has available room: ie whenever cwnd - package_window > 0.
-
- Whenever the primary circuit's congestion window becomes full, the
- secondary circuit is used. We stop reading on the send window source
- (edge connection) when both congestion windows become full.
-
+3.1. MinRTT scheduling [MINRTT_TOR]
+
+ This schedulng algorithm is used for the MIN_LATENCY user experience.
+
+ It works by always and only sending on the circuit with the current minimum
+ RTT. With this algorithm, conflux should effectively stay on the circuit with
+ the lowest initial RTT, unless that circuit's RTT raises above the RTT of the
+ other circuit (due to relay load or congestion). When the circuit's congestion
+ window is full (ie: cwnd - inflight <= 0), or if the local OR conn blocks,
+ the conflux set stops transmitting and stops reading on edge connections,
+ rather than switch.
+
+ This should result in low out-of-order queues in most situations, unless
+ the initial RTTs of the two circuits are very close (basically within the
+ Vegas RTT bounds of queue variance, 'alpha' and 'beta').
+
+3.2. LowRTT Scheduling [LOWRTT_TOR]
+
+ This scheduling algorithm is based on [MPTCP]'s LowRTT scheduler. This
+ algorithm is used for the UX choice of HIGH_THROUGHPUT.
+
+ In this algorithm, endpoints send cells on the circuit with lowest RTT that
+ has an unblocked local OR connection, and room in its congestion window (ie:
+ cwnd - inflight > 0). We stop reading on edge connections only when both
+ congestion windows become full, or when both local OR connections are blocked.
+
In this way, unlike original conflux, we switch to the secondary circuit
- without causing congestion on the primary circuit. This improves both
- load times, and overall throughput.
-
- This behavior matches minRTT from [MPTCP], sometimes called LowRTT.
-
- It may be better to stop reading on the edge connection when the primary
- congestion window becomes full, rather than switch to the secondary
- circuit as soon as the primary congestion window becomes full. (Ie: only
- switch if the RTTs themselves change which circuit is primary). This is
- what was done in the original Conflux paper. This behavior effectively
- causes us to optimize for responsiveness and congestion avoidance,
- rather than throughput. For evaluation, we will control this switching
- behavior with a consensus parameter (see [CONSENSUS_PARAMETERS]).
-
- Because of potential side channel risk (see [SIDE_CHANNELS]), a third
- variant of this algorithm, where the primary circuit is chosen during
- the [LINKING_CIRCUITS] handshake and never changed, is also possible
- to control via consensus parameter.
-
-3.2. BLEST Scheduling [BLEST_TOR]
+ without causing congestion either locally, or on either circuit. This
+ improves both load times, and overall throughput. Given a large enough
+ transmission, both circuits are used to their full capacity,
+ simultaneously.
+
+3.3. MinRTT Low-Memory Scheduling [MINRTT_LOWMEM_TOR]
+
+ The low memory version of the MinRTT scheduler ensures that we do not
+ perform a switch more often than once per congestion window worth of data.
+
+ XXX: Other rate limiting, such as not switching unless the RTT changes by
+ more than X%, may be useful here.
+
+3.4. BLEST Scheduling [BLEST_TOR]
+
+ XXX: Something like this might be useful for minimizing OOQ for the UX
+ choice of LOW_MEM_THROUGHPUT, but we might just be able to reduce switching
+ frequency instead.
+
+ XXX: We want an algorithm that only uses cwnd instead. This algorithm
+ has issues if the primary cwnd grows while the secondary does not.
+ Expect this section to change.
[BLEST] attempts to predict the availability of the primary circuit, and
use this information to reorder transmitted data, to minimize
head-of-line blocking in the recipient (and thus minimize out-of-order
queues there).
-
+
BLEST_TOR uses the primary circuit until the congestion window is full.
Then, it uses the relative RTT times of the two circuits to calculate
how much data can be sent on the secondary circuit faster than if we
- just waited for the primary circuit to become available.
-
- This is achieved by computing two variables at the sender:
-
+ just waited for the primary circuit to become available.
+
+ This is achieved by computing two variables at the sender:
+
rtts = secondary.currRTT / primary.currRTT
primary_limit = primary.cwnd + (rtts-1)/2)*rtts
-
+
Note: This (rtts-1)/2 factor represents anticipated congestion window
growth over this period.. it may be different for Tor, depending on CC
alg.
-
+
If primary_limit < secondary.cwnd - (secondary.package_window + 1), then
there is enough space on the secondary circuit to send data faster than
we could than waiting for the primary circuit.
-
+
XXX: Note that BLEST uses total_send_window where we use secondary.cwnd
in this check. total_send_window is min(recv_win, CWND). But since Tor
does not use receive windows and instead uses stream XON/XOFF, we only
@@ -472,69 +671,28 @@ Status: Draft
hopefully this is fine. If we need to, we could turn [REORDER_SIGNALING]
into a receive window indication of some kind, to indicate remaining
buffer size.
-
+
Otherwise, if the primary_limit condition is not hit, cease reading on
source edge connections until SENDME acks come back.
-
+
Here is the pseudocode for this:
-
+
while source.has_data_to_send():
if primary.cwnd > primary.package_window:
primary.send(source.get_packet())
continue
-
+
rtts = secondary.currRTT / primary.currRTT
primary_limit = (primary.cwnd + (rtts-1)/2)*rtts
-
+
if primary_limit < secondary.cwnd - (secondary.package_window+1):
secondary.send(source.get_packet())
else:
break # done for now, wait for SENDME to free up CWND and restart
-
+
Note that BLEST also has a parameter lambda that is updated whenever HoL
blocking occurs. Because it is expensive and takes significant time to
signal this over Tor, we omit this.
-
- XXX: See [REORDER_SIGNALING] section if we want this lambda feedback.
-
-3.3. Reorder queue signaling [REORDER_SIGNALING]
-
- Reordering is fairly simple task. By following using the sequence
- number field in [SEQUENCING], endpoints can know how many cells are
- still in flight on the other leg.
-
- To reorder them properly, a buffer of out of order cells needs to be
- kept. On the Exit side, this can quickly become overwhelming
- considering ten of thousands of possible circuits can be held open
- leading to gigabytes of memory being used. There is a clear potential
- memory DoS vector in this case, covered in more detail in
- [MEMORY_DOS].
-
- Luckily, [BLEST_TOR] and the form of [LOWRTT_TOR] that only uses the
- primary circuit will minimize or eliminate this out-of-order buffer.
-
- XXX: The remainder of this section may be over-complicating things... We
- only need these concepts if we want to use BLEST's lambda feedback. Though
- turning this into some kind of receive window that indicates remaining
- reorder buffer size may also help with the total_send_window also noted
- in BLEST_TOR.
-
- The default for this queue size is governed by the 'cflx_reorder_client'
- and 'cflx_reorder_srv' consensus parameters (see [CONSENSUS_PARAMS]).
- 'cflx_reorder_srv' applies to Exits and onion services. Both parameters
- can be overridden by Torrc, to larger or smaller than the consensus
- parameter. (Low memory clients may want to lower it; SecureDrop onion
- services or other high-upload services may want to raise it).
-
- When the reorder queue hits this size, a RELAY_CONFLUX_XOFF is sent down
- the circuit leg that has data waiting in the queue and use of that leg
- SHOULD cease, until it drains to half of this value, at which point an
- RELAY_CONFLUX_XON is sent. Note that this is different than the stream
- XON/XOFF from Proposal 324.
-
- XXX: [BLEST] actually does not cease use of a path in this case, but
- instead uses this signal to adjust the lambda parameter, which biases
- traffic away from that leg.
4. Security Considerations
@@ -543,109 +701,152 @@ Status: Draft
Both reorder queues and retransmit buffers inherently represent a memory
denial of service condition.
-
+
For [RESUMPTION] retransmit buffers, endpoints that support this feature
SHOULD free retransmit information as soon as they get close to memory
pressure. This prevents resumption while data is in flight, but will not
otherwise harm operation.
-
- For reorder buffers, adversaries can potentially impact this at any
- point, but most obviously and most severely from the client position.
-
- In particular, clients can lie about sequence numbers, sending cells
- with sequence numbers such that the next expected sequence number is
- never sent. They can do this repeatedly on many circuits, to exhaust
- memory at exits.
-
- One option is to only allow actual traffic splitting in the downstream
- direction, towards clients, and always use the primary circuit for
- everything in the upstream direction. However, the ability to support
- conflux from the client to the exit shows promise against traffic
- analysis (see [WTF_SPLIT]).
-
- The other option is to use [BLEST_TOR] from clients to exits, as it has
- predictable interleaved cell scheduling, and minimizes reorder queues at
- exits. If the ratios prescribed by that algorithm are not followed
- within some bounds, the other endpoint can close both circuits, and free
- the queue memory.
-
- This still leaves the possibility that intermediate relays may block a
- leg, allowing cells to traverse only one leg, thus still accumulating at
- the reorder queue. Clients can also spoof sequence numbers similarly, to
- make it appear that they are following [BLEST_TOR], without actually
- sending any data on one of the legs.
-
- To handle either of these cases, when a relay is under memory pressure,
- the circuit OOM killer SHOULD free and close circuits with the oldest
- reorder queue data, first. This heuristic was shown to be best during
- the [SNIPER] attack OOM killer iteration cycle.
-
-4.2. Side Channels [SIDE_CHANNELS]
-
- Two potential side channels may be introduced by the use of Conflux:
- 1. RTT leg-use bias by altering SENDME latency
+
+ In terms of adversarial issues, clients can lie about sequence numbers,
+ sending cells with sequence numbers such that the next expected sequence
+ number is never sent. They can do this repeatedly on many circuits, to
+ exhaust memory at exits. Intermediate relays may also block a leg, allowing
+ cells to traverse only one leg, thus still accumulating at the reorder queue.
+
+ In C-Tor we will mitigate this in three ways: via the OOM killer, by the
+ ability for exits to request that clients use the LOW_MEM_LATENCY UX
+ behavior, and by rate limiting the frequency of switching under the
+ LOW_MEM_LATENCY UX style.
+
+ When a relay is under memory pressure, the circuit OOM killer SHOULD free
+ and close circuits with the oldest reorder queue data, first. This heuristic
+ was shown to be best during the [SNIPER] attack OOM killer iteration cycle.
+
+ The rate limiting under LOW_MEM_LATENCY will be heuristic driven, based
+ on data from Shadow simulations, and live network testing. It is possible that
+ other algorithms may be able to be similarly rate limited.
+
+4.2. Protocol Side Channels [SIDE_CHANNELS]
+
+ To understand the decisions we make below with respect to handling
+ potential side channels, it is important to understand a bit of the history
+ of the Tor threat model.
+
+ Tor's original threat model completely disregarded all traffic analysis,
+ including protocol side channels, assuming that they were all equally
+ effective, and that diversity of relays was what provided protection.
+ Numerous attack papers have proven this to be an over-generalization.
+
+ Protocol side channels are most severe when a circuit is known to be silent,
+ because stateful protocol behavior prevents other normal cells from ever being
+ sent. In these cases, it is trivial to inject a packet count pattern that has
+ zero false positives. These kinds of side channels are made use of in the
+ Guard discovery literature, such as [ONION_FOUND], and [DROPMARK]. It is even
+ more trivial to manipulate the AES-CTR cipherstream, as per [RACOON23], until
+ we implement [PROP308].
+
+ However, because we do not want to make this problem worse, it is extremely
+ important to be mindful of ways that an adversary can inject new cell
+ commands, as well as ways that the adversary can spawn new circuits
+ arbitrarily.
+
+ It is also important, though slightly less so, to be mindful of the uniqueness
+ of new handshakes, as handshakes can be used to classify usage (such as via
+ Onion Service Circuit Fingerprinting). Handshake side channels are only
+ weakly defended, via padding machines for onion services. These padding
+ machines will need to be improved, and this is also scheduled for arti.
+
+ Finally, usage-based traffic analysis need to be considered. This includes
+ things like website traffic fingerprinting, and is covered in
+ [TRAFFIC_ANALYSIS].
+
+4.2.1. Cell Injection Side Channel Mitigations
+
+ To avoid [DROPMARK] attacks, several checks must be performed, depending
+ on the cell type. The circuit MUST be closed if any of these checks fail.
+
+ RELAY_CONFLUX_LINK:
+ - Ensure conflux is enabled
+ - Ensure the circuit is an Exit (or Service Rend) circuit
+ - Ensure that no previous LINK cell has arrived on this circuit
+
+ RELAY_CONFLUX_LINKED:
+ - Ensure conflux is enabled
+ - Ensure the circuit is client-side
+ - Ensure this is an unlinked circuit that sent a LINK command
+ - Ensure that the nonce matches the nonce used in the LINK command
+ - Ensure that the cell came from the expected hop
+
+ RELAY_CONFLUX_LINKED_ACK:
+ - Ensure conflux is enabled
+ - Ensure that this circuit is not client-side
+ - Ensure that the circuit has successfully received its LINK cell
+ - Ensure that this circuit has not received a LINKED_ACK yet
+
+ RELAY_CONFLUX_SWITCH
+ - If Prop#340 is in use, this cell MUST be packed with a valid
+ multiplexed RELAY_COMMAND cell.
+ - XXX: Additional rate limiting per algorithm, after tuning.
+
+4.2.2. Guard Discovery Side Channel Mitigations
+
+ In order to mitigate potential guard discovery by malicious exits,
+ clients MUST NOT retry failed unlinked circuit legs for a set more than
+ 'cfx_max_unlinked_leg_retry' times.
+
+4.2.3. Usage-Based Side Channel Discussion
+
+ After we have solved all of the zero false positive protocol side
+ channels in Tor, our attention can turn to more subtle, usage-based
+ side channels.
+
+ Two potential usage side channels may be introduced by the use of Conflux:
+ 1. Delay-based side channels, by manipulating switching
2. Location info leaks through the use of both leg's latencies
-
- For RTT and leg-use bias, Guard relays could delay legs to introduce a
- pattern into the delivery of cells at the exit relay, by varying the
- latency of SENDME cells (every 100th cell) to change the distribution of
- traffic to send information. This attack could be performed in either
- direction of traffic, to bias traffic load off of a particular Guard.
- If an adversary controls both Guards, it could in theory send a binary
- signal more easily, by alternating delays on each.
-
- However, this risk weighs against the potential benefits against traffic
- fingerprinting, as per [WTF_SPLIT]. Additionally, even ignoring
- cryptographic tagging attacks, this side channel provides significantly
- lower information over time than inter-packet-delay based side channels
- that are already available to Guards and routers along the path to the
- Guard.
-
- Tor currently provides no defenses against already existing
- single-circuit delay-based side channels, though both circuit padding
- and [BACKLIT] are potential options it could conceivably deploy. The
- [BACKLIT] paper also has an excellent review of the various methods that
- have been studied for such single circuit side channels, and the
- [BACKLIT] style RTT monitoring could be used to protect against these
- conflux side channels as well. Circuit padding can also help to obscure
- which cells are SENDMEs, since circuit padding is not counted towards
- SENDME totals.
-
+
+ To perform delay-based side channels, Exits can simply disregard the RTT
+ or cwnd when deciding to switch legs, thus introducing a pattern of gaps that
+ the Guard node can detect. Guard relays can also delay legs to introduce a
+ pattern into the delivery of cells at the exit relay, by varying the latency
+ of SENDME cells (every 31st cell) to change the distribution of traffic to
+ send information. This attack could be performed in either direction of
+ traffic, to bias traffic load off of a particular Guard. If an adversary
+ controls both Guards, it could in theory send a binary signal, by
+ alternating delays on each.
+
+ However, Tor currently provides no defenses against already existing
+ single-circuit delay-based (or stop-and-start) side channels. It is already
+ the case that on a single circuit, either the Guard or the Exit can simply
+ withhold sending traffic, as per a recognizable pattern. This class of
+ attacks, and a possible defense for them, is discussed in [BACKLIT].
+
+ However, circuit padding can also help to obscure these side channels,
+ even if tuned for website fingerprinting. See [TRAFFIC_ANALYSIS] for more
+ details there.
+
The second class of side channel is where the Exit relay may be able to
use the two legs to further infer more information about client
location. See [LATENCY_LEAK] for more details. It is unclear at this
time how much more severe this is for two paths than just one.
-
+
We preserve the ability to disable conflux to and from Exit relays
using consensus parameters, if these side channels prove more severe,
or if it proves possible possible to mitigate single-circuit side
channels, but not conflux side channels.
-
- In all cases, all of these side channels appear less severe for onion
- service traffic, due to the higher path variability due to relay
- selection, as well as the end-to-end nature of conflux in that case.
- Thus, we separate our ability to enable/disable conflux for onion
- services from Exits.
4.3. Traffic analysis [TRAFFIC_ANALYSIS]
Even though conflux shows benefits against traffic analysis in
[WTF_SPLIT], these gains may be moot if the adversary is able to perform
packet counting and timing analysis at guards to guess which specific
- circuits are linked. In particular, the 3 way handshake in
+ circuits are linked. In particular, the 3 way handshake in
[LINKING_CIRCUITS] may be quite noticeable.
-
- As one countermeasure, it may be possible to eliminate the third leg
- (RELAY_CIRCUIT_LINKED_RTT_ACK) by computing the exit/service RTT via
- measuring the time between CREATED/REND_JOINED and RELAY_CIRCUIT_LINK,
- but this will introduce cross-component complexity into Tor's protocol
- that could quickly become unwieldy and fragile.
-
+
Additionally, the conflux handshake may make onion services stand out
more, regardless of the number of stages in the handshake. For this
- reason, it may be more wise to simply address these issues with circuit
+ reason, it may be wise to simply address these issues with circuit
padding machines during circuit setup (see padding-spec.txt).
-
+
Additional traffic analysis considerations arise when combining conflux
with padding, for purposes of mitigating traffic fingerprinting. For
this, it seems wise to treat the packet schedulers as another piece of a
@@ -653,7 +854,7 @@ Status: Draft
machines, perhaps introducing randomness or fudge factors their
scheduling, as a parameterized distribution. For details, see
https://github.com/torproject/tor/blob/master/doc/HACKING/CircuitPaddingDevelopment.md
-
+
Finally, conflux may exacerbate forms of confirmation-based traffic
analysis that close circuits to determine concretely if they were in
use, since closing either leg might cause resumption to fail. TCP RST
@@ -661,44 +862,58 @@ Status: Draft
capability. [RESUMPTION] with buffering of the inflight unacked
package_window data, for retransmit, is a partial mitigation, if
endpoints buffer this data for retransmission for a brief time even if
- both legs close. This seems more feasible for onion services, which are
- more vulnerable to this attack. However, if the adversary controls the
- client, they will notice the resumption re-link, and still obtain
+ both legs close. This buffering seems more feasible for onion services,
+ which are more vulnerable to this attack. However, if the adversary
+ controls the client and is attacking the service in this way, they
+ will notice the resumption re-link at their client, and still obtain
confirmation that way.
-
+
It seems the only way to fully mitigate these kinds of attacks is with
the Snowflake pluggable transport, which provides its own resumption and
retransmit behavior. Additionally, Snowflake's use of UDP DTLS also
protects against TCP RST injection, which we suspect to be the main
vector for such attacks.
-
+
In the future, a DTLS or QUIC transport for Tor such as masque could
provide similar RST injection resistance, and resumption at Guard/Bridge
nodes, as well.
+5. Consensus Parameters [CONSENSUS]
-5. System Interactions
+ - cfx_enabled
+ - Values: 0=off, 1=on
+ - Description: Emergency off switch, in case major issues are discovered.
- - congestion control
- - EWMA and KIST
- - CBT and number of guards
- - Onion service circ obfuscation
- - Future UDP (may increase need for UDP to buffer before dropping)
- - Padding (no sequence numbers on padding cells, as per [SEQUENCING])
- - Also, any padding machines may need re-tuning
- - No 'cannibalization' of linked circuits
+ - cfx_low_exit_threshold
+ - Range: 0-10000
+ - Description: Fraction out of 10000 that represents the fractional rate of
+ exits that must support protover 5. If the fraction is below this
+ amount, the number of pre-built sets is restricted to 1.
+ - cfx_max_linked_set
+ - Range: 0-255
+ - Description: The total number of linked sets that can be created. 255
+ means "unlimited".
-6. Consensus and Torrc Parameters [CONSENSUS]
+ - cfx_max_prebuilt_set
+ - Range: 0-255
+ - Description: The maximum number of pre-built conflux sets to make.
+ This value is overridden by the 'cfx_low_exit_threshold' criteria.
- - conflux_circs
- - Number of conflux circuits
+ - cfx_max_unlinked_leg_retry
+ - Range: 0-255
+ - Description: The maximum number of times to retry an unlinked leg that
+ fails during build or link, to mitigate guard discovery attacks.
- - conflux_sched_exits, conflux_sched_clients, conflux_sched_service
- - Three forms of LOWRTT_TOR, and BLEST_TOR
+ - cfx_num_legs_set
+ - Range: 0-255
+ - Description: The number of legs to link in a set.
- - ConfluxOnionService
- - ConfluxOnionCircs
+ - cfx_send_pct
+ - XXX: Experimental tuning parameter. Subject to change/removal.
+
+ - cfx_drain_pct
+ - XXX: Experimental tuning parameter. Subject to change/removal.
7. Tuning Experiments [EXPERIMENTS]
@@ -713,51 +928,11 @@ Status: Draft
Appended A [ALTERNATIVES]
-A.1 BEGIN/END sequencing [ALTERNATIVE_SEQUENCING]
-
- In this method of signaling, we increment the sequence number by 1 only
- when we switch legs, and use BEGIN/END "bookends" to know that all data
- on a leg has been received.
-
- To achieve this, we add a small sequence number to the common relay
- header for all relay cells on linked circuits, as well as a field to
- signal the beginning of a sequence, intermediate data, and the end of a
- sequence.
-
- Relay command [1 byte]
- Recognized [2 bytes]
- StreamID [2 bytes]
- Digest [4 bytes]
- Length [2 bytes]
- > Switching [2 bits] # 01 = BEGIN, 00 = CONTINUE, 10 = END
- > Sequencing [6 bits]
- Data [PAYLOAD_LEN - 12 - Length bytes]
-
- These fields MUST be present on ALL end-to-end relay cells on each leg
- that come from the endpoint, following a RELAY_CIRCUIT_LINK command.
-
- They are absent on 'leaky pipe' RELAY_COMMAND_DROP and
- RELAY_COMMAND_PADDING_NEGOTIATED cells that come from middle relays, as
- opposed to the endpoint, to support padding.
-
- Sequence numbers are incremented by one when an endpoint switches legs
- to transmit a cell. This number will wrap; implementations MUST treat
- 0 as the next sequence after 2^6-1. Because we do not expect to support
- significantly more than 2 legs, and much fewer than 63, this is not an
- issue.
-
- The first cell on a new circuit MUST use the BEGIN code for switching.
- Cells are delivered from that circuit until an END switching signal is
- received, even if cells arrive first on another circuit with the next
- sequence number before and END switching field. Recipients MUST only
- deliver cells with a BEGIN, if their Sequencing number is one more than
- the last END.
-
-A.2 Alternative Link Handshake [ALTERNATIVE_LINKING]
+A.1 Alternative Link Handshake [ALTERNATIVE_LINKING]
The circuit linking in [LINKING_CIRCUITS] could be done as encrypted
ntor onionskin extension fields, similar to those used by v3 onions.
-
+
This approach has at least four problems:
i). For onion services, since onionskins traverse the intro circuit
and return on the rend circuit, this handshake cannot measure
@@ -771,58 +946,58 @@ A.2 Alternative Link Handshake [ALTERNATIVE_LINKING]
iv). The overhead in processing this onionskin in onionskin queues
adds additional time for linking, even in the Exit case, making
that RTT potentially noisy.
-
+
Additionally, it is not clear that this approach actually saves us
anything in terms of setup time, because we can optimize away the
- linking phase using Proposal 325, to combine initial RELAY_BEGIN cells
+ linking phase using Proposal 340, to combine initial RELAY_BEGIN cells
with RELAY_CIRCUIT_LINK.
-A.3. Alternative RTT measurement [ALTERNATIVE_RTT]
+A.2. Alternative RTT measurement [ALTERNATIVE_RTT]
Instead of measuring RTTs during [LINKING_CIRCUITS], we could create
PING/PONG cells, whose sole purpose is to allow endpoints to measure
RTT.
-
+
This was rejected for several reasons. First, during circuit use, we
already have SENDMEs to measure RTT. Every 100 cells (or
'circwindow_inc' from Proposal 324), we are able to re-measure RTT based
on the time between that Nth cell and the SENDME ack. So we only need
PING/PONG to measure initial circuit RTT.
-
+
If we were able to use onionskins, as per [ALTERNATIVE_LINKING] above,
we might be able to specify a PING/PONG/PING handshake solely for
measuring initial RTT, especially for onion service circuits.
-
+
The reason for not making a dedicated PING/PONG for this purpose is that
it is context-free. Even if we were able to use onionskins for linking
and resumption, to avoid additional data in handshake that just measures
RTT, we would have to enforce that this PING/PONG/PING only follows the
exact form needed by this proposal, at the expected time, and at no
other points.
-
+
If we do not enforce this specific use of PING/PONG/PING, it becomes
another potential side channel, for use in attacks such as [DROPMARK].
-
+
In general, Tor is planning to remove current forms of context-free and
semantic-free cells from its protocol:
https://gitlab.torproject.org/tpo/core/torspec/-/issues/39
-
+
We should not add more.
-Appendix B: Acknowledgments [ACKNOWLEDGEMENTS]
+Appendix B: Acknowledgments [ACKNOWLEDGMENTS]
Thanks to Per Hurtig for helping us with the framing of the MPTCP
problem space.
-
+
Thanks to Simone Ferlin for clarifications on the [BLEST] paper, and for
pointing us at the Linux kernel implementation.
-
+
Extreme thanks goes again to Toke Høiland-Jørgensen, who helped
immensely towards our understanding of how the BLEST condition relates
to edge connection pushback, and for clearing up many other
misconceptions we had.
-
+
Finally, thanks to Mashael AlSabah, Kevin Bauer, Tariq Elahi, and Ian
Goldberg, for the original [CONFLUX] paper!
@@ -859,3 +1034,22 @@ References:
[DROPMARK]
https://www.petsymposium.org/2018/files/papers/issue2/popets-2018-0011.pdf
+
+[RACCOON23]
+ https://archives.seul.org/or/dev/Mar-2012/msg00019.html
+
+[ONION_FOUND]
+ https://www.researchgate.net/publication/356421302_From_Onion_Not_Found_to_Guard_Discovery/fulltext/619be24907be5f31b7ac194a/From-Onion-Not-Found-to-Guard-Discovery.pdf
+
+[VANGUARDS_ADDON]
+ https://github.com/mikeperry-tor/vanguards/blob/master/README_TECHNICAL.md
+
+[PROP324]
+ https://gitlab.torproject.org/tpo/core/torspec/-/blob/main/proposals/324-rtt-congestion-control.txt
+
+[PROP339]
+ https://gitlab.torproject.org/tpo/core/torspec/-/blob/main/proposals/339-udp-over-tor.md
+
+[PROP308]
+ https://gitlab.torproject.org/tpo/core/torspec/-/blob/main/proposals/308-counter-galois-onion.txt
+```
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 b76a451..10f0dd4 100644
--- a/proposals/332-ntor-v3-with-extra-data.md
+++ b/proposals/332-ntor-v3-with-extra-data.md
@@ -3,7 +3,7 @@ Filename: 332-ntor-v3-with-extra-data.md
Title: Ntor protocol with extra data, version 3.
Author: Nick Mathewson
Created: 12 July 2021
-Status: Finished
+Status: Closed
```
# Overview
@@ -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/333-vanguards-lite.md b/proposals/333-vanguards-lite.md
index 5e62b03..1e83046 100644
--- a/proposals/333-vanguards-lite.md
+++ b/proposals/333-vanguards-lite.md
@@ -3,7 +3,7 @@ Filename: 333-vanguards-lite.md
Title: Vanguards lite
Author: George Kadianakis, Mike Perry
Created: 2021-05-20
-Status: Finished
+Status: Closed
Implemented-In: 0.4.7.1-alpha
```
@@ -46,14 +46,14 @@ Implemented-In: 0.4.7.1-alpha
Service intro: C -> G -> L2 -> M -> Intro
Service hsdir: C -> G -> L2 -> M -> HSDir
-# 3. Rotation Period Analysis
+# 2. Rotation Period Analysis
From the table in Section 3.1 of Proposal 292, with NUM_LAYER2_GUARDS=4 it
can be seen that this means that the Sybil attack on Layer2 will complete
with 50% chance in 18*7 days (126 days) for the 1% adversary, 4*7 days (one
month) for the 5% adversary, and 2*7 days (two weeks) for the 10% adversary.
-# 4. Tradeoffs from Proposal 292
+# 3. Tradeoffs from Proposal 292
This proposal has several advantages over Proposal 292:
@@ -69,7 +69,25 @@ Implemented-In: 0.4.7.1-alpha
protected, and this proposal might provide those services with a false sense
of security. Such services should still use the vanguards addon [VANGUARDS_REF].
-# 4. References
+# 4. Implementation nuances
+
+ Tor replaces an L2 vanguard whenever it is no longer listed in the most
+ recent consensus, with the goal that we will always have the right
+ number of vanguards ready to be used.
+
+ For implementation reasons, we also replace a vanguard if it loses
+ the Fast or Stable flag, because the path selection logic wants middle
+ nodes to have those flags when it's building preemptive vanguard-using
+ circuits.
+
+ The design doesn't have to be this way: we might instead have chosen
+ to keep vanguards in our list as long as possible, and continue to use
+ them even if they have lost some flags. This tradeoff is similar to
+ the one in https://bugs.torproject.org/17773 about whether to continue
+ using Entry Guards if they lose the Guard flag -- and Tor's current
+ choice is "no, rotate" for that case too.
+
+# 5. References
[PROP292_REF]: https://gitlab.torproject.org/tpo/core/torspec/-/blob/main/proposals/292-mesh-vanguards.txt
[VANGUARDS_REF]: https://github.com/mikeperry-tor/vanguards
diff --git a/proposals/334-middle-only-flag.txt b/proposals/334-middle-only-flag.txt
index 823e927..c011b6c 100644
--- a/proposals/334-middle-only-flag.txt
+++ b/proposals/334-middle-only-flag.txt
@@ -1,3 +1,4 @@
+```
Filename: 334-middle-only-flag.txt
Title: A Directory Authority Flag To Mark Relays As Middle-only
Author: Neel Chauhan
@@ -114,3 +115,4 @@ Superseded-by: 335-middle-only-redux.md
[2] - https://lists.torproject.org/pipermail/tor-dev/2021-September/014627.html
[3] - https://lists.torproject.org/pipermail/tor-dev/2021-September/014630.html
+```
diff --git a/proposals/336-randomize-guard-retries.md b/proposals/336-randomize-guard-retries.md
index 05cf1c3..0e819d4 100644
--- a/proposals/336-randomize-guard-retries.md
+++ b/proposals/336-randomize-guard-retries.md
@@ -3,9 +3,15 @@ Filename: 336-randomize-guard-retries.md
Title: Randomized schedule for guard retries
Author: Nick Mathewson
Created: 2021-10-22
-Status: Accepted
+Status: Closed
```
+# Implementation Status
+
+> This proposal is implemented in Arti, and recommended for future
+> guard implementations. We have no current plans to implement it in
+> C Tor.
+
# Introduction
When we notice that a guard isn't working, we don't mark it as retriable
diff --git a/proposals/337-simpler-guard-usability.md b/proposals/337-simpler-guard-usability.md
index 898c6e0..a2f93f7 100644
--- a/proposals/337-simpler-guard-usability.md
+++ b/proposals/337-simpler-guard-usability.md
@@ -3,7 +3,7 @@ Filename: 337-simpler-guard-usability.md
Title: A simpler way to decide, "Is this guard usable?"
Author: Nick Mathewson
Created: 2021-10-22
-Status: Accepted
+Status: Closed
```
# Introduction
diff --git a/proposals/339-udp-over-tor.md b/proposals/339-udp-over-tor.md
index 2dbe3b5..e5235d1 100644
--- a/proposals/339-udp-over-tor.md
+++ b/proposals/339-udp-over-tor.md
@@ -3,7 +3,7 @@ Filename: 339-udp-over-tor.md
Title: UDP traffic over Tor
Author: Nick Mathewson
Created: 11 May 2020
-Status: Draft
+Status: Accepted
```
# Introduction
@@ -11,7 +11,7 @@ Status: Draft
Tor currently only supports delivering two kinds of traffic to the
internet: TCP data streams, and a certain limited subset of DNS
requests. This proposal describes a plan to extend the Tor protocol so
-that exit relays can also relay UDP traffic to the network?.
+that exit relays can also relay UDP traffic to the network.
Why would we want to do this? There are important protocols that use
UDP, and in order to support users that rely on these protocols, we'll
@@ -149,6 +149,42 @@ along with extensions to some older relay message types. We note in
passing how we could extend these messages to support unconnected UDP
sockets in the future.
+### Common Format
+
+We define here a common format for an "address" that is used both in a
+CONNECT_UDP and CONNECTED_UDP cell.
+
+#### Address
+
+Defines an IP or Hostname address along with its port. This can be seen as the
+`ADDRPORT` of a `BEGIN` cell defined in tor-spec.txt but with a different
+format.
+
+```
+/* Address types.
+
+ Note that these are the same as in RESOLVED cells.
+*/
+const T_HOSTNAME = 0x00;
+const T_IPV4 = 0x04;
+const T_IPV6 = 0x06;
+
+struct address {
+ u8 type IN [T_IPV4, T_IPV6, T_HOSTNAME];
+ u8 len;
+ union addr[type] with length len {
+ T_IPV4: u32 ipv4;
+ T_IPV6: u8 ipv6[16];
+ T_HOSTNAME: u8 hostname[];
+ };
+ u16 port;
+}
+```
+
+The `hostname` follows the RFC1035 for its accepted length that is 63
+characters or less that is a `len` between 0 and 255 (bytes). It should
+contain a sequence of nonzero octets as in any nul byte results in a malformed
+cell.
### CONNECT_UDP
@@ -161,26 +197,13 @@ sockets in the future.
struct connect_udp_body {
/* As in BEGIN cells. */
u32 flags;
- /* Tag for union below. */
- u8 addr_type IN [T_HOSTNAME, T_IPV4, T_IPV6];
- /* Length of the following union */
- u8 addr_len;
- /* The address to connect to. */
- union address[addr_type] with length addr_len {
- T_IPV4: u32 ipv4;
- T_IPV6: u8 ipv6[16];
- T_HOSTNAME: nulterm name
- };
- u16 port;
+ /* Address to connect to. */
+ struct address addr;
// The rest is ignored.
// TODO: Is "the rest is ignored" still a good idea? Look at Rochet's
// research.
}
-/* Address types */
-const T_HOSTNAME = 0x01;
-const T_IPV4 = 0x04;
-const T_IPV6 = 0x06;
/* As in BEGIN cells: these control how hostnames are interpreted.
Clients MUST NOT send unrecognized flags; relays MUST ignore them.
@@ -191,6 +214,10 @@ const FLAG_IPV4_NOT_OKAY = 0x02;
const FLAG_IPV6_PREFERRED = 0x04;
```
+A "hostname" is a DNS hostname that can only contain ascii characters. It is
+NOT following the large and broad DNS syntax. These behaves exacly like BEGIN
+cell behave with regards to the hostname given.
+
### CONNECTED_UDP
A CONNECTED_UDP cell sent in response to a CONNECT_UDP cell has the following
@@ -198,12 +225,6 @@ format.
```
struct udp_connected_body {
- /* 5 bytes to distinguish from other CONNECTED_UDP cells. This is not
- * strictly necessary, since we can distinguish by context, but
- * it's nice to have a way to tell them apart at the parsing stage.
- */
- u32 zero IN [0];
- u8 ff IN [0xFF];
/* The address that the relay has bound locally. This might not
* be an address that is advertised in the relay's descriptor. */
struct address our_address;
@@ -214,27 +235,17 @@ struct udp_connected_body {
// TODO: Is "the rest is ignored" still a good idea? Look at Rochet's
// research.
}
-
-/* Note that this is a subset of the allowable address parts of a CONNECT_UDP
- message */
-struct address {
- u8 tag IN [T_IPV4, T_IPV6];
- u8 len;
- union addr[tag] with length len {
- T_IPV4: u32 ipv4;
- T_IPV6: u8 ipv6[16];
- };
- u16 port;
-}
```
+Both `our_address` and `their_address` MUST NOT be of type `T_HOSTNAME` else
+the cell is considered malformed.
+
### DATAGRAM
```
struct datagram_body {
/* The datagram body is the entire body of the message.
- This length is in the relay message header.
- */
+ * This length is in the relay message header. */
u8 body[..];
}
```
@@ -253,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
new file mode 100644
index 0000000..cd98cfd
--- /dev/null
+++ b/proposals/340-packed-and-fragmented.md
@@ -0,0 +1,516 @@
+```
+Filename: 340-packed-and-fragmented.md
+Title: Packed and fragmented relay messages
+Author: Nick Mathewson
+Created: 31 May 2022
+Status: Open
+```
+
+# Introduction
+
+Tor sends long-distance messages on circuits via _relay cells_. The
+current relay cell format allows one _relay message_ (e.g., "BEGIN" or
+"DATA" or "END") per relay cell. We want to relax this 1:1 requirement,
+between messages and cells, for two reasons:
+
+ * To support relay messages that are longer than the current 498-byte
+ limit. Applications would include wider handshake messages for
+ postquantum crypto, UDP messages, and SNIP transfer in walking
+ onions.
+
+ * To transmit small messages more efficiently. Several message types
+ (notably `SENDME`, `XON`, `XOFF`, and several types from
+ [proposal 329](./329-traffic-splitting.txt)) are much smaller than
+ the relay cell size, and could be sent comparatively often.
+ We also want to be able to *hide* the transmission of small control messages
+ by packing them into what would have been the padding of other messages,
+ making them effectively invisible to a network traffic observer.
+
+In this proposal, we describe a way to decouple relay cells from relay
+messages. Relay messages can now be packed into multiple cells or split
+across multiple cells.
+
+This proposal combines ideas from
+[proposal 319](./319-wide-everything.md) (fragmentation) and
+[proposal 325](./325-packed-relay-cells.md) (packed cells). It requires
+[ntor v3](./332-ntor-v3-with-extra-data.md) and prepares for
+[next-generation relay cryptography](./308-counter-galois-onion.md).
+
+Additionally, this proposal has been revised to incorporate another
+protocol change, and move StreamId from the relay cell header into a new,
+optional header.
+
+## A preliminary change: Relay encryption, version 1.5
+
+We are fairly sure that, whatever we do for our next batch of relay
+cryptography, we will want to increase the size of the data used to
+authenticate relay cells to 128 bits. (Currently it uses a 4-byte tag
+plus 2 bytes of zeros.)
+
+To avoid proliferating formats, I'm going to suggest that we make the
+other changes in this proposal changes concurrently with a change in our
+relay cryptography, so that we do not have too many incompatible cell
+formats going on at the same time.
+
+The new format for a decrypted relay _cell_ will be:
+
+```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`
+is truncated to 14 bytes instead of 4.
+
+If we are lucky, we won't have to build this encryption at all, and we
+can just move to some version of GCM-UIV or other RPRP that reserves 16
+bytes for an authentication tag or similar cryptographic object.
+
+The `body` MUST contain exactly 493 bytes as relay cells have a fixed size.
+
+## New relay message packing
+
+We define this new format for a relay message. We require that
+both header parts fit in a single RELAY cell.
+However, the body can be split across many relay cells:
+
+```
+ Message Header
+ command u8
+ length u16
+ Message Routing Header (optional)
+ stream_id u16
+ Message Body
+ data u8[length]
+```
+
+One big change from the current tor protocol is something that has become
+optional: we have moved `stream_id` into a separate inner header that only
+appears sometimes named the Message Routing Header. The command value tells us
+if the header is to be expected or not.
+
+The following message types take required stream IDs: `BEGIN`, `DATA`, `END`,
+`CONNECTED`, `RESOLVE`, `RESOLVED`, and `BEGIN_DIR`, `XON`, `XOFF`.
+
+The following message types from proposal 339 (UDP) take required stream IDs:
+`CONNECT_UDP`, `CONNECTED_UDP` and `DATAGRAM`.
+
+No other current message types take stream IDs. The `stream_id` field, when
+present, MUST NOT be zero.
+
+Messages can be split across relay cells; multiple messages can occur in
+a single relay cell. We enforce the following rules:
+
+ * Headers may not be split across cells.
+ * If a 0 byte follows a message body, there are no more messages.
+ * A message body is permitted to end at exactly the end of a relay cell,
+ without a 0 byte afterwards.
+ * A relay cell may not be "empty": it must have at least some part of
+ some message.
+
+Unless specified elsewhere, **all** message types may be packed, and
+**all** message types may be fragmented.
+
+Every command has an associated maximum length for its messages. If not
+specified elsewhere, the maximum length for every message is 498 bytes (for
+legacy reasons).
+
+Receivers MUST validate that the cell `header` and the `message header` are
+well-formed and have valid lengths while handling the cell in which the header
+is encoded. If any of them is invalid, the circuit MUST be destroyed.
+
+A message header with an unrecognized `command` is considered invalid and thus
+MUST result in the circuit being immediately destroyed (without waiting for the
+rest of the relay message to arrive, in the case of a fragmented message).
+
+## New subprotocol `RelayCell`
+
+We introduce a new subprotocol `RelayCell` to specify the relay cell ABI. The
+new format specified in this proposal, supporting packing and fragmentation,
+corresponds to `RelayCell` version 1. The ABI prior to this proposal is
+`RelayCell` version 0.
+
+All clients and relays implicitly support `RelayCell` version 0.
+
+> XXX: Do we want to consider some migration path for eventually removing
+> support for `RelayCell` version 0? e.g. maybe this should be something like
+> "Support for any of `Relay` versions 1-5 imply support for `RelayCell`
+> version 0"?
+
+We reserve the protocol ID 13 for binary encoding of this subprotocol with
+respect to [proposal 346][prop346] and [proposal 323][prop323].
+
+To use `RelayCell` version 1 or greater with a given relay on a given circuit,
+the client negotiates it using an `ntor_v3` extension, as per [proposal
+346][prop346]. This implies that the relay must advertise support for `Relay`
+version 5 (`ntor_v3` circuit extensions) as well as the target `RelayCell`
+version (1 for the format introduced in this proposal).
+
+Circuits using mixed `RelayCell` versions are permitted. e.g. we anticipate
+some of the use-cases for packing and fragmentation to only need the exit-relay
+to support it. Not requiring `RelayCell=1` for other relays in the circuit
+provides a larger pool of candidate relays. While an intermediate relay using a
+different `RelayCell` version than the destination relay of a given relay cell
+will look at the wrong bytes for the `recognized` and `digest` fields, they
+will reach the correct conclusion that the cell is not intended for them and
+pass it to the next hop in the circuit.
+
+## Migration
+
+> Note: This differs from what we decided was our new best-practices.
+> Should we make this disableable at all?
+
+We add a consensus parameter, "streamed-relay-messages", with default
+value 0, minimum value 0, and maximum value 1.
+
+If this value is 0, then clients will not (by default) negotiate this
+relay protocol. If it is 1, then clients will negotiate it when relays
+support it.
+
+For testing, clients can override this setting. Once enough relays
+support this proposal, we'll change the consensus parameter to 1.
+Later, we'll change the default to 1 as well.
+
+## Packing decisions
+
+We specify the following greedy algorithm for making decisions about
+fragmentation and packing. Other algorithms are possible, but this one
+is fairly simple, and using it will help avoid distinguishability
+issues:
+
+Whenever a client or relay is about to send a cell that would leave
+at least 32 bytes unused in a relay cell, it checks to see whether there
+is any pending data to be sent in the same circuit (in a data cell). If
+there is, then it adds a DATA message to the end of the current cell,
+with as much data as possible. Otherwise, the client sends the cell
+with no packed data.
+
+> XXX: This isn't quite right. What was actually implemented in tor, and
+> what we want in arti, is to defer sending some "control" messages like
+> confluence switch and (non-first) xon, until they can be invisibly packed
+> into a cell for a DATA message.
+>
+> dgoulet: Could you update this section with the concrete details, and exactly
+> what property we're trying to achieve? e.g.:
+>
+> If we have data to send, but the corresponding DATA messages don't leave
+> enough room to pack in the deferred control message(s), what do we do? If we
+> continue deferring could we end up deferring forever if the application
+> always writes in chunks that happen to align this way?
+>
+> Since cells containing any part of a DATA message is subject to congestion
+> windows, does that mean if our congestion window is empty we can't send these
+> control messages either (until the window becomes non-empty)?
+
+## Onion services
+
+Negotiating this for onion services will happen in a separate proposal;
+it is not a current priority, since there is nothing sent over
+rendezvous circuits that we currently need to fragment or pack.
+
+## Miscellany
+
+### Handling `RELAY_EARLY`
+
+The `RELAY_EARLY` status for a command is determined based on the relay
+cell in which the command's _header_ appeared.
+
+Thus, a relay MUST close a circuit if the cell containing the _first_
+fragment of an `EXTEND` message is not `RELAY_EARLY`, and MUST allow
+but NOT require `RELAY_EARLY` to be set on other cells.
+
+This implies that a client only _needs_ to set `RELAY_EARLY` on the cell
+containing the _first_ fragment of an EXTEND message, but that it MAY
+set RELAY_EARLY on other cells, in order to prevent traffic fingerprinting.
+
+(Note: As now, relays and clients MUST destroy any circuit upon seeing a
+`RELAY_EARLY` message in the inbound direction.)
+
+> In our implementation, clients will continue to set `RELAY_EARLY` on
+> the first N cells of each circuit, as we do today.
+
+> Note that this description allows us to take two approaches when
+> we eventually _do_ support fragmented `EXTEND` messages. We can
+> either set the `RELAY_EARLY` flag on the cell containing the first
+> fragment only, or we can continue to set it on the first N cells
+> sent on each circuit. Both will work fine, assuming that the
+> limit of `RELAY_EARLY` cells is adjustable. This brings us to:
+
+#### Making the `RELAY_EARLY` limit adjustable
+
+We add the following parameter, to support an eventual migration to
+longer extend cells, in case we decide to take the second approach in
+our note above.
+
+ "max_early_per_circ" -- Relays MUST destroy any circuit on
+ which they see more than this number of RELAY_EARLY cells.
+ Min: 5. Max: 65535. Default: 8.
+
+
+### Handling `SENDME`s
+
+SENDME messages may not be fragmented; the body and the command must
+appear in the same cell. (This is necessary so authenticated sendmes
+can have a reasonable implementation.)
+
+### Interaction with Conflux
+
+Fragmented messages may be used together with Conflux, but we do not
+allow fragments from a single method to be sent on separate legs of
+a single circuit bundle.
+
+That is to say, it is an error to send a CONFLUX_SWITCH message if
+the SeqNum would leave any other circuit with an incomplete message
+where not all framgents have arrived. Upon receiving such an
+erroneous message, parties SHOULD destroy all circuits in the
+conflux bundle.
+
+### An exception for `DATA`.
+
+Data messages may not be fragmented. When packing data into a cell containing
+other messages is desired, the application can instead construct a DATA message
+of an appropriate size to fit into the remaining space.
+
+While relaxing this could simplify the implementation of opportunistic packing
+somewhat (by allowing code that constructs `DATA` messages not to have to know
+about packing or fragmentation), doing so would have several downsides.
+
+First, on the receiver side a naive implementation that receives the first cell
+of a fragmented `DATA` message would not be able to pass the data in that
+fragment on to the application until the remaining cells of that message are
+received. An optimized implementation might choose to do so, but that
+complexity seems worse than the complexity we'd be avoiding by allowing `DATA`
+fragmentation in the first place.
+
+Second, as with any sort of flexibility permitted to implementations, allowing
+flexibility here adds opportunities for fingerprinting and covert channels.
+
+### Extending message-length maxima
+
+For now, the maximum length for every message body is 493 bytes, except as
+follows:
+
+ - `DATAGRAM` messages (see proposal 339) have a maximum body length
+ of 1967 bytes. (This works out to four relay cells, and
+ accommodates most reasonable MTU choices)
+
+Any increase in maximum length for any other message type requires a new
+`RelayCell` subprotocol version. (For example, if we later want to allow
+EXTEND2 messages to be 2000 bytes long, we need to add a new proposal
+saying so, and reserving a new subprotocol version.)
+
+### `SENDME` window accounting
+
+`SENDME` windows count relay *cells* rather than relay *messages*.
+
+A cell counts towards the circuit's `SENDME` window if it contains any part of
+any message that would normally count towards `SENDME` windows (currently only
+`DATA`).
+
+A cell counts towards the `SENDME` window of every stream that it contains
+part of a message for, whose command counts towards `SENDME` windows.
+
+Examples:
+
+* A cell containing a `SENDME` message and a `RESOLVE` message currently
+ wouldn't count towards any windows, since neither of those commands currently
+ counts towards windows.
+* A cell containing a `SENDME` message and a `DATA` message would count towards
+ the circuit window and the `DATA` message's stream's window.
+* A cell containing two `DATA` messages, for different streams, would count
+ towards the circuit-level window and both stream-level windows.
+* A cell containing two `DATA` messages for the *same* stream counts
+ *once* towards the circuit-level and stream-level windows.
+* If `DATAGRAM` messages (proposal 339) are implemented, and count towards
+ windows, then every cell containing a fragment of a `DATAGRAM` message counts
+ towards windows.
+
+# Appendix: Example cells
+
+Here is an example of the simplest case: one message, sent in one relay cell:
+
+```
+ Cell 1:
+ header:
+ circid .. [4 bytes]
+ command RELAY [1 byte]
+ relay cell header:
+ recognized 0 [2 bytes]
+ digest (...) [14 bytes]
+ message header:
+ command BEGIN [1 byte]
+ length 23 [2 bytes]
+ message routing header:
+ stream_id 42 [2 bytes]
+ message body:
+ "www.torproject.org:443\0" [23 bytes]
+ end-of-messages marker:
+ 0 [1 byte]
+ padding up to end of cell:
+ random [464 bytes]
+```
+
+Total of 514 bytes which is the absolute maximum relay cell size.
+
+A message whose body ends at exactly the end of a relay cell has no
+corresponding end-of-messages marker.
+
+```
+ Cell 1:
+ header:
+ circid .. [4 bytes]
+ command RELAY [1 byte]
+ relay cell header:
+ recognized 0 [2 bytes]
+ digest (...) [14 bytes]
+ message header:
+ command DATA [1 byte]
+ length 488 [2 bytes]
+ message routing header:
+ stream_id 42 [2 bytes]
+ message body:
+ (data) [488 bytes]
+```
+
+Here's an example with fragmentation only: a large EXTEND2 message split
+across two relay cells.
+
+```
+ Cell 1:
+ header:
+ circid .. [4 bytes]
+ command RELAY_EARLY [1 byte]
+ relay cell header:
+ recognized 0 [2 bytes]
+ digest (...) [14 bytes]
+ message header:
+ command EXTEND [1 byte]
+ length 800 [2 bytes]
+ message body:
+ (extend body, part 1) [490 bytes]
+
+ Cell 2:
+ header:
+ circid .. [4 bytes]
+ command RELAY [1 byte]
+ relay cell header:
+ recognized 0 [2 bytes]
+ digest (...) [14 bytes]
+ message body, continued:
+ (extend body, part 2) [310 bytes] (310+490=800)
+ end-of-messages marker:
+ 0 [1 byte]
+ padding up to end of cell:
+ random [182 bytes]
+```
+
+Each cells are 514 bytes for a message body totalling 800 bytes.
+
+Here is an example with packing only: A `BEGIN_DIR` message and a data message
+in the same cell.
+
+```
+ Cell 1:
+ header:
+ circid .. [4 bytes]
+ command RELAY [1 byte]
+ relay cell header:
+ recognized 0 [2 bytes]
+ digest (...) [14 bytes]
+
+ # First relay message
+ message header:
+ command BEGIN_DIR [1 byte]
+ length 0 [2 bytes]
+ message routing header:
+ stream_id 32 [2 bytes]
+
+ # Second relay message
+ message header:
+ command DATA [1 byte]
+ length 25 [2 bytes]
+ message routing header:
+ stream_id 32 [2 bytes]
+ message body:
+ "HTTP/1.0 GET /tor/foo\r\n\r\n" [25 bytes]
+
+ end-of-messages marker:
+ 0 [1 byte]
+ padding up to end of cell:
+ random [457 bytes]
+
+```
+
+Here is an example with packing and fragmentation: a large DATAGRAM cell, a
+SENDME cell, and an XON cell.
+
+(Note that this sequence of cells would not actually be generated by the
+algorithm described in "Packing decisions" above; this is only an example of
+what parties need to accept.)
+
+```
+ Cell 1:
+ header:
+ circid .. [4 bytes]
+ command RELAY [1 byte]
+ relay cell header:
+ recognized 0 [2 bytes]
+ digest (...) [14 bytes]
+
+ # First message
+ message header:
+ command DATAGRAM [1 byte]
+ length 1200 [2 bytes]
+ message routing header:
+ stream_id 99 [2 bytes]
+ message body:
+ (datagram body, part 1) [488 bytes]
+
+ Cell 2:
+ header:
+ circid .. [4 bytes]
+ command RELAY [1 byte]
+ relay cell header:
+ recognized 0 [2 bytes]
+ digest (...) [14 bytes]
+ message body, continued:
+ (datagram body, part 2) [493 bytes]
+
+ Cell 3:
+ header:
+ circid .. [4 bytes]
+ command RELAY [1 byte]
+ relay cell header:
+ recognized 0 [2 bytes]
+ digest (...) [14 bytes]
+ message body, continued:
+ (datagram body, part 3) [219 bytes] (488+493+219=1200)
+
+ # Second message
+ message header:
+ command SENDME [1 byte]
+ length 23 [2 bytes]
+ message body:
+ version 1 [1 byte]
+ datalen 20 [2 bytes]
+ data (digest to ack) [20 bytes]
+
+ # Third message
+ message header:
+ command XON [1 byte]
+ length 1 [2 bytes]
+ message routing header:
+ stream_id 50 [2 bytes]
+ message body:
+ version 1 [1 byte]
+
+ end-of-messages marker:
+ 0 [1 byte]
+ padding up to end of cell:
+ random [241 bytes]
+```
+
+[prop323]: ./323-walking-onions-full.md "Specification for Walking Onions"
+[prop346]: ./346-protovers-again.md "Clarifying and extending the use of protocol versioning"
diff --git a/proposals/341-better-oos.md b/proposals/341-better-oos.md
new file mode 100644
index 0000000..8ddf7fd
--- /dev/null
+++ b/proposals/341-better-oos.md
@@ -0,0 +1,171 @@
+```
+Filename: 341-better-oos.md
+Title: A better algorithm for out-of-sockets eviction
+Author: Nick Mathewson
+Created: 25 July 2022
+Status: Open
+```
+
+# Introduction
+
+Our existing algorithm for handling an out-of-sockets condition needs
+improvement. It only handles sockets used for OR connections, and
+prioritizes those with more circuits. Because of these weaknesses, the
+algorithm is trivial to circumvent, and it's disabled by default with
+`DisableOOSCheck`.
+
+Here we propose a new algorithm for choosing which connections to close
+when we're out of sockets. In summary, the new algorithm works by
+deciding which kinds of connections we have "too many" of, and then by
+closing excess connections of each kind. The algorithm for selecting
+connections of each kind is different.
+
+
+
+# Intuitions behind the algorithm below
+
+We want to keep a healthy mix of connections running; favoring one kind
+of connection over another gives the attacker a fine way to starve the
+disfavored connections by making a bunch of the favored kind.
+
+The correct mix of connections depends on the type of service we are
+providing. Everywhere _except_ authorities, for example, inbound
+directory connections are perfectly fine to close, since nothing in our
+protocol actually generates them.
+
+In general, we would prefer to close DirPort connections, then Exit
+connections, then OR connections.
+
+The priority with which to close connections is different depending on
+the connection type. "Age of connection" or "number of circuits" may be
+a fine metric for how truly used an OR connection is, but for a DirPort
+connection, high age is suspicious.
+
+# The algorithm
+
+Define a "candidate" connection as one that has a socket, and is either
+an exit stream, an _inbound_ directory stream, or an OR connection.
+
+(Note that OR connections can be from clients, relays, or bridges. Note
+that ordinary relays should not get directory streams that use sockets,
+since clients always use `BEGIN_DIR` to create tunneled directory
+streams.)
+
+In all of the following, treat subtraction as saturating at zero. In
+other words, when you see "A - B" below, read it as "MAX(A-B, 0)".
+
+## Phase 1: Deciding how many connections to close
+
+When we find that we are low on sockets, we pick a number of sockets
+that we want to close according to our existing algorithm. (That is, we
+try to close 1/4 of our maximum sockets if we have reached our upper
+limit, or 1/10 of our maximum sockets if we have encountered a failure
+from socket(2).) Call this `N_CLOSE`.
+
+Then we decide which sockets to target based on this algorithm.
+
+1. Consider the total number of sockets used for exit streams
+ (`N_EXIT`), the total number used for _inbound_ directory streams
+ (`N_DIR`), and the total number used for OR connections (`N_OR`).
+ (In these calculations, we exclude connections that are already
+ marked to be closed.) Call the total `N_CONN = N_DIR + N_OR +
+ N_EXIT`. Define `N_RETAIN = N_CONN - N_CLOSE`.
+
+2. Compute how many connections of each type are "in excess". First,
+ calculate our target proportions:
+
+ * If we are an authority, let `T_DIR` = 1. Otherwise set `T_DIR = 0.1`.
+ * If we are an exit or we are running an onion service, let `T_EXIT =
+ 2`. Otherwise let `T_EXIT = 0.1`.
+ * Let `T_OR` = 1.
+
+ > TODO: Should those numbers be consensus parameters?
+
+ These numbers define the relative proportions of connections that
+ we would be willing to retain retain in our final mix. Compute a
+ number of _excess_ connections of each type by calculating.
+
+ ```
+ T_TOTAL = T_OR + T_DIR + T_EXIT.
+ EXCESS_DIR = N_DIR - N_RETAIN * (T_DIR / T_TOTAL)
+ EXCESS_EXIT = N_EXIT - N_RETAIN * (T_EXIT / T_TOTAL)
+ EXCESS_OR = N_OR - N_RETAIN * (T_OR / T_TOTAL)
+ ```
+
+3. Finally, divide N_CLOSE among the different types of excess
+ connections, assigning first to excess directory connections, then
+ excess exit connections, and finally to excess OR connections.
+
+ ```
+ CLOSE_DIR = MIN(EXCESS_DIR, N_CLOSE)
+ N_CLOSE := N_CLOSE - CLOSE_DIR
+ CLOSE_EXIT = MIN(EXCESS_EXIT, N_CLOSE)
+ N_CLOSE := N_CLOSE - CLOSE_EXIT
+ CLOSE_OR = MIN(EXCESS_OR, N_CLOSE)
+ ```
+
+We will try to close `CLOSE_DIR` directory connections, `CLOSE_EXIT`
+exit connections, and `CLOSE_OR` OR connections.
+
+## Phase 2: Closing directory connections
+
+We want to close a certain number of directory connections. To select
+our targets, we sort first by the number of directory connections from
+a similar address (see "similar address" below) and then by their age,
+preferring to close the oldest ones first.
+
+> This approach defeats "many requests from the same address" and "Open
+> a connection and hold it open, and do so from many addresses". It
+> doesn't do such a great job with defeating "open and close frequently
+> and do so on many addresses."
+
+> Note that fallback directories do not typically use sockets for
+> handling directory connections: theirs are usually created with
+> BEGIN_DIR.
+
+## Phase 3: Closing exit connections.
+
+We want to close a certain number of exit connections. To do this, we
+pick an exit connection at random, then close its circuit _along with
+all the other exit connections on the same circuit_. Then we repeat
+until we have closed at least our target number of exit connections.
+
+> This approach probabilistically favors closing circuits with a large
+> number of sockets open, regardless of how long those sockets have been
+> open. This defeats the easiest way of opening a large number of exit
+> streams ("open them all on one circuit") without making the
+> counter-approach ("open each exit stream on its own circuit") much
+> more attractive.
+
+## Phase 3: Closing OR connections.
+
+We want to close a certain number of OR connections, to clients, bridges, or
+relays.
+
+To do this, we first close OR connections with zero circuits. Then we
+close all OR connections but the most recent 2 from each "similar
+address". Then we close OR connections at random from among those _not_
+to a recognized relay in the latest directory. Finally, we close OR
+connections at random.
+
+> We used to unconditionally prefer to close connections with fewer
+> circuits. That's trivial for an adversary to circumvent, though: they
+> can just open a bunch of circuits on their bogus OR connections, and
+> force us to preferentially close circuits from real clients, bridges,
+> and relays.
+
+> Note that some connections that seem like client connections ("not
+> from relays in the latest directory") are actually those created by
+> bridges.
+
+## What is "A similar address"?
+
+We define two connections as having a similar address if they are in the
+same IPv4 /30, or if they are in the same IPv6 /90.
+
+
+# Acknowledgments
+
+This proposal was inspired by a set of
+[OOS improvements](https://gitlab.torproject.org/tpo/core/tor/-/issues/32794)
+from `starlight`.
diff --git a/proposals/342-decouple-hs-interval.md b/proposals/342-decouple-hs-interval.md
new file mode 100644
index 0000000..395c454
--- /dev/null
+++ b/proposals/342-decouple-hs-interval.md
@@ -0,0 +1,107 @@
+```
+Filename: 342-decouple-hs-interval.md
+Title: Decoupling hs_interval and SRV lifetime
+Author: Nick Mathewson
+Created: 9 January 2023
+Status: Draft
+```
+
+# Motivation and introduction
+
+Tor uses shared random values (SRVs) in the consensus to determine
+positions of relays within a hash ring. Which shared random value is to
+be used for a given time period depends upon the time at which that
+shared random value became valid.
+
+But right now, the consensus voting period is closely tied to the shared
+random value voting cycle: and clients need to understand both of these
+in order to determine when a shared random value became current.
+
+This creates tight coupling between:
+ * The voting schedule
+ * The SRV liveness schedule
+ * The hsdir_interval parameter that determines the length of the
+ an HSDIR index
+
+To decouple these values, this proposal describes a forward compatible
+change to how Tor reports SRVs in consensuses, and how Tor decides which
+hash ring to use when.
+
+
+## Reporting SRV timestamps
+
+In consensus documents, parties should begin to accept
+`shared-rand-*-value` lines with an additional argument, in the format
+of an IsoTimeNospace timestamp (like "1985-10-26T00:00:00"). When
+present, this timestamp indicates the time at which the given shared
+random value first became the "current" SRV.
+
+Additionally, we define a new consensus method that adds these
+timestamps to the consensus.
+
+We specify that, in the absence of such a timestamp, parties are to
+assume that the `shared-rand-current-value` SRV became "current" at the
+first 00:00 UTC on the UTC day of the consensus's valid-after timestamp,
+and that the `shard-rand-previous-value` SRV became "current" at 00:00
+UTC on the previous UTC day.
+
+
+## Generalizing HSDir index scheduling.
+
+Under the current HSDir design, there is one SRV for each time period,
+and one time period for which each SRV is in use. Decoupling
+`hsdir_interval` from 24 hours will require that we change this notion
+slightly.
+
+We therefore propose this set of generalized directory behavior rules,
+which should be equivalent to the current rules under current
+parameters.
+
+The calculation of time periods remains the same (see `rend-spec-v3.txt`
+section `[TIME PERIODS]`).
+
+A single SRV is associated with each time period: specifically, the SRV
+that was "current" at the start of the time period.
+
+There is a separate hash ring associated with each time period and its
+SRV.
+
+Whenever fetching an onion service descriptor, the client uses the hash
+ring for the time period that contains the start of the liveness
+interval of the current consensus. Call this the "Consensus" time period.
+
+Whenever uploading an onion service descriptor, the service uses _two or
+three_ hash rings:
+ * The "consensus" time period (see above).
+ * The immediately preceding time period, if the SRV to calculate that
+ hash ring is available in the consensus.
+ * The immediately following time period, if the SRV to calculate that
+ hash ring is available in the consensus.
+
+(Under the current parameters, where `hsdir_interval = SRV_interval`,
+there will never be more than two possible time periods for which the
+service can qualify.)
+
+## Migration
+
+We declare that, for at least the lifetime of the C tor client, we will
+not make any changes to the voting interval, the SRV interval, or the
+`hsdir_interval`. As such, we do not need to prioritize implementing
+these changes in the C client: we can make them in Arti only.
+
+## Issues left unsolved
+
+There are likely other lingering issues that would come up if we try to
+change the voting interval. This proposal does not attempt to solve
+them.
+
+This proposal does not attempt to add flexibility to the SRV voting
+algorithm itself.
+
+Changing `hsdir_interval` would create a flag day where everybody using
+old and new values of `hsdir_interval` would get different hash
+rings. We do not try to solve that here.
+
+## Acknowledgments
+
+Thanks to David Goulet for explaining all of this stuff to me!
diff --git a/proposals/343-rend-caa.txt b/proposals/343-rend-caa.txt
new file mode 100644
index 0000000..1de1355
--- /dev/null
+++ b/proposals/343-rend-caa.txt
@@ -0,0 +1,112 @@
+```
+Filename: 343-rend-caa.txt
+Title: CAA Extensions for the Tor Rendezvous Specification
+Author: Q Misell <q@as207960.net>
+Created: 2023-04-25
+Status: Open
+Ticket: https://gitlab.torproject.org/tpo/core/tor/-/merge_requests/716
+
+Overview:
+ The document defines extensions to the Tor Rendezvous Specification Hidden
+ Service descriptor format to allow the attachment of DNS style CAA records to
+ Tor hidden services to allow the same security benefits as CAA provides in the
+ DNS.
+
+Motivation:
+ As part of the work on draft-misell-acme-onion [I-D.misell-acme-onion] at the
+ IETF it was felt necessary to define a method to incorporate CAA records
+ [RFC8659] into Tor hidden services.
+
+ CAA records in the DNS provide an mechanism to indicate which Certificate
+ Authorities are permitted to issue certificates for a given domain name, and
+ restrict which validation methods are permitted for certificate validation.
+
+ As Tor hidden service domains are not in the DNS another way to provide the
+ same security benefits as CAA does in the DNS needed to be devised.
+
+ It is important to note that a hidden service is not required to publish a CAA
+ record to obtain a certificate, as is the case in the DNS.
+
+ More information about this project in general can be found at
+ https://acmeforonions.org.
+
+Specification:
+ To enable maximal code re-use in CA codebases the same CAA record format is
+ used in Tor hidden services as in the DNS. To this end a new field is added to
+ the second layer hidden service descriptor [tor-rend-spec-v3] § 2.5.2.2.
+ with the following format:
+
+ "caa" SP flags SP tag SP value NL
+ [Any number of times]
+
+ The contents of "flag", "tag", and "value" are as per [RFC8659] § 4.1.1.
+ Multiple CAA records may be present, as is the case in the DNS.
+
+ A hidden service's second layer descriptor using CAA may look
+ something like the following:
+
+ create2-formats 2
+ single-onion-service
+ caa 0 issue "example.com"
+ caa 0 iodef "mailto:security@example.com"
+ caa 128 validationmethods "onion-csr-01"
+ introduction-point AwAGsAk5nSMpAhRqhMHbTFCTSlfhP8f5PqUhe6DatgMgk7kSL3KHCZ...
+
+ As the CAA records are in the second layer descriptor and in the case of a
+ hidden service requiring client authentication it is impossible to read them
+ without the hidden service trusting a CA's public key, a method is required to
+ signal that there are CAA records present (but not reveal their contents,
+ which may disclose unwanted information about the hidden service operator to
+ third parties). This is to allow a CA to know that it must attempt to check
+ CAA records before issuance, and fail if it is unable to do so.
+
+ To this end a new field is added to the first layer hidden service descriptor
+ [tor-rend-spec-v3] § 2.5.1.2. with the following format:
+
+ "caa-critical" NL
+ [At most once]
+
+Security Considerations:
+ The second layer descriptor is signed, encrypted and MACed in a way that only
+ a party with access to the secret key of the hidden service could manipulate
+ what is published there. Therefore, Tor CAA records have at least the same
+ security as those in the DNS secured by DNSSEC.
+
+ The "caa-critical" flag is visible to anyone with knowledge of the hidden
+ service's public key, however it reveals no information that could be used to
+ de-anonymize the hidden service operator.
+
+ The CAA flags in the second layer descriptor may reveal information about the
+ hidden service operator if they choose to publish an "iodef", "contactemail",
+ or "contactphone" tag. These however are not required for primary goal of CAA,
+ that is to restrict which CAs may issue certificates for a given domain name.
+
+ No more information is revealed by the "issue" nor "issuewild" tags than would
+ be revealed by someone making a connection to the hidden service and noting
+ which certificate is presented.
+
+Compatibility:
+ The hidden service spec [tor-rend-spec-v3] already requires that clients
+ ignore unknown lines when decoding hidden service descriptors, so this change
+ should not cause any compatibility issues. Additionally in testing no
+ compatibility issues where found with existing Tor implementations.
+
+ A hidden service with CAA records published in its descriptor is available at
+ znkiu4wogurrktkqqid2efdg4nvztm7d2jydqenrzeclfgv3byevnbid.onion, to allow
+ further compatibility testing.
+
+References:
+ [I-D.misell-acme-onion]
+ Misell, Q., "Automated Certificate Management Environment (ACME)
+ Extensions for ".onion" Domain Names", Internet-Draft
+ draft-misell-acme-onion-02, April 2023,
+ <https://datatracker.ietf.org/doc/html/draft-misell-acme-onion-02>.
+
+ [RFC8659] Hallam-Baker, P., Stradling, R., and J. Hoffman-Andrews,
+ "DNS Certification Authority Authorization (CAA) Resource
+ Record", RFC 8659, DOI 10.17487/RFC8659, November 2019,
+ <https://www.rfc-editor.org/info/rfc8659>.
+
+ [tor-rend-spec-v3]
+ The Tor Project, "Tor Rendezvous Specification - Version 3",
+ <https://spec.torproject.org/rend-spec-v3>.```
diff --git a/proposals/344-protocol-info-leaks.txt b/proposals/344-protocol-info-leaks.txt
new file mode 100644
index 0000000..f20ebca
--- /dev/null
+++ b/proposals/344-protocol-info-leaks.txt
@@ -0,0 +1,1188 @@
+```
+Filename: 344-protocol-info-leaks.txt
+Title: Prioritizing Protocol Information Leaks in Tor
+Author: Mike Perry
+Created: 2023-07-17
+Purpose: Normative
+Status: Open
+
+
+0. Introduction
+
+Tor's protocol has numerous forms of information leaks, ranging from highly
+severe covert channels, to behavioral issues that have been useful
+in performing other attacks, to traffic analysis concerns.
+
+Historically, we have had difficulty determining the severity of these
+information leaks when they are considered in isolation. At a high level, many
+information leaks look similar, and all seem to be forms of traffic analysis,
+which is regarded as a difficult attack to perform due to Tor's distributed
+trust properties.
+
+However, some information leaks are indeed more severe than others: some can
+be used to remove Tor's distributed trust properties by providing a covert
+channel and using it to ensure that only colluding and communicating relays
+are present in a path, thus deanonymizing users. Some do not provide this
+capability, but can be combined with other info leak vectors to quickly yield
+Guard Discovery, and some only become dangerous once Guard Discovery or other
+anonymity set reduction is already achieved.
+
+By prioritizing information leak vectors by their co-factors, impact, and
+resulting consequences, we can see that these attack vectors are not all
+equivalent. Each vector of information leak also has a common solution, and
+some categories even share the same solution as other categories.
+
+This framework is essential for understanding the context in which we will be
+addressing information leaks, so that decisions and fixes can be understood
+properly. This framework is also essential for recognizing when new protocol
+changes might introduce information leaks or not, for gauging the severity of
+such information leaks, and for knowing what to do about them.
+
+Hence, we are including it in tor-spec, as a living, normative document to be
+updated with experience, and as external research progresses.
+
+It is essential reading material for any developers working on new Tor
+implementations, be they Arti, Arti-relay, or a third party implementation.
+
+This document is likely also useful to developers of Tor-like anonymity
+systems, of which there are now several, such as I2P, MASQUE, and Oxen. They
+definitely share at least some, and possibly even many of these issues.
+
+Readers who are relatively new to anonymity literature may wish to first
+consult the Glossary in Section 3, especially if terms such as Covert Channel,
+Path Bias, Guard Discovery, and False Positive/False Negative are unfamiliar
+or hazy. There is also a catalog of historical real-world attacks that are
+known to have been performed against Tor in Section 2, to help illustrate how
+information leaks have been used adversarially, in practice.
+
+We are interested in hearing from journalists and legal organizations who
+learn about court proceedings involving Tor. We became aware of three
+instances of real-world attacks covered in Section 2 in this way. Parallel
+construction (hiding the true source of evidence by inventing an alternate
+story for the court -- also known as lying) is a possibility in the US and
+elsewhere, but (so far) we are not aware of any direct evidence of this
+occurring with respect to Tor cases. Still, keep your eyes peeled...
+
+
+0.1. Table of Contents
+
+ 1. Info Leak Vectors
+ 1.1. Highly Severe Covert Channel Vectors
+ 1.1.1. Cryptographic Tagging
+ 1.1.2. End-to-end cell header manipulation
+ 1.1.3. Dropped cells
+ 1.2. Info Leaks that enable other attacks
+ 1.2.1. Handshakes with unique traffic patterns
+ 1.2.2. Adversary-Induced Circuit Creation
+ 1.2.3. Relay Bandwidth Lying
+ 1.2.4. Metrics Leakage
+ 1.2.5. Protocol Oracles
+ 1.3. Info Leaks of Research Concern
+ 1.3.1. Netflow Activity
+ 1.3.2. Active Traffic Manipulation Covert Channels
+ 1.3.3. Passive Application-Layer Traffic Patterns
+ 1.3.4. Protocol or Application Linkability
+ 1.3.5. Latency Measurement
+ 2. Attack Examples
+ 2.1. CMU Tagging Attack
+ 2.2. Guard Discovery Attacks with Netflow Deanonymization
+ 2.3. Netflow Anonymity Set Reduction
+ 2.4. Application Layer Confirmation
+ 3. Glossary
+
+
+1. Info Leak Vectors
+
+In this section, we enumerate the vectors of protocol-based information leak
+in Tor, in order of highest priority first. We separate these vectors into
+three categories: "Highly Severe Covert Channels", "Info Leaks that Enable
+other attacks", and "Info Leaks Of Research Concern". The first category
+yields deanonymization attacks on their own. The second category enables other
+attacks that can lead to deanonymization. The final category can be aided by
+the earlier vectors to become more severe, but overall severity is a
+combination of many factors, and requires further research to illuminate all
+of these factors.
+
+For each vector, we provide a brief "at-a-glance" summary, which includes a
+ballpark estimate of Accuracy in terms of False Positives (FP) and False
+Negatives (FN), as 0, near-zero, low, medium, or high. We then list what is
+required to make use of the info leak, the impact, the reason for the
+prioritization, and some details on where the signal is injected and observed.
+
+
+1.1. Highly Severe Covert Channel Vectors
+
+This category of info leak consists entirely of covert channel vectors that
+have zero or near-zero false positive and false negative rates, because they
+can inject a covert channel in places where similar activity would not happen,
+and they are end-to-end.
+
+They also either provide or enable path bias attacks that can capture
+the route clients use, to ensure that only malicious exits are used, leading
+to full deanonymization when the requirements are met.
+
+If the adversary has censorship capability, and can ensure that users only
+connect to compromised Guards (or Bridges), they can fully deanonymize all
+users with these covert channels.
+
+
+1.1.1. Cryptographic Tagging
+
+At a glance:
+ Accuracy: FP=0, FN=0
+ Requires: Malicious or compromised Guard, at least one exit
+ Impact: Full deanonymization (path bias, identifier transmission)
+ Path Bias: Automatic route capture (all non-deanonymized circuits fail)
+ Reason for prioritization: Severity of Impact; similar attacks used in wild
+ Signal is: Modified cell contents
+ Signal is injected: by guard
+ Signal is observed: by exit
+
+First reported at Black Hat in 2009 (see [ONECELL]), and elaborated further
+with the path bias amplification attack in 2012 by some Raccoons (see
+[RACCOON23]), this is the most severe vector of covert channel attack in Tor.
+
+Cryptographic tagging is where an adversary who controls a Guard (or Bridge)
+XORs an identifier, such as an IP address, directly into the circuit's
+cipher-stream, in an area of known-plaintext. This tag can be exactly
+recovered by a colluding exit relay, ensuring zero false positives and zero
+false negatives for this built-in identifier transmission, along with their
+collusion signal.
+
+Additionally, because every circuit that does not have a colluding relay will
+automatically fail because of the failed digest validation, the adversary gets
+a free path bias amplification attack, such that their relay only actually
+carries traffic that they know they have successfully deanonymized. Because
+clients will continually attempt to re-build such circuits through the guard
+until they hit a compromised exit and succeed, this violates Tor's distributed
+trust assumption, reducing it to the same security level as a one-hop proxy
+(ie: the security of fully trusting the Guard relay). Worse still, when the
+adversary has full censorship control over all connections into the Tor
+network, Tor provides zero anonymity or privacy against them, when they also
+use this vector.
+
+Because the Exit is able to close *all* circuits that are not deanonymized,
+for maximal efficiency, the adversary's Guard capacity should exactly match
+their Exit capacity. To make up for the loss of traffic caused by closing many
+circuits, relays can lie about their bandwidth (see Section 1.2.3).
+
+Large amounts of circuit failure (that might be evidence of such an attack)
+are tracked and reported by C-Tor in the logs, by the path bias detector, but
+when the Guard is under DDoS, or even heavy load, this can yield false alarms.
+These false alarms happened frequently during the network-wide DDoS of
+2022-2023. They can also be induced at arbitrary Guards via DoS, to make users
+suspicious of their Guards for no reason.
+
+The path bias detector could have a second layer in Arti, that checks to see
+if any specific Exits are overused when the circuit failure rate is high. This
+would be more indicative of an attack, but could still go off if the user is
+actually trying to use rare exits (ie: country selection, bittorrent).
+
+This attack, and path bias attacks that are used in the next two sections, do
+have some minor engineering barriers when being performed against both onion
+and exit traffic, because the onion service traffic is restricted to
+particular hops in the case of HSDIR and intro point circuits. However,
+because pre-built circuits are used to access HSDIR and intro points, the
+adversary can use their covert channel such that only exits and pre-built
+onion service circuits are allowed to proceed. Onion services are harder to
+deanonymize in this way, because the HSDIR choice itself can't be controlled
+by them, but they can still be connected to using pre-built circuits until the
+adversary also ends up in the HSDIR position, for deanonymization.
+
+Solution: Path Bias Exit Usage Counter;
+ Counter Galois Onion (CGO) (Forthcoming update to Prop#308).
+Status: Unfixed (Current PathBias detector is error-prone under DDoS)
+Funding: CGO explicitly funded via Sponsor 112
+
+
+1.1.2. End-to-end cell header manipulation
+
+At a glance:
+ Accuracy: FP=0, FN=0
+ Requires: Malicious or compromised Guard, at least one exit
+ Impact: Full deanonymization (path bias, identifier transmission)
+ Path Bias: Full route capture is trivial
+ Reason for prioritization: Severity of Impact; used in the wild
+ Signal is: Modified cell commands.
+ Signal is injected: By either guard or exit/HSDIR
+ Signal is observed: By either guard or exit/HSDIR
+
+The Tor protocol consists of both cell header commands, and relay header
+commands. Cell commands are not encrypted by circuit-level encryption, so they
+are visible and modifiable by every relay in the path. Relay header commands
+are encrypted, and not visible to every hop in the path.
+
+Not all cell commands are forwarded end-to-end. Currently, these are limited
+to RELAY, RELAY_EARLY, and DESTROY. Because of the attack described here,
+great care must be taken when adding new end-to-end cell commands, even if
+they are protected by a MAC.
+
+Previously, a group of researchers at CMU used this property to modify the
+cell command header of cells on circuits, to switch between RELAY_EARLY and
+RELAY at exits and HSDIRs (see [RELAY_EARLY]). This creates a visible bit in
+each cell, that can signal collusion, or with enough cells, can encode an
+identifier such as an IP address. They assisted the FBI, to use this attack in
+the wild to deanonymize clients.
+
+We addressed the CMU attack by closing the circuit upon receiving an "inbound"
+(towards the client) RELAY_EARLY command cell, and by limiting the number of
+"outbound" (towards the exit) RELAY_EARLY command cells at relays, and by
+requiring the use of RELAY_EARLY for EXTEND (onionskin) relay commands. This
+defense is not generalized, though. Guards may still use this specific covert
+channel to send around 3-5 bits of information after the extend handshake,
+without killing the circuit. It is possible to use the remaining outbound
+vector to assist in path bias attacks for dropped cells, as a collusion signal
+to reduce the amount of non-compromised traffic that malicious exits must
+carry (see the following Section 1.1.3).
+
+If this covert channel is not addressed, it is trivial for a Guard and Exit
+relays to close every circuit that does not display this covert channel,
+providing path bias amplification attack and distributed trust reduction,
+similar to cryptographic tagging attacks. Because the inbound direction *is*
+addressed, we believe this kind of path bias is currently not possible with
+this vector by itself (thus also requiring the vector from Section 1.1.3), but
+it could easily become possible if this defense is forgotten, or if a new
+end-to-end cell type is introduced.
+
+While more cumbersome than cryptographic tagging attacks, in practice this
+attack is just as successful, if these cell command types are not restricted
+and limited. It is somewhat surprising that the FBI used this attack before
+cryptographic tagging, but perhaps that was just a lucky coincidence of
+opportunity.
+
+Solution: CGO (Updated version of Prop#308) covers cell commands in the MAC;
+ Any future end-to-end cell commands must still limit usage
+Status: Fix specific to CMU attack; Outbound direction is unfixed
+Funding: Arti and relay-side fixes are explicitly funded via Sponsor 112
+
+
+1.1.3. Dropped cells
+
+At a glance:
+ Accuracy: FP=0, FN=0
+ Requires: Malicious Guard or Netflow data (if high volume), one exit
+ Impact: Full deanonymization (path bias amplification, collusion signal)
+ Path Bias: Full route capture is trivial
+ Reason for prioritization: Severity of Impact; similar attacks used in wild
+ Signal is: Unusual patterns in number of cells received
+ Signal is injected: By exit or HSDIR
+ Signal is observed: at guard or client<->guard connection.
+
+Dropped cells are cells that a relay can inject that end up ignored and
+discarded by a Tor client. These include:
+ - Unparsable cells
+ - Unrecognized cells (ie: wrong source hop, or decrypt failures)
+ - invalid relay commands
+ - unsupported (or consensus-disabled) relay commands or extensions
+ - out-of-context relay commands
+ - duplicate relay commands
+ - relay commands that hit any error codepaths
+ - relay commands for an invalid or already-closed stream ID
+ - semantically void relay cells (incl relay data len == 0, or PING)
+ - onion descriptor-appended junk
+
+This attack works by injecting inbound RELAY cells at the exit or at a middle
+relay, and then observing anomalous traffic patterns at the guard or at the
+client->guard connection.
+
+The severity of this covert channel is extreme (zero false positives; zero
+false negatives) when they are injected in cases where the circuit is
+otherwise known to be silent, because of the protocol state machine. These
+cases include:
+ - Immediately following an onionskin response
+ - During other protocol handshakes (onion services, conflux)
+ - Following relay CONNECTED or RESOLVED (not as severe - no path bias)
+
+Because of the stateful and deterministic nature of the Tor protocol,
+especially handshakes, it is easy to accurately recognize these specific cases
+even when observing only encrypted circuit traffic at the Guard relay (see
+[DROPMARK]).
+
+Because this covert channel is most accurate before actual circuit use, when
+the circuit is expected to be otherwise silent, it is trivial for a Guard
+relay to close every circuit that does not display this covert channel,
+providing path bias amplification attack and distributed trust reduction,
+similar to cryptographic tagging attacks and end-to-end cell header
+manipulation. This ability to use the collusion signal to perform path bias
+before circuit use differentiates dropped cells within the Tor Protocol from
+deadweight traffic during application usage (such as javascript requests for
+404 URLs, covered in Section 1.3.2).
+
+This category is not quite as severe as these previous two categories by
+itself, for two main reasons. However, it is also the case that due to other
+factors, these reasons may not matter in practice.
+
+First, the Exit can't use this covert channel to close circuits that are not
+deanonymized by a colluding Guard, since there is no covert channel from the
+Guard to the Exit with this vector alone. Thus, unlike cryptographic tagging,
+the adversary's Exits will still carry non-deanonymized traffic from
+non-adversary Guards, and thus the adversary needs more Exit capacity than
+Guard capacity. These kinds of more subtle trade-offs with respect to path
+bias are covered in [DOSSECURITY]. However, note that this issue can be fixed
+by using the previous RELAY_EARLY covert channel from the Guard to the Exit
+(since this direction is unfixed). This allows the adversary to confirm
+receipt of the dropped cell covert channel, allowing both the Guard and the
+Exit to close all non-confirmed circuits, and thus ensure that they only need
+to allocate equal amounts of compromised Guard and Exit traffic, to monitor
+all Tor traffic.
+
+Second, encoding a full unique identifier in this covert channel is
+non-trivial. A significant amount of injected traffic must be sent to exchange
+more than a simple collusion signal, to link circuits when attacking a large
+number of users. In practice, this likely means some amount of correlation,
+and a resulting (but very small) statistical error.
+
+Obviously, the actual practical consequences of these two limitations are
+questionable, so this covert channel is still regarded as "Highly Severe". It
+can still result in full deanonymization of all Tor traffic by an adversary
+with censorship capability, with very little error.
+
+Solution: Forthcoming dropped-cell proposal
+Status: Fixed with vanguards addon; Unfixed otherwise
+Funding: Arti and relay-side fixes are explicitly funded via Sponsor 112
+
+
+1.2. Info Leaks that enable other attacks
+
+These info leaks are less severe than the first group, as they do not yield
+full covert channels, but they do enable other attacks, including guard
+discovery and eventual netflow deanonymization, and website traffic
+fingerprinting.
+
+
+1.2.1. Handshakes with unique traffic patterns
+
+At a glance:
+ Accuracy: FP=near-zero, FN=near-zero
+ Requires: Compromised Guard
+ Impact: Anonymity Set Reduction and Oracle; assists in Guard Discovery
+ Path Bias: Full route capture is difficult (high failure rate)
+ Reason for Prioritization: Increases severity of vectors 1.2.2 and 1.3.3
+ Signal is: Caused by client's behavior.
+ Signal is observed: At guard
+ Signal is: Unique cell patterns
+
+Certain aspects of Tor's handshakes are very unique and easy to fingerprint,
+based only on observed traffic timing and volume patterns. In particular, the
+onion client and onion service handshake activity is fingerprintable with
+near-zero false negatives and near-zero false positive rates, as per
+[ONIONPRINT]. The conflux link handshake is also unique (and thus accurately
+recognizable), because it is our only 3-way handshake.
+
+This info leak is very accurate. However, the impact is much lower than that
+of covert channels, because by itself, it can only tell if a particular Tor
+protocol, behavior, or feature is in use.
+
+Additionally, Tor's distributed trust properties remain in-tact, because there
+is no collusion signal built in to this info leak. When a path bias attack
+is mounted to close circuits during circuit handshake construction without a
+collusion signal to the Exit, it must proceed hop-by-hop. Guards must close
+circuits that do not extend to colluding middles, and those colluding middles
+must close circuits that don't extend to colluding exits. This means that the
+adversary must control some relays in each position, and has a substantially
+higher circuit failure rate while directing circuits to each of these relays
+in a path.
+
+To put this into perspective, an adversary using a collusion signal with 10%
+of Exits expects to fail 9 circuits before detecting their signal at a
+colluding exit and allowing a circuit to succeed. However, an adversary
+without a collusion signal and 10% of all relays expects to fail 9 circuits
+before getting a circuit to their middle, but then expects 9 of *those*
+circuits to fail before reaching an Exit, for 81 circuit failures for every
+successful circuit.
+
+Published attacks have built upon this info leak, though.
+
+In particular, certain error conditions, such as returning a single
+"404"-containing relay cell for an unknown onion service descriptor, are
+uniquely recognizable. This fingerprint was used in the [ONIONFOUND] guard
+discovery attack, and they provide a measurement of its uniqueness.
+
+Additionally, onion client fingerprintability can be used to vastly reduce the
+set of website traffic traces that need to be considered for website traffic
+fingerprinting (see Section 1.3.3), making that attack realistic and
+practical. Effectively, it functions as a kind of oracle in this case (see
+Glossary, and [ORACLES]).
+
+Solution: Padding machines at middles for protocol handshakes (as per [PCP]);
+ Pathbias-lite.
+Status: Padding machines deployed for onion clients, but have weaknesses
+ against DF and stateful cross-circuit fingerprints
+Funding: Not explicitly funded
+
+
+1.2.2. Adversary-Induced Circuit Creation
+
+At a glance:
+ Accuracy: FP=high, FN=high
+ Requires: Onion service activity, or malicious exit
+ Impact: Guard discovery
+ Path Bias: Repeated circuits eventually provide the desired path
+ Reason for Prioritization: Enables Guard Discovery
+ Signal is: Inducing a client to make a new Tor circuit
+ Signal is injected: by application layer, client, or malicious relay
+ Signal is observed: At middle
+
+By itself, the ability for an adversary to cause a client to create circuits
+is not a covert channel or arguably even an info leak. Circuit creation, even
+bursts of frequent circuit creation, is commonplace on the Tor network.
+
+However, when this activity is combined with a covert channel from Section
+1.1, with a unique handshake from Section 1.2.1, or with active traffic
+manipulation (Section 1.3.2), then it leads to Guard Discovery, by allowing
+the adversary to recognize when they are chosen for the Middle position, and
+thus learn the Guard. Once Guard Discovery is achieved, netflow analysis of
+the Guard's connections can be used to perform intersection attacks and
+eventually determine the client IP address (see Section 1.3.1).
+
+Large quantities of circuit creation can be induced by:
+ - Many connections to an Onion Service
+ - Causing a client to make connections to many onion service addresses
+ - Application connection to ports in rare exit policies, followed by circuit
+ close at Exit
+ - Repeated Conflux leg failures
+
+In Tor 0.4.7 and later, onion services are protected from this activity via
+Vanguards-Lite (Proposal #333). This system adds a second layer of vanguards
+to onion service circuits, with rotation times set such that it is sufficient
+to protect a user for use cases on the order of weeks, assuming the adversary
+does not get lucky and land in a set. Non-Onion service activity, such as
+Conflux leg failures, is protected by feature-specific rate limits.
+
+Longer lived onion services should use the Vanguards Addon, which implements
+Mesh Vanguards (Prop#292). It uses two layers of vanguards, and expected
+use cases of months.
+
+These attack times are probabilistic expectations, and are rough estimates.
+See the proposals for details. To derive these numbers, the proposals assume a
+100% accurate covert channel for detecting that the middle is in the desired
+circuit. If we address the low hanging fruit for such covert channels above,
+these numbers change, and such attacks also become much more easily
+detectable, as they will rely on application layer covert channels (See
+Section 1.3.2), which will resemble an application layer DoS or flood.
+
+Solution: Mesh-vanguards (Prop#292); Vanguards-lite (Prop#333); rate limiting
+ circuit creation attempts; rate limiting the total number of distinct
+ paths used by circuits
+Status: Vanguards-lite deployed in Tor 0.4.7; Mesh-vanguards is vanguards addon;
+ Conflux leg failures are limited per-exit; Exitpolicy scanner exists
+Funding: Not explicitly funded
+
+
+1.2.3. Relay Bandwidth Lying
+
+At a glance:
+ Accuracy: FP=high, FN=high
+ Requires: Running relays in the network
+ Impact: Additional traffic towards malicious relays
+ Path Bias: Bandwidth lying can make up for circuit rejection
+ Reason for prioritization: Assists Covert Channel Path Bias attacks
+ Signal is injected: by manipulating reported descriptor bandwidths
+ Signal is observed: by clients choosing lying relays more often
+ Signal is: the effect of using lying relays more often
+
+Tor clients select relays for circuits in proportion to their fraction of
+consensus "bandwidth" weight. This consensus weight is calculated by
+multiplying the relay's self-reported "observed" descriptor bandwidth value by
+a ratio that is measured by the Tor load balancing system (formerly TorFlow;
+now sbws -- see [SBWS] for an overview).
+
+The load balancing system uses two-hop paths to measure the stream bandwidth
+through all relays on the network. The ratio is computed by determining a
+network-wide average stream bandwidth, 'avg_sbw', and a per-relay average
+stream bandwidth, 'relay_sbw'. Each relay's ratio value is 'relay_sbw/avg_sbw'.
+(There are also additional filtering steps to remove slow outlier streams).
+
+Because the consensus weights for relays derive from manipulated descriptor
+values by multiplication with this ratio, relays can still influence their
+weight by egregiously lying in their descriptor value, thus attracting more
+client usage. They can also attempt to fingerprint load balancer activity and
+selectively give it better service, though this is more complicated than
+simply patching Tor to lie.
+
+This attack vector is especially useful when combined with a path bias attack
+from Section 1.1: if an adversary is using one of those covert channels to
+close a large portion of their circuits, they can make up for this loss of
+usage by inflating their corresponding bandwidth value by an equivalent
+amount, thus causing the load balancer to still measure a reasonable ratio for
+them, and thus still provide fast service for the fully deanonymized circuits
+that they do carry.
+
+There are many research papers written on alternate approaches to the
+measurement problem. These have not been deployed for three reasons:
+ 1. The unwieldy complexity and fragility of the C-Tor codebase
+ 2. The conflation of measurement with load balancing (we need both)
+ 3. Difficulty performing measurement of the fastest relays with
+ non-detectable/distributed mechanisms
+
+In the medium term, we will work on detecting bandwidth lying and manipulation
+via scanners. In the long term, Arti-relay will allow the implementation of
+distributed and/or dedicated measurement components, such as [FLASHFLOW].
+(Note that FlashFlow still needs [SBWS] or another mechanism to handle load
+balancing, though, since FlashFlow only provides measurement).
+
+Solutions: Scan for lying relays; implement research measurement solutions
+Status: A sketch of the lying relay scanner design is in [LYING_SCANNER]
+Funding: Scanning for lying relays is funded via Sponsor 112
+
+
+1.2.4. Metrics Leakage
+
+At a glance:
+ Accuracy: FP=low, FN=high
+ Requires: Some mechanism to bias or inflate reported relay metrics
+ Impact: Guard discovery
+ Path Bias: Potentially relevant, depending on type of leak
+ Reason for prioritization: Historically severe issues
+ Signal is injected: by interacting with onion service
+ Signal is observed: by reading router descriptors
+ Signal is: information about volume of traffic and number of IP addresses
+
+In the past, we have had issues with info leaks in our metrics reporting (see
+[METRICSLEAK]). We addressed them by lowering the resolution of read/write
+history, and ensuring certain error conditions could not willfully introduce
+noticeable asymmetries. However, certain characteristics, like reporting local
+onion or SOCKS activity in relay bandwidth counts, still remain.
+
+Additionally, during extremely large flooding or DDoS attempts, it may still
+be possible to see the corresponding increases in reported metrics for Guards
+in use by onion services, and thus discover its Guards.
+
+Solutions: Fix client traffic reporting; remove injectable asymmetries;
+ reduce metrics resolution; add noise
+Status: Metrics resolution reduced to 24hr; known asymmetries fixed
+Funding: Not funded
+
+
+1.2.5. Protocol Oracles
+
+At a glance:
+ Accuracy: FP=medium, FN=0 (for unpopular sites: FP=0, FN=0)
+ Requires: Probing relay DNS cache
+ Impact: Assists Website Traffic Fingerprinting; Domain Usage Analytics
+ Path Bias: Not Possible
+ Reason for prioritization: Historically accurate oracles
+ Signal is injected: by client causing DNS caching at exit
+ Signal is observed: by probing DNS response wrt to cell ordering via all exits
+ Signal is: If cached, response is immediate; otherwise other cells come first
+
+Protocol oracles, such as exit DNS cache timing to determine if a domain has
+been recently visited, increase the severity of Website Traffic Fingerprinting
+in Section 1.3.3, by reducing false positives, especially for unpopular
+websites.
+
+There are additional forms of oracles for Website Traffic Fingerprinting, but
+the remainder are not protocol oracles in Tor. See [ORACLES] in the
+references.
+
+Tor deployed a defense for this oracle in the [DNSORACLE] tickets, to
+randomize expiry time. This helps reduce the precision of this oracle for
+popular and moderately popular domains/websites in the network, but does not
+fully eliminate it for unpopular domains/websites.
+
+The paper in [DNSORACLE] specifies a further defense, using a pre-load of
+popular names and circuit cache isolation defense in Section 6.2, with third
+party resolvers. The purpose of the pre-load list is to preserve the cache
+hits for shared domains across circuits (~11-17% of cache hits, according to
+the paper). The purpose of circuit isolation is to avoid Tor cache hits for
+unpopular domains across circuits. The purpose of third party resolvers is to
+ensure that the local resolver's cache does not become measurable, when
+isolating non-preloaded domains to be per-circuit.
+
+Unfortunately, third party resolvers are unlikely to be recommended for use by
+Tor, since cache misses of unpopular domains would hit them, and be subject to
+sale in DNS analytics data at high resolution (see [NETFLOW_TICKET]).
+
+Also note that the cache probe attack can only be used by one adversary at a
+time (or they begin to generate false positives for each other by actually
+*causing* caching, or need to monitor for each other to avoid each other).
+This is in stark contrast to third party resolvers, where this information is
+sold and available to multiple adversaries concurrently, for all uncached
+domains, with high resolution timing, without the need for careful
+coordination by adversaries.
+
+However, note that an arti-relay implementation would no longer be single
+threaded, and would be able to reprioritize asynchronous cache activity
+arbitrarily, especially for sensitive uncached activity to a local resolver.
+This might be useful for reducing the accuracy of the side channel, in this
+case.
+
+Unfortunately, we lack sufficient clarity to determine if it is meaningful to
+implement any further defense that does not involve third party resolvers
+under either current C-Tor, or future arti-relay circumstances.
+
+Solutions: Isolate cache per circuit; provide a shared pre-warmed cache of
+ popular domains; smarter cache handling mechanisms?
+Status: Randomized expiry only - not fully eliminated
+Funding: Any further fixes are covered by Sponsor 112
+
+
+1.3. Info Leaks of Research Concern
+
+In this section, we list info leaks that either need further research, or are
+undergoing active research.
+
+Some of these are still severe, but typically less so than the already covered
+ones, unless they are part of a combined attack, such as with an Oracle,
+or with Guard Discovery.
+
+Some of these may be more or less severe than currently suspected: If we
+knew for certain, they wouldn't need research.
+
+
+1.3.1. Netflow Activity
+
+At a glance:
+ Accuracy: FP=high; FN=0 (FN=medium with incomplete vantage point set)
+ Requires: Access to netflow data market, or ISP coercion
+ Impact: Anonymity Set Reduction; Deanonymization with Guard Discovery/Oracle
+ Path Bias: Not possible
+ Reason for Prioritization: Low impact without Guard Discovery/Oracle
+ Signal is: created by using the network
+ Signal is observed: at ISP of everything that is using the network.
+ Signal is: Connection tuple times and byte counts
+
+Netflow is a feature of internet routers that records connection tuples, as
+well as time stamps and byte counts, for analysis.
+
+This data is bought and sold, by both governments and threat intelligence
+companies, as documented in [NETFLOW_TICKET].
+
+Tor has a padding mechanism to reduce the resolution of this data (see Section
+2 of [PADDING_SPEC]), but this hinges on clients' ability to keep connections
+open and padded for 45-60 minutes, even when idle. This padding reduces the
+resolution of intersection attacks, making them operate on 30 minute time
+windows, rather than 15 second time windows. This increases the false positive
+rate, and thus increases the duration of such intersection attacks.
+
+Large scale Netflow data can also be used to track Tor users as they migrate
+from location to location, without necessarily deanonymizing them. Because Tor
+uses three directory guards, and has ~4000 Guard relays, the choice
+Choose(4000,3) of directory Guards is ~10 billion different combinations,
+though probability weighting of Guard selection does reduce this considerably
+in practice. Lowering the total number of Guard relays (via arti-relay and
+using only the fastest Guards), and using just two directory guards as opposed
+to three can reduce this such that false positives become more common. More
+thorough solutions are discussed in [GUARDSETS].
+
+Location tracking aside, by itself, this data (especially when padded) is not
+a threat to client anonymity. However, this data can also be used in
+combination with a number of Oracles or confirmation vectors, such as:
+ - Guard Discovery
+ - Flooding an onion service with huge amounts of traffic in a pattern
+ - Advertising analytics or account activity log purchase
+ - TCP RST injection
+ - TLS conn rotation
+
+These oracles can be used to either confirm the connection of an onion
+service, or to deanonymize it after Guard Discovery.
+
+In the case of clients, the use of Oracle data can enable intersection attacks
+to deanonymize them. The oracle data necessary for client intersection attack
+is also being bought and sold, as documented in [NETFLOW_TICKET]. It is
+unknown how long such attacks take, but it is a function of the number of
+users under consideration, and their connection durations.
+
+The research interest here is in determining what can be done to increase the
+amount of time these attacks take, in terms of increasing connection duration,
+increasing the number of users, reducing the total number of Guard relays,
+using a UDP transport, or changing user behavior.
+
+Solutions: Netflow padding; connection duration increase; QUIC transport;
+ using bridges; decreasing total number of guards; using only two
+ directory guards; guardsets; limiting sensitive account usage
+Status: Netflow padding deployed in C-Tor and arti
+Funding: Not explicitly funded
+
+
+1.3.2. Active Traffic Manipulation Covert Channels
+
+At a Glance:
+ Accuracy: FP=medium, FN=low
+ Requires: Netflow data, or compromised/monitored Guard
+ Impact: Anonymity Set Reduction; Netflow-assisted deanonymization
+ Path Bias: Possible via exit policy or onion service reconnection
+ Reason for Prioritization: Can assist other attacks; lower severity otherwise
+ Signal is injected: by the target application, manipulated by the other end.
+ Signal is observed: at Guard, or target->guard connection.
+ Signal is: Unusual traffic volume or timing.
+
+This category of covert channel occurs after a client has begun using a
+circuit, by manipulating application data traffic. This manipulation can
+occur either at the application layer, or at the Tor protocol layer.
+
+Because it occurs after the circuit is in use, it does not permit the use of
+path bias or trust reduction properties by itself (unless combined with one of
+the above info leak attack vectors -- most often Adversary-Induced Circuit
+Creation).
+
+These covert channels also have a significantly higher false positive rate
+than those before circuit use, since application traffic is ad-hoc and
+arbitrary, and is also involved during the attempted manipulation of
+application traffic.
+
+For onion services, this covert channel is much more severe: Onion services may
+be flooded with application data in large-volume patterns over long periods of
+time, which can be seen in netflow logs.
+
+For clients, this covert channel typically is only effective after the
+adversary suspects an individual, for confirmation of their suspicion, or
+after Guard Discovery.
+
+Examples of this class of covert channel include:
+ - Application-layer manipulation (AJAX)
+ - Traffic delays (rainbow, swirl - see [BACKLIT])
+ - Onion Service flooding via HTTP POST
+ - Flooding Tor relays to notice traffic changes in onion service throughput
+ - Conflux leg switching patterns
+ - Traffic inflation (1 byte data cells)
+
+Solution: Protocol checks; Padding machines at middles for specific kinds of
+ traffic; limits on inbound onion service traffic; Backlit
+Status: Protocol checks performed for conflux; vanguards addon closes
+ high-volume circuits
+Funding: Not explicitly funded
+
+
+1.3.3. Passive Application-Layer Traffic Patterns
+
+At a Glance:
+ Accuracy: FP=medium, FN=Medium
+ Requires: Compromised Guard (external monitoring increases FP+FN rate)
+ Impact: Links client and destination activity (ie: deanonymization with logs)
+ Path Bias: Not Possible
+ Reason for prioritization: Large FP rate without oracle, debated practicality
+ Signal is: not injected; passively extracted
+ Signal is observed: at Guard, or entire network
+ Signal is: timing and volume patterns of traffic.
+
+This category of information leak occurs after a client has begun using a
+circuit, by analyzing application data traffic.
+
+Examples of this class of information leak include:
+ - Website traffic fingerprinting
+ - End-to-end correlation
+
+The canonical application of this information leak is in end-to-end
+correlation, where application traffic entering the Tor network is correlated
+to traffic exiting the Tor network (see [DEEPCOFFEA]). This attack vector
+requires a global view of all Tor traffic, or false negatives skyrocket.
+However, this information leak is also possible to exploit at a single
+observation point, using machine learning classifiers (see [ROBFINGERPRINT]),
+typically either the Guard or bridge relay, or the path between the
+Guard/bridge and the client.
+
+In both cases, this information leak has a significant false positive rate,
+since application traffic is ad-hoc, arbitrary, and self-similar. Because
+multiple circuits are multiplexed on one TLS connection, the false positive
+and false negative rates are higher still at this observation location, as
+opposed to on a specific circuit.
+
+In both cases, the majority of the information gained by classifiers is in the
+beginning of the trace (see [FRONT] and [DEEPCOFFEA]).
+
+This information leak gets more severe when it is combined with another oracle
+(as per [ORACLES]) that can confirm the statistically derived activity, or
+narrow the scope of material to analyze. Example oracles include:
+ - DNS cache timing
+ - Onion service handshake fingerprinting
+ - Restricting targeting to either specific users, or specific websites
+ - Advertising analytics or account activity log purchase (see
+ [NETFLOW_TICKET])
+
+Website traffic fingerprinting literature is divided into two classes of
+attack study: Open World and Closed World. Closed World is when the adversary
+uses an Oracle to restrict the set of possible websites to classify traffic
+against. Open World is when the adversary attempts to recognize a specific
+website or set of websites out of all possible other traffic.
+
+The nature of the protocol usage by the application can make this attack
+easier or harder, which has resulted in application layer defenses, such as
+[ALPACA]. Additionally, the original Google QUIC was easier to fingerprint
+than HTTP (See [QUICPRINT1]), but IETF HTTP3 reversed this (See [QUICPRINT2]).
+Javascript usage makes these attacks easier (see [INTERSPACE], Table 3), where
+as concurrent activity (in the case of TLS observation) makes them harder.
+Web3 protocols that exchange blocks of data instead of performing AJAX
+requests are likely to be much harder to fingerprint, so long as the web3
+application is accessed via its native protocol, and not via a website
+front-end.
+
+The entire research literature for this vector is fraught with analysis
+problems, unfortunately. Because smaller web crawl sizes make the attacks more
+effective, and because attack papers are easier to produce than defenses
+generally, dismal results are commonplace. [WFNETSIM] and [WFLIVE] examine
+some of these effects. It is common for additional hidden gifts to adversaries
+to creep in, leading to contradictory results, even in otherwise comprehensive
+papers at top-tier venues. The entire vein of literature must be read with a
+skeptical eye, a fine-tooth comb, and a large dumpster nearby.
+
+As one recent example, in an otherwise comprehensive evaluation of modern
+defenses, [DEFCRITIC] found a contrary result with respect to the Javascript
+finding in the [INTERSPACE] paper, by training and testing their classifiers
+with knowledge of the Javascript state of the browser (thus giving them a free
+oracle). In truth, neither [DEFCRITIC] nor [INTERSPACE] properly examined the
+effects of Javascript -- a rigorous test would train and test on a mix of
+Javascript and non-Javascript traffic, and then compare the classification
+accuracy of each set separately, after joint classification. Instead,
+[DEFCRITIC] just reported that disabling Javascript (via the security level of
+Tor Browser) has "no beneficial effect", which they showed by actually letting
+the adversary know which traces had Javascript disabled.
+
+Such hidden gifts to adversaries are commonplace, especially in attack papers.
+While it may be useful to do this while comparing defenses against each other,
+when these assumptions are hidden, and when defenses are not re-tunable for
+more realistic conditions, this leads to focus on burdensome defenses with
+large amounts of delay or huge amounts of overhead, at the expense of ignoring
+lighter approaches that actually improve the situation in practice.
+
+This of course means that nothing gets done at all, because Tor is neither
+going to add arbitrary cell delay at relays (because of queue memory required
+for this and the impacts on congestion control), nor add 400% overhead to
+both directions of traffic.
+
+In terms of defense deployment, it makes the most sense to place these padding
+machines at the Guards to start, for many reasons. This is in contrast to
+other lighter padding machines for earlier vectors, where it makes more sense
+to place them at the middle relay. In this case, the heavier padding machines
+necessary for this vector can take advantage of higher multiplexing, which
+means less overhead. They can also use the congestion signal at the TLS
+connection, to more easily avoid unnecessary padding when the TLS connection
+is blocked, thus only using "slack" Guard capacity. Conflux also can be tuned
+to provide at least some benefit here: even if in lab conditions it provides
+low benefit, in the scenarios studied by [WFNETSIM] and [WFLIVE], this may
+actually be considerable, unless the adversary has both guards, which is more
+difficult for an internal adversary. Additionally, the distinction between
+external and internal adversaries is rarely, if ever, evaluated in the
+literature anyway, so there is little guidance on this distinction as a whole,
+right now.
+
+
+Solution: Application layer solutions ([ALPACA], disabling Javascript, web3 apps);
+ Padding machines at guards for application traffic; conflux tuning
+Status: Unfixed
+Funding: Padding machine and simulator port to arti are funded via Sponsor 112
+
+
+1.3.4. Protocol or Application Linkability
+
+At a Glance:
+ Accuracy: FP=0, FN=0
+ Requires: Compromised Exit; Traffic Observation; Hostile Website
+ Impact: Anonymity Set Reduction
+ Path Bias: Not Possible
+ Reason for prioritization: Low impact with faster releases
+ Signal is: not injected; passively extracted
+ Signal is observed: at Exit, or at application destination
+ Signal is: Rare protocol usage or behavior
+
+Historically, due to Tor's slow upgrade cycles, we have had concerns about
+deploying new features that may fragment the anonymity set of early adopters.
+
+Since we have moved to a more rapid release cycle for both clients and relays
+by abandoning the Tor LTS series, these concerns are much less severe.
+However, they can still present concerns during the upgrade cycle. For
+Conflux, for example, during the alpha series, the fact that few exits
+supported conflux caused us to limit the number of pre-built conflux sets to
+just one, to avoid concentrating alpha users at just a few exits. It is not
+clear that this was actually a serious anonymity concern, but it was certainly
+a concern with respect to concentrating the full activity of all these users
+at just a few locations, for load balancing reasons alone.
+
+Similar concerns exist for users of alternate implementations, both of Tor,
+and of applications like the browser. We regard this as a potential research
+concern, but it is likely not a severe one. For example, assuming Tor Browser
+and Brave both address browser fingerprinting, how bad is it for anonymity
+that they address it differently? Even if they ensure that all their users
+have the same or similar browser fingerprints, it will still be possible for
+websites, analytics datasets, and possibly even Exit relays or Exit-side
+network observers, to differentiate the use of one browser versus the other.
+Does this actually harm their anonymity in a real way, or must other oracles
+be involved? Are these oracles easy to obtain?
+
+Similarly, letting users choose their exit country is in this category. In
+some circumstances, this choice has serious anonymity implications: if the
+choice is a permanent, global one, and the user chooses an unpopular country
+with few exits, all of their activity will be much more linkable. However, if
+the country is popular, and/or if the choice is isolated per-tab or per-app,
+is this still significant such that it actually enables any real attacks? It
+seems like not so much.
+
+Solutions: Faster upgrade cycle; Avoiding concentrated use of new features
+Status: Tor LTS series is no longer supported
+Funding: Not explicitly funded
+
+
+1.3.5. Latency Measurement
+
+At a glance:
+ Accuracy: FP=high, FN=high
+ Requires: Onion service, or malicious Exit
+ Impact: Anonymity Set Reduction/Rough geolocation of services
+ Path Bias: Possible exacerbating factor
+ Reason for Prioritization: Low impact; multiple observations required
+ Signal is created naturally by anything that has a "reply" mechanic
+ Signal is observed at either end.
+ Signal is: delays between a message sent and a message received in reply.
+
+Latency's effects on anonymity set has been studied in the [LATENCY_LEAK]
+papers.
+
+It may be possible to get a rough idea of the geolocation of an onion service
+by measuring the latency over many different circuits. This seems more
+realistic if the Guard or Guards are known, so that their contribution to
+latency statistics can be factored in, over many many connections to an onion
+service. For normal client activity, route selection and the fact that the
+Exit does not know specific accounts or cookies in use likely provides enough
+protection.
+
+If this turns out to be severe, it seems the best option is to add a delay on
+the client side to attempt to mask the overall latency. This kind of approach
+is only likely to make sense for onion services. Other path selection
+alterations may help, though.
+
+Solutions: Guards, vanguards, alternative path selection, client-side delay
+Status: Guards and vanguards-lite are used in Tor since 0.4.7
+Funding: Not explicitly funded
+
+
+2. Attack Examples
+
+To demonstrate how info leaks combine, here we provide some historical
+real-world attacks that have used these info leaks to deanonymize Tor
+users.
+
+
+2.1. CMU Tagging Attack
+
+Perhaps the most famous historical attack was when a group at CMU assisted the
+FBI in performing dragnet deanonymization of Tor users, through their
+[RELAY_EARLY] attack on the live network. This attack could only work on users
+who happened to use their Guards, but those users could be fully deanonymized.
+
+The attack itself operated on connections to monitored HSDIRs: it encoded the
+address of the onion service in the cell command header, via the RELAY_EARLY
+bitflipping technique from Section 1.1.2. Their Guards then recorded this
+address, along with the IP address of the user, providing a log of onion
+services that each IP address visited.
+
+It is not clear if the CMU group even properly utilized the full path bias
+attack power here to deanonymize as many Tor users as possible, or if their
+logs were simply of interest to the FBI because of what they happened to
+capture. It seems like the latter is the case.
+
+A similar, motivated adversary could use any of the covert channels in Section
+1.1, in combination with Path Bias to close non-deanonymized circuits, to
+fully deanonymize all exit traffic carried by their Guard relays. There are
+path bias detectors in Tor to detect large amounts of circuit failure, but
+when the network (or the Guard) is also under heavy circuit load, they can
+become unreliable, and have their own false positives.
+
+While this attack vector requires the Guard relay, it is of interest to any
+adversary that would like to perform dragnet deanonymization of a wide range
+of Tor users, or to compel a Guard to deanonymize certain Tor users. It is
+also of interest to adversaries with censorship capability, who would like
+to monitor all Tor usage of users, rather than block them. Such an adversary
+would use their censorship capability to direct Tor users to only their own
+malicious Guards or Bridges.
+
+
+2.2. Guard Discovery Attacks with Netflow Deanonymization
+
+Prior to the introduction of Vanguards-lite in Tor 0.4.7, it was possible to
+combine "1.2.2. Adversary-Induced Circuit Creation", with a circuit-based
+covert channel (1.1.3, 1.2.1, or 1.3.2), to obtain a middle relay confirmed
+to be next to the user's Guard.
+
+Once the Guard is obtained, netflow connection times can be used to find the
+user of interest.
+
+There was at least one instance of this being used against a user of Ricochet,
+who was fully deanonymized. The user was using neither vanguards-lite, nor the
+vanguards addon, so this attack was trivial. It is unclear which covert
+channel type was used for Guard Discovery. The netflow attack proceeded
+quickly, because the attacker was able to determine when the user was on and
+offline via their onion service descriptor being available, and the number
+of users at the discovered Guard was relatively small.
+
+
+2.3. Netflow Anonymity Set Reduction
+
+Netflow records have been used, to varying degrees of success, to attempt to
+identify users who have posted violent threats in an area.
+
+In most cases, this has simply ended up hassling unrelated Tor users, without
+finding the posting user. However, in at least one case, the user was found.
+
+Netflow records were also reportedly used to build suspicion of a datacenter
+in Germany which was emitting large amounts of Tor traffic, to eventually
+identify it as a Tor hosting service providing service to drug markets, after
+further investigation. It is not clear if a flooding attack was also used in
+this case.
+
+
+2.4. Application Layer Confirmation
+
+The first (and only) known case of fine-grained traffic analysis of Tor
+involved an application layer confirmation attack, using the vector from
+1.3.2.
+
+In this case, a particular person was suspected as being involved in a group
+under investigation, due to the presence of an informant in that group. The
+FBI then monitored the suspect's WiFi, and sent a series of XMPP ping messages
+to the account in question. Despite the use of Tor, enough pings were sent
+such that the timings on the monitored WiFi showed overlap with the XMPP
+timings of sent pings and responses. This was prior to Tor's introduction of
+netflow padding (which generates similar back-and-forth traffic every 4-9
+seconds between the client and the Guard).
+
+It should be noted that such attacks are still prone to error, especially for
+heavy Tor users whose other traffic would always cause such overlap, as
+opposed to those who use Tor for only one purpose, and very lightly or
+infrequently.
+
+
+3. Glossary
+
+Covert Channel:
+ A kind of information leak that allows an adversary to send information
+ to another point in the network.
+
+Collusion Signal:
+ A Covert Channel that only reliably conveys 1 bit: if an adversary is
+ present. Such covert channels are weaker than those that enable full
+ identifier transmission, and also typically require correlation.
+
+Confirmation Signal:
+ Similar to a collusion signal, a confirmation signal is sent over a
+ weak or noisy channel, and can only confirm that an already suspected
+ entity is the target of the signal.
+
+False Negative:
+ A false negative is when the adversary fails to spot the presence of
+ an info leak vector, in instances where it is actually present.
+
+False Positive:
+ A false positive is when the adversary attempts to use an info leak vector,
+ but some similar traffic pattern or behavior elsewhere matches the traffic
+ pattern of their info leak vector.
+
+Guard Discovery:
+ The ability of an adversary to determine the Guard in use by a service or
+ client.
+
+Identifier Transmission:
+ The ability of a covert channel to reliably encode a unique identifier,
+ such as an IP address, without error.
+
+Oracle:
+ An additional mechanism used to confirm an observed info leak vector
+ that has a high rate of False Positives. Can take the form of DNS
+ cache, server logs, analytics data, and other factors. (See [ORACLES]).
+
+Path Bias (aka Route Manipulation, or Route Capture):
+ The ability of an adversary to direct circuits towards their other
+ compromised relays, by destroying circuits and/or TLS connections
+ whose paths are not sufficiently compromised.
+
+
+Acknowledgments:
+
+This document has benefited from review and suggestions by David Goulet, Nick
+Hopper, Rob Jansen, Nick Mathewson, Tobias Pulls, and Florentin Rochet.
+
+
+References:
+
+[ALPACA]
+ https://petsymposium.org/2017/papers/issue2/paper54-2017-2-source.pdf
+
+[BACKLIT]
+ https://www.freehaven.net/anonbib/cache/acsac11-backlit.pdf
+
+[DEEPCOFFEA]
+ https://www-users.cse.umn.edu/~hoppernj/deepcoffea.pdf
+
+[DEFCRITIC]
+ https://www-users.cse.umn.edu/~hoppernj/sok_wf_def_sp23.pdf
+
+[DNSORACLE]
+ https://www.usenix.org/system/files/usenixsecurity23-dahlberg.pdf
+ https://gitlab.torproject.org/rgdd/ttapd/-/tree/main/artifact/safety-board
+ https://gitlab.torproject.org/tpo/core/tor/-/issues/40674
+ https://gitlab.torproject.org/tpo/core/tor/-/issues/40539
+ https://gitlab.torproject.org/tpo/core/tor/-/issues/32678
+
+[DOSSECURITY]
+ https://www.princeton.edu/~pmittal/publications/dos-ccs07.pdf
+
+[DROPMARK]
+ https://petsymposium.org/2018/files/papers/issue2/popets-2018-0011.pdf
+
+[FLASHFLOW]
+ https://gitweb.torproject.org/torspec.git/tree/proposals/316-flashflow.md
+
+[FRONT]
+ https://www.usenix.org/system/files/sec20summer_gong_prepub.pdf
+
+[GUARDSETS]
+ https://www.freehaven.net/anonbib/cache/guardsets-pets2015.pdf
+ https://www.freehaven.net/anonbib/cache/guardsets-pets2018.pdf
+
+[INTERSPACE]
+ https://arxiv.org/pdf/2011.13471.pdf (Table 3)
+
+[LATENCY_LEAK]
+ https://www.freehaven.net/anonbib/cache/ccs07-latency-leak.pdf
+ https://www.robgjansen.com/publications/howlow-pets2013.pdf
+
+[LYING_SCANNER]
+ https://gitlab.torproject.org/tpo/network-health/team/-/issues/313
+
+[METRICSLEAK]
+ https://gitlab.torproject.org/tpo/core/tor/-/issues/23512
+
+[NETFLOW_TICKET]
+ https://gitlab.torproject.org/tpo/network-health/team/-/issues/42
+
+[ONECELL]
+ https://www.blackhat.com/presentations/bh-dc-09/Fu/BlackHat-DC-09-Fu-Break-Tors-Anonymity.pdf
+
+[ONIONPRINT]
+ https://www.freehaven.net/anonbib/cache/circuit-fingerprinting2015.pdf
+
+[ONIONFOUND]
+ https://www.researchgate.net/publication/356421302_From_Onion_Not_Found_to_Guard_Discovery/fulltext/619be24907be5f31b7ac194a/From-Onion-Not-Found-to-Guard-Discovery.pdf?origin=publication_detail
+
+[ORACLES]
+ https://petsymposium.org/popets/2020/popets-2020-0013.pdf
+
+[PADDING_SPEC]
+ https://gitlab.torproject.org/tpo/core/torspec/-/blob/main/padding-spec.txt#L68
+
+[PCP]
+ https://arxiv.org/abs/2103.03831
+
+[QUICPRINT1]
+ https://arxiv.org/abs/2101.11871 (see also: https://news.ycombinator.com/item?id=25969886)
+
+[QUICPRINT2]
+ https://netsec.ethz.ch/publications/papers/smith2021website.pdf
+
+[RACCOON23]
+ https://archives.seul.org/or/dev/Mar-2012/msg00019.html
+
+[RELAY_EARLY]
+ https://blog.torproject.org/tor-security-advisory-relay-early-traffic-confirmation-attack/
+
+[ROBFINGERPRINT]
+ https://www.usenix.org/conference/usenixsecurity23/presentation/shen-meng
+
+[SBWS]
+ https://tpo.pages.torproject.net/network-health/sbws/how_works.html
+
+[WFLIVE]
+ https://www.usenix.org/system/files/sec22-cherubin.pdf
+
+[WFNETSIM]
+ https://petsymposium.org/2023/files/papers/issue4/popets-2023-0125.pdf
+```
diff --git a/proposals/345-specs-in-mdbook.md b/proposals/345-specs-in-mdbook.md
new file mode 100644
index 0000000..40c9504
--- /dev/null
+++ b/proposals/345-specs-in-mdbook.md
@@ -0,0 +1,255 @@
+```
+Filename: 345-specs-in-mdbook.md
+Title: Migrating the tor specifications to mdbook
+Author: Nick Mathewson
+Created: 2023-10-03
+Status: Closed
+```
+
+# Introduction
+
+I'm going to propose that we migrate our specifications to a
+set of markdown files, specifically using the [`mdbook`]
+tool.
+
+This proposal does _not_ propose a bulk rewrite of our specs;
+it is meant to be a low-cost step forward that will produce
+better output, and make it easier to continue working on our
+specs going forward.
+
+That said, I think that this change will enable rewrites
+in the future. I'll explain more below.
+
+# What is mdbook?
+
+Mdbook is a tool developed by members of the Rust community to
+create books with [Markdown]. Each chapter is a single
+markdown file; the files are organized into a book using a
+[`SUMMARY.md`] file.
+
+Have a look at the [`mdbook` documentation][`mdbook`]; this is
+what the output looks like.
+
+Have a look at this [source tree]: that's the input that
+produces the output above.
+
+Markdown is extensible: it can use numerous [plugins] to
+enhance the semantics of the the markdown input, add diagrams,
+output in more formats, and so on.
+
+# What would using mdbook get us _immediately_?
+
+There are a bunch of changes that we could get immediately via
+even the simplest migration to mdbook. These immediate
+benefits aren't colossal, but they are things we've wanted for
+quite a while.
+
+* We'll have a document that's easier to navigate (via the sidebars).
+
+* We'll finally have good HTML output.
+
+* We'll have all our specifications organized into a single
+ "document", able to link to one another and cross reference
+ one another.
+
+* We'll have perma-links to sections.
+
+* We'll have a built-in text search function. (Go to the [`mdbook`]
+ documentation and hit "`s`" to try it out.)
+
+## How will mdbook help us _later on_ as we reorganize?
+
+Many of the benefits of mdbook will come later down the line as we
+improve our documentation.
+
+* Reorganizing will become much easier.
+
+ * Our links will no longer be based on section number, so we
+ won't have to worry about renumbering when we add new sections.
+ * We'll be able to create redirects from old section filenames
+ to new ones if we need to rename a file completely.
+ * It will be far easier to break up our files into smaller files
+ when we find that we need to reorganize material.
+
+* We will be able make our documents even _easier_ to navigate.
+
+ * As we improve our documentation, we'll be able to use links
+ to cross-reference our sections.
+
+* We'll be able to include real diagrams and tables.
+
+ * We're already using the [`mermaid`] tool in Arti in
+ generate [protocol diagrams] and [architecture diagrams];
+ we can use this in our specs too, instead of hand-drawn
+ ASCII art.
+
+* We'll be able to integrate proposals more easily.
+
+ * New proposals can become new chapters in our specification
+ simply by copying them into a new 'md' file or files; we won't
+ have to decide between integrating them into existing files
+ or creating a new spec.
+
+ * Implemented but unmerged proposals can become additional chapters
+ in an appendix to the spec. We can refer to them with permalinks
+ that will still work when they move to another place in the specs.
+
+
+# How should we do this?
+
+
+## Strategy
+
+My priorities here are:
+ * no loss of information,
+ * decent-looking output,
+ * a quick automated conversion process that won't lose a bunch of time.
+ * a process that we can run experimentally until we are satisfied
+ with the results
+
+With that in mind, I'm writing a simple set of [`torspec-converter`]
+scripts to convert our old torspec.git repository into its new format.
+We can tweak the scripts until we like the that they produce.
+
+After running a recent `torspec-converter` on a fairly recent
+torspec.git, here is how the branch looks:
+
+
+https://gitlab.torproject.org/nickm/torspec/-/tree/spec_conversion?ref_type=heads
+
+And here's the example output when running mdbook on that branch:
+
+https://people.torproject.org/~nickm/volatile/mdbook-specs/index.html
+
+> Note: these is not a permanent URL; we won't keep the example output
+> forever. When we actually merge the changes, they will move into
+> whatever final location we provide.
+
+The conversion script isn't perfect. It only recognizes three kinds of
+content: headings, text, and "other". Content marked "other" is
+marked with \`\`\` to reneder it verbatim.
+
+The choice of which sections to split up and which to keep as a single
+page is up to us; I made some initial decisions in the file above, but
+we can change it around as we please. See the [configuration section]
+at the end of the `grinder.py` script for details on how it's set up.
+
+## Additional work that will be needed
+
+Assuming that we make this change, we'll want to build an automated CI
+process to build it as a website, and update the website whenever
+there is a commit to the specifications.
+
+(This automated CI process might be as simple as `git clone && mdbook
+build && rsync -avz book/ $TARGET`.)
+
+We'll want to go through our other documentation and update links,
+especially the permalinks in spec.torproject.org.
+
+It might be a good idea to use spec.torproject.org as the new location
+of this book, assuming weasel (who maintains spec.tpo) also thinks
+it's reasonable.
+If we do that, we need to
+decide on what we want the landing page to look like, and we need
+_very much_ to get our permalink story correct. Right now I'm
+generating a .htaccess file as part of the conversion.
+
+
+## Stuff we shouldn't do.
+
+I think we should continue to use the existing torspec.git repository
+for the new material, and just move the old text specs into a new
+archival location in torspec. (We *could* make a new repository
+entirely, but I don't think that's the best idea. In either case, we
+shouldn't change the text specifications after the initial
+conversion.)
+
+
+We'll want to figure out our practices for keeping links working as we
+reorganize these documents. Mdbook has decent redirect support, but
+it's up to us to actually create the redicrets as necessary.
+
+
+
+# The transition, in detail
+
+* Before the transition:
+ - Work on the script until it produces output we like.
+ - Finalize this proposal and determine where we are hosting everything.
+ - Develop the CI process as needed to keep the site up to date.
+ - Get approval and comment from necessary stakeholders.
+ - Write documentation as needed to support the new way of doing things.
+ - Decide on the new layout we want for torspec.git.
+
+* Staging the transition:
+ - Make a branch to try out the transition; explicitly allow force-pushing that branch. (Possibly nickm/torspec.git in a branch called mdbook-demo, or torspec.git in a branch called mdbook-demo assuming it is not protected.)
+ - Make a temporary URL to target with the transition (possibly spec-demo.tpo)
+ - Once we want to do the transition, shift the scripts to tpo/torspec.git:main and spec.tpo, possibly?
+
+* The transition:
+ - Move existing specs to a new subdirectory in torspec.git.
+ - Run the script to produce an mdbook instance in torspec.git with the right layout.
+ - Install the CI process to keep the site up to date.
+
+* Post-transition
+ - Update links elsewhere.
+ - Continue to improve the specs.
+
+# Integrating proposals
+
+We could make all of our proposals into a separate book, like rust
+does at https://rust-lang.github.io/rfcs/ . We could also leave them
+as they are for now.
+
+(I don't currently think we should make all proposals part of the spec
+automatically.)
+
+
+# Timing
+
+I think the right time to do this, if we decide to move ahead, is
+before November. That way we have this issue as something people can
+work on during the docs hackathon.
+
+# Alternatives
+
+I've tried experimenting with Docusaurus here, which is even more
+full-featured and generates pretty react sites
+[like this](https://docusaurus.io/).
+(We're likely to use it for managing the Arti documentation and
+website.)
+
+For the purposes we have here, it seems slightly overkill, but I do
+think a migration is feasible down the road if we decide we _do_ want
+to move to docusaurus. The important thing is the ability to keep our
+URLs working, and I'm confident we could do that
+
+The main differences for our purposes here seem to be:
+
+ * The markdown implementation in Docusaurus is extremely picky about
+ stuff that looks like HTML but isn't; it rejects it, rather than
+ passing it on as text. Thus, using it would require a more
+ painstaking conversion process before we could include text like
+ `"<state:on>"` or `"A <-> B"` as our specs do in a few places.
+
+ * Instead of organizing our documents in a `SUMMARY.md` with an MD
+ outline format, we'd have to organize them in a `sidebar.js` with a
+ javascript syntax.
+
+ * Docusaurus seems to be far more flexible and have a lot more
+ features, but also seems trickier to configure.
+
+
+
+<-- References -->
+
+[`mdbook`]: https://rust-lang.github.io/mdBook/
+[source tree]: https://github.com/rust-lang/mdBook/tree/master/guide/src/
+[Markdown]: https://en.wikipedia.org/wiki/Markdown
+[`SUMMARY.md`]: https://rust-lang.github.io/mdBook/format/summary.html
+[plugins]: https://github.com/rust-lang/mdBook/wiki/Third-party-plugins
+[`mermaid`]: https://mermaid.js.org/
+[architecture diagrams]: https://gitlab.torproject.org/tpo/core/arti/-/blob/main/doc/dev/Architecture.md
+[protocol diagrams]: https://gitlab.torproject.org/tpo/core/arti/-/blob/main/doc/dev/hs-overview.md
+[`torspec-converter`]: https://gitlab.torproject.org/nickm/torspec-converter
+[configuration section]: https://gitlab.torproject.org/nickm/torspec-converter/-/blob/main/grinder.py?ref_type=heads#L310 \ No newline at end of file
diff --git a/proposals/346-protovers-again.md b/proposals/346-protovers-again.md
new file mode 100644
index 0000000..a5c7e24
--- /dev/null
+++ b/proposals/346-protovers-again.md
@@ -0,0 +1,298 @@
+```
+Filename: 346-protovers-again.md
+Title: Clarifying and extending the use of protocol versioning
+Author: Nick Mathewson
+Created: 19 Oct 2023
+Status: Open
+```
+
+# Introduction
+
+In proposal 264, we introduced "subprotocol versions" as a way to
+independently version different pieces of the Tor protocols, and
+communicate which parts of the Tor protocols are supported,
+recommended, and required.
+
+Here we clarify the semantics of individual subprotocol versions, and
+describe more ways to use and negotiate them.
+
+# Semantics: Protocol versions are feature flags
+
+One issue we left unclarified previously is the relationship between
+two different versions of the same subprotocol. That is, if we know
+the semantics of (say) `Handshake=7`, can we infer anything about a
+relay that supports `Handshake=8`? In particular, can we infer that
+it supports all of the same features implied by `Handshake=7`? If we
+want to know "does this relay support some feature supported by
+`Handshake=7`", must we check whether it supports `Handshake=7`, or
+should we check `Handshake=x for any x≥7`?
+
+In this proposal, we settle the question as follows: subprotocol
+versions are flags. They do not have any necessary semantic
+relationship between them.
+
+We reject the `≥` interpretation for several reasons:
+ * It's tricky to implement.
+ * It prevents us from ever removing a feature.
+ * It requires us to implement features in the same order across
+ all Tor versions.
+
+## ...but sometimes a flag _is_ a version!
+
+There _are_ some places in our protocol (notably: directory authority
+consensus methods, and channel protocol versions) where there _is_ a
+semantic relationship between version numbers. Specifically: "higher
+numbers are already better". When parties need to pick a one of
+_these_ versions, they always pick the highest version number
+supported by enough of them.
+
+When this kind of _real_ version intersects with the "subprotocol
+versions" system, we use the same numbers:
+
+ * `Link` subprotocols correspond one-to-one with the version numbers
+ sent in a VERSIONS cell.
+ * `Microdesc` and `Cons` subprotocols correspond to a _subset_ of
+ the version numbers of consensus methods.
+
+## How to document subprotocol versions
+
+When describing a subprotocol, we should be clear what relationship,
+if any, exists between its versions and any versions negotiated
+elsewhere in the specifications.
+
+Unless otherwise documented, all versions can be in use _at the same
+time_: if only one can exist at once (on a single circuit, a single
+document, etc), this must be documented.
+
+> Implication: This means that we must say (for example) that you
+> can't use Link=4 and Link=5 on the same channel.
+
+# Negotiating protocol versions in circuit handshakes.
+
+Here we describe a way for a client to opt into features as part of
+its circuit handshake, in order to avoid proliferating negotiating
+extensions.
+
+## Binary-encoding protocol versions.
+
+We assign a one-byte encoding for each protocol version number,
+ordered in the same way as in tor-spec.
+
+| Protocol | Id |
+| --- | --- |
+| Link | 0 |
+| LinkAuth | 1 |
+| Relay | 2 |
+| DirCache | 3 |
+| HSDir | 4 |
+| HSIntro | 5 |
+| HSRend | 6 |
+| Desc | 7 |
+| MicroDesc| 8 |
+| Cons | 9 |
+| Padding | 10 |
+| FlowCtrl | 11 |
+| Conflux | 12 |
+| RelayCell| 13 |
+| Datagram | TBD|
+
+> Note: This is the same encoding used in [walking onions proposal][prop323].
+> It takes its order from the ordering of protocol versions in
+> [tor-spec][subprotocol-versioning] and matches up with the values defined in
+> for `protocol_type_t` in C tor's `protover.h`.
+
+## Requesting an opt-in circuit feature
+
+When a client wants to request a given set of features, it sends an
+`ntor_v3` extension containing:
+
+```
+struct subproto_request {
+ struct req[..]; // up to end of extension
+}
+
+struct req {
+ u8 protocol_id;
+ u8 protovol_version;
+}
+```
+
+> Note 1: The above format does not include any parameters for each
+> req. Thus, if we're negotiating an extension that requires a client-
+> supplied parameter, it may not be appropriate to use this
+> request format.
+>
+> Note 2: This proposal does not include any relay extension
+> acknowledging support. In the case of individual subprotocols, we could
+> later say "If this subprotocol is in use, the relay MUST also send
+> extension foo".
+>
+> Note 3: The existence of this extension does not preclude the later
+> addition of other extensions to negotiate featuress differently, or
+> to do anything else.
+
+Each `req` entry corresponds to a single subprotocol version. A client
+MUST NOT send any `req` entry unless:
+ * That subprotocol version is advertised by the relay,
+ * OR that subprotocol version is listed as required for relays in the
+ current consensus, using `required-relay-protocols`.
+
+> Note: We say above that a client may request a _required_ subprotocol
+> even if the relay does not advertise it. This is what allows
+> clients to send a `req` extension to introduction points and
+> rendezvous points, even when we do not recognize the relay from the
+> consensus.
+>
+> Note 2: If the intro/rend point does not support a _required_ protocol,
+> it should not be on the network, and the client/service should not have
+> selected it.
+
+If a relay receives a `subproto_request` extension for any subprotocol
+version that it does not support, it MUST reject the circuit with a
+DESTROY cell.
+
+> Alternatives: we _could_ give the relay the option to
+> decline to support an extension, and we _could_ require the
+> relay to acknowledge which extensions it is providing.
+> We aren't doing that, in the name of simplicity.
+
+Only certain subprotocol versions need to be negotiated in this way;
+they will be explicitly listed as such in our specifications, with
+language like "This extension is negotiated as part of the circuit
+extension handshake". Other subprotocol versions MUST NOT be listed
+in this extension; if they are, the relay SHOULD reject the circuit.
+
+> Alternative: We _could_ allow the client to list other subprotocols
+> that the relay supports which are nonetheless irrelevant to
+> the circuit protocol, like `Microdesc`, or ones that don't currently need
+> to be negotiated, like `HsRend`.
+>
+> This is not something we plan to do.
+
+Currently specified subprotocol versions which can be negotiated using
+this extension are:
+
+ * FlowCtrl=2 (congestion control)
+ * RelayCell=1 (proposal 340)
+
+The availability of the `subproto_request` extension itself
+will be indicated by a new Relay=X flag. When used, it will supplant
+several older `ntor_v3` extensions, including:
+
+ * (TODO: list these here, if we find any. I think FlowCtrl has an
+ extension?)
+
+That is, if using `subproto_request`, there is no need to send the
+(TODO) extensions.
+
+
+
+## Making features that can be disabled.
+
+Sometimes, we will want the ability to make features that can be
+enabled or disabled from the consensus. But if we were to make a single
+flag that can turn the feature on and off, we'd run into trouble:
+after the feature was turned off, every relay would stop providing it
+right away, but there would be a delay before clients realized that
+the relays had stopped advertising the feature. During this interval,
+clients would try to enable the feature, and the relays would reject
+their circuits.
+
+To solve this problem, we need to make features like these controlled
+by a _pair_ of consensus parameters: one to disable advertising the
+feature, and one to disable the feature itself. To disable a feature,
+first the authorities would tell relays to stop advertising it, and
+only later tell the relays to stop supporting it. (If we want to
+_enable_ a previously disabled feature, we can turn on advertisement
+and support at the same time.)
+
+These parameters would be specified something like this (for a
+hypthetical `Relay=33` feature).
+
+ * `support-relay-33`: if set to 1, relays that can provide
+ `Relay=33` should do so.
+ * `advertise-relay-33`: if set to 1, relays that are
+ providing `Relay=33` should include it in their advertised
+ protocol versions.
+
+Note: as a safety measure, relays MUST NOT advertise any feature that
+they do not support. This is reflected in the descriptions of the
+parameters above.
+
+When we add a new feature of this kind, we should have the
+`advertise-*` flag parameter be `1` by default, and probably we should
+have `support-*` be `1` by default oo.
+
+# Subprotocol versions in onion services
+
+Here we describe how to expand the onion service protocols in order
+to better accomodate subprotocol versions.
+
+## Advertising an onion service's subprotocols
+
+In its encrypted descriptor (the innermost layer), the onion service
+adds a new entry:
+
+ * `"protocols"` - A list of supported subprotocol versions, in the
+ same format as those listed in a microdescriptor or descriptor.
+
+Note that this is NOT a complete list of all the subprotocol versions
+actually supported by the onion service. Instead, onion services only
+advertise a subprotocol version if they support it, _and_ it is
+documented in the specs as being supported by onion services.
+
+> Alternative: I had considered having a mask that would be put in the
+> consensus document, telling the onion services which subprotocols
+> to advertise. I don't think that's a great idea, however.
+
+Right now, the following protocols should be advertised:
+
+ - FlowCtrl
+ - Conflux (?? Doesn't this take parameters? TODO)
+ - Pow (??? Doesn't this take parameters? If we do it, we need to
+ allocate a subprotocol for it. TODO)
+
+
+## Negotiating subprotocols with an onion service.
+
+In the `hs_ntor` handshake sent by the client, we add an encrypted
+`subproto_request` extension of the same format, with the same
+semantics, as used in the `ntor-v3` handshake.
+
+This supplants the following:
+
+ - (Congestion Control; Pow? TODO)
+
+
+## Advertising other relays' subprotocols?
+
+> Alternative: I had previously considered a design where the introduction points
+> in the onion service descriptor would be listed along with their
+> subprotocols, and the `hs_ntor` handshake would contain the
+> subprotocols of the rendezvous point.
+>
+> I'm rejecting this design for now because it gives the onion service
+> and the client too much freedom to lie about relays. In the future,
+> the walking onions design would solve this, since the contact
+> information for intro and rend points would be authenticated.
+
+# Appendix
+
+New numbers to reserve:
+
+ * An extension ID for the `ntor_v3` handshake `subproto_request`
+ extension.
+ * An extension ID for the `hs_ntor` handshake `subproto_request`
+ extension.
+ * A Relay= subprotocol indicating support for the ntor-v3 and
+ hs_ntor extensions.
+ * The numeric encoding of each existing subprotocol, in the table
+ above.
+
+# Acknowledgments
+
+Thanks to David Goulet and Mike Perry for their feedback on earlier
+versions of this proposal!
+
+[prop323]: https://spec.torproject.org/proposals/323-walking-onions-full.html
+[subprotocol-versioning]: https://spec.torproject.org/tor-spec/subprotocol-versioning.html
diff --git a/proposals/347-domain-separation.md b/proposals/347-domain-separation.md
new file mode 100644
index 0000000..3056d10
--- /dev/null
+++ b/proposals/347-domain-separation.md
@@ -0,0 +1,80 @@
+```
+Filename: 347-domain-separation.md
+Title: Domain separation for certificate signing keys
+Author: Nick Mathewson
+Created: 19 Oct 2023
+Status: Open
+```
+
+## Our goal
+
+We'd like to be able to use the "family key" from proposal 321 as a
+general purpose signing key, to authenticate other things than the
+membership of a family. For example, we might want to have a
+challenge/response mechanism where the challenger says, "If you want
+to log in as the owner of the account corresponding to this family,
+sign the following challenge with your key. Or we might want to
+have a message authentication scheme where an operator can
+sign a message in a way that proves key ownership.
+
+We _might_ also like to use relay identity keys or onion service
+identitiy keys for the same purpose.
+
+## The problem
+
+When we're using a signing key for two purposes, it's important
+to perform some kind of domain separation so that documents
+signed for one purpose can't be mistaken for documents signed for the
+other.
+
+For example, in the challenge/response example, it would be bad if
+the challenger could provide a challenge string that would cause the
+signer to inadvertently authenticate an incorrect family.
+
+These keys are currently used in some places with no
+personalization. Their signature format is as described in
+`cert-spec.txt`, which says:
+
+> The signature is created by signing all the fields in
+> the certificate up until "SIGNATURE" (that is, signing
+> sizeof(ed25519_cert) - 64 bytes).
+
+
+
+## One solution
+
+This one is pretty easy: we would extend `cert-spec` as follows.
+
+
+> ### Using signing keys for other purposes.
+>
+> Other protocols may introduce other uses for the signing keys
+> in these certificates other than those specified here. When
+> they do, they MUST ensure that the documents being signed
+> cannot be confused with the certificate bodies of this document.
+>
+> In some existing cases in the Tor protocols, we achieve this by
+> specifying an ASCII prefix string that must be prepended to the
+> other protocol's signed object before it is signed.
+>
+> For future protocols, we recommend that this be done by
+> specifying that the signing key is to be used to sign a
+> cSHAKE digest (or other secure customizable digest)
+> of the other protocol's signed object, using
+> a customization string unique to the other protocol.
+
+We would also make this amendment:
+
+> ### Future versions of this specification
+>
+> In order to maintain the domain separation that currently exists
+> between the signatures on these certificates and other documents
+> signed with the same keys, it suffices (for now!) that these
+> certificates begin with the version byte `[01]`, whereas
+> the other documents are in printable ASCII, which never
+> includes `[01]`.
+>
+> Future versions of this specification SHOULD move to using
+> an ed25519-prehash construction, using a customizable hash
+> with built-in domain separation.
+
diff --git a/proposals/348-udp-app-support.md b/proposals/348-udp-app-support.md
new file mode 100644
index 0000000..9482a8f
--- /dev/null
+++ b/proposals/348-udp-app-support.md
@@ -0,0 +1,742 @@
+```
+Filename: 348-udp-app-support.md
+Title: UDP Application Support in Tor
+Author: Micah Elizabeth Scott
+Created: December 2023
+Status: Open
+```
+
+# UDP Application Support in Tor
+
+## Table of Contents
+
+- [Introduction](#introduction)
+ - [History](#history)
+ - [Scope](#scope)
+- [UDP Traffic Models](#udp-traffic-models)
+ - [User Datagram Protocol (RFC768)](#user-datagram-protocol-rfc768)
+ - [Socket Layer](#socket-layer)
+ - [Network Address Translation (NAT)](#network-address-translation-nat)
+ - [Mapping and Filtering Behaviors](#mapping-and-filtering-behaviors)
+ - [Common Protocols](#common-protocols)
+ - [QUIC](#quic)
+ - [WebRTC](#webrtc)
+ - [Common Applications](#common-applications)
+- [Overview of Possible Solutions](#overview-of-possible-solutions)
+ - [Datagram Routing](#datagram-routing)
+ - [Intentional UDP Leak](#intentional-udp-leak)
+ - [3rd Party Implementations](#3rd-party-implementations)
+ - [Future Work on Tor](#future-work-on-tor)
+ - [Tunneling](#tunneling)
+ - [TURN Encapsulated in Tor Streams](#turn-encapsulated-in-tor-streams)
+ - [Tor Stream Tunnel to an Exit](#tor-stream-tunnel-to-an-exit)
+ - [Tor Stream Tunnel to a Rendezvous Point](#tor-stream-tunnel-to-a-rendezvous-point)
+- [Specific Designs Using Tor Streams](#specific-designs-using-tor-streams)
+ - [One Stream per Tunnel (VPN)](#one-stream-per-tunnel-vpn)
+ - [One Stream per Local Port (TURN)](#one-stream-per-local-port-turn)
+ - [One Stream per Local Port (Proposal 339)](#one-stream-per-local-port-proposal-339)
+ - [One Stream per Local Port (NAT Mapping)](#one-stream-per-local-port-nat-mapping)
+ - [One Stream per Flow](#one-stream-per-flow)
+ - [Hybrid Mapping and Flow Approach](#hybrid-mapping-and-flow-approach)
+- [Risks](#risks)
+ - [Behavior Regressions](#behavior-regressions)
+ - [Bandwidth Usage](#bandwidth-usage)
+ - [Local Port Exhaustion](#local-port-exhaustion)
+ - [Application Fingerprinting](#application-fingerprinting)
+ - [Peer-to-Peer Metadata Collection](#peer-to-peer-metadata-collection)
+ - [Interaction with Other Networks](#interaction-with-other-networks)
+ - [Traffic Injection](#traffic-injection)
+ - [Malicious Outgoing Traffic](#malicious-outgoing-traffic)
+- [Next Steps](#next-steps)
+ - [Requiring a Long-Term Datagram Plan](#requiring-a-long-term-datagram-plan)
+ - [Alternatively, Modular Application-Level Support](#alternatively-modular-application-level-support)
+
+## Introduction
+
+This proposal takes a fresh look at the problem of implementing support in Tor for applications which require UDP/IP communication.
+
+This work is being done with the sponsorship and goals of the [Tor VPN Client for Android project](https://gitlab.torproject.org/groups/tpo/-/milestones/32).
+
+The proposal begins with a summary of previous work and the specific problem space being addressed.
+This leads into an analysis of possible solutions, and finally some possible conclusions about the available development opportunities.
+
+### History
+
+There have already been multiple attempts over Tor's history to define some type of UDP extension.
+
+#### 2006
+
+[Proposal 100](https://spec.torproject.org/proposals/100-tor-spec-udp.html) by Marc Liberatore in 2006 suggested a way to "add support for tunneling unreliable datagrams through tor with as few modifications to the protocol as possible."
+This proposal suggested extending the existing TLS+TCP protocol with a new DTLS+UDP link mode.
+The focus of this work was on a potential way to support unreliable traffic, not necessarily on UDP itself or on UDP applications.
+
+In proposal 100, a Tor *stream* is used for one pairing of local and remote address and port, copying the technique used by Tor for TCP.
+This works for some types of UDP applications, but it's broken by common behaviors like ICE connectivity checks, NAT traversal attempts, or using multiple servers via the same socket.
+
+No additional large-message fragmentation protocol is defined, so the MTU in proposal 100 is limited to what fits in a single Tor cell.
+This value is much too small for most applications.
+
+It's possible these UDP protocol details would have been elaborated during design, but the proposal hit a snag elsewhere:
+there was no agreement on a way to avoid facilitating new attacks against anonymity.
+
+#### 2014
+
+In [a thread on the tor-talk mailing list](https://tor-talk.torproject.narkive.com/Weyl6Vrq/using-udpgw-and-tun2socks-over-tor), Nathan Freitas suggested UDP tunneling over Tor using the [*BadVPN*](https://github.com/ambrop72/badvpn) project's `udpgw` protocol.
+
+This protocol was never formally documented and is no longer actively maintained, but it was very broadly similar in scope to a [RFC8656](https://www.rfc-editor.org/rfc/rfc8656) TURN relay operating over a TCP transport.
+
+#### 2018
+
+In 2018, Nick Mathewson and Mike Perry wrote a
+[summary of the side-channel issues with unreliable transports for Tor](https://research.torproject.org/techreports/side-channel-analysis-2018-11-27.pdf).
+
+The focus of this document is on the communication between Tor relays, but there is considerable overlap between the attack space explored here and the potential risks of any application-level UDP support.
+Attacks that are described here, such as drops and injections, may be applied by malicious exits or some types of third parties even in an implementation using only present-day reliable Tor transports.
+
+#### 2020
+
+[Proposal 339](https://spec.torproject.org/proposals/339-udp-over-tor.html) by Nick Mathewson in 2020 introduced a simpler UDP encapsulation design which had similar stream mapping properties as in proposal 100, but with the unreliable transport omitted. Datagrams are tunneled over a new type of Tor stream using a new type of Tor message.
+As a prerequisite, it depends on [proposal 319](https://spec.torproject.org/proposals/319-wide-everything.html) to support messages that may be larger than a cell, extending the MTU to support arbitrarily large UDP datagrams.
+
+In proposal 339 the property of binding a stream both to a local port and to a remote peer is described in UNIX-style terminology as a *connected socket*. This idea is explored below using alternate terminology from [RFC4787](https://www.rfc-editor.org/rfc/rfc4787), *NAT behavior requirements for UDP*.
+The single-peer *connected socket* behavior would be referred to as an *endpoint-dependent mapping* in RFC4787.
+This type works fine for client/server apps but precludes the use of NAT traversal for peer-to-peer transfer.
+
+### Scope
+
+This proposal aims to allow Tor applications and Tor-based VPNs to provide compatibility with applications that require UDP/IP communications.
+
+We don't have a specific list of applications that must be supported, but we are currently aiming for broad support of popular applications while still respecting and referencing all applicable Internet standards documents.
+
+Changes to the structure of the Tor network are out of scope, as are most performance optimizations. We expect to rely on common optimizations to the performance of Tor circuits, rather than looking to make specific changes that optimize for unreliable datagram transmission.
+
+This document will briefly discuss UDP for onion services below.
+It's worth planning for this as a way to evaluate the future design space, but in practice we are not aiming for UDP onion services yet.
+This will require changes to most applications that want to use it, as it implies that any media negotiations will need to understand onion addressing in addition to IPv4 and IPv6.
+
+The allowed subset of UDP traffic is not subject to a single rigid definition.
+There are several options discussed below using the RFC4787 framework.
+
+We require support for DNS clients. Tor currently only supports a limited subset of DNS queries, and it's desirable to support more. This will be analyzed in detail as an application below. DNS is one of very few applications that still rely on fragmented UDP datagrams, though this may not be relevant for us since only servers typically need to control the production of fragments.
+
+We require support for voice/video telecommunications apps. Even without an underlying transport that supports unreliable datagrams, we expect a tunnel to provide a usable level of compatibility. This design space is very similar to the TURN ([RFC8656](https://www.rfc-editor.org/rfc/rfc8656)) specification, already used very widely for compatibility with networks that filter UDP. See the analysis of specific applications below.
+
+We require support for peer-to-peer UDP transfer without additional relaying, in apps that use ICE ([RFC8445](https://www.rfc-editor.org/rfc/rfc8445)) or similar connection establishment techniques.
+Video calls between two Tor users should transit directly between two exit nodes.
+This requires that allocated UDP ports can each communicate with multiple peers:
+*endpoint-independent mapping* as described by RFC4787.
+
+We do not plan to support applications which accept incoming datagrams from previously-unknown peers, for example a DNS server hosted via Tor.
+RFC4787 calls this *endpoint-independent filtering*.
+It's unnecessary for running peer-to-peer apps, and it facilitates an extremely easy [traffic injection](#traffic-injection) attack.
+
+## UDP Traffic Models
+
+To better specify the role of a UDP extension for Tor, this section explores a few frameworks for describing noteworthy subsets of UDP traffic.
+
+### User Datagram Protocol (RFC768)
+
+The "User Interface" suggested by [RFC768](https://www.rfc-editor.org/rfc/rfc768) for the protocol is a rough sketch, suggesting that applications have some way to allocate a local port for receiving datagrams and to transmit datagrams with arbitrary headers.
+
+Despite UDP's simplicity as an application of IP, we do need to be aware of IP features that are typically hidden by TCP's abstraction.
+
+UDP applications typically try to obtain an awareness of the path MTU, using some type of path MTU discovery (PMTUD) algorithm.
+On IPv4, this requires sending packets with the "Don't Fragment" flag set, and measuring when those packets are lost or when ICMP "Fragmentation Needed" replies are seen.
+
+Note that many applications have their own requirements for path MTU. For example, QUIC and common implementations of WebRTC require an MTU no smaller than 1200 bytes, but they can discover larger MTUs when available.
+
+### Socket Layer
+
+In practice the straightforward "User Interface" from RFC768, capable of arbitrary local address, is only available to privileged users.
+
+BSD-style sockets support UDP via `SOCK_DGRAM`.
+UDP is a stateless protocol, but sockets do have state.
+Each socket is bound, either explicitly with `bind()` or automatically, to a source IP and port.
+
+At the API level, a socket is said to be *connected* to a remote `(address, port)` if that address is the default destination.
+A *connected* socket will also filter out incoming packets with source addresses different from this default destination.
+A socket is considered *unconnected* if `connect()` has not been called.
+These sockets have no default destination, and they accept datagrams from any source.
+
+There does not need to be any particular mapping between the lifetime of these application sockets and any higher-level "connection" the application establishes.
+It's better to think of one socket as one allocated local port.
+A typical application may allocate only a single port (one socket) for talking to many peers.
+Every datagram sent or received on the socket may have a different peer address.
+
+### Network Address Translation (NAT)
+
+Much of the real-world complexity in applying UDP comes from defining strategies to detect and overcome the effects of NAT.
+As a result, an intimidating quantity of IETF documentation has been written on NAT behavior and on strategies for NAT traversal.
+
+[RFC4787](https://www.rfc-editor.org/rfc/rfc4787.html) and later [RFC7857](https://www.rfc-editor.org/rfc/rfc7857.html) offer best practices for implementing NAT. These are sometimes referred to as the [BEHAVE-WG](https://datatracker.ietf.org/wg/behave/about/) recommendations, based on the "Behavior Engineering for Hindrance Avoidance" working group behind them.
+
+[RFC6888](https://www.rfc-editor.org/rfc/rfc6888.html) makes additional recommendations for "carrier grade" NAT systems, where small pools of IP addresses are shared among a much larger number of subscribers.
+
+[RFC8445](https://www.rfc-editor.org/rfc/rfc8445.html) describes the Interactive Connectivity Establishment (ICE) protocol, which has become a common and recommended application-level technique for building peer-to-peer applications that work through NAT.
+
+There are multiple fundamental technical issues that NAT presents:
+
+1. NAT must be stateful in order to route replies back to the correct source.
+
+ This directly conflicts with the stateless nature of UDP itself.
+ The NAT's mapping lifetime, determined by a timer, will not necessarily match the lifetime of the application-level connection.
+ This necessitates keep-alive packets in some protocols.
+ Protocols that allow their binding to expire may be open to a NAT rebinding attack, when a different party acquires access to the NAT's port allocation.
+
+2. Applications no longer know an address they can be reached at without outside help.
+
+ Chosen port numbers may or may not be used by the NAT.
+ The effective IP address and port are not knowable without observing from an outside peer.
+
+3. Filtering and mapping approaches both vary, and it's not generally possible to establish a connection without interactive probing.
+
+ This is the reason ICE exists, but it's also a possible anonymity hazard.
+ This risk is explored a bit further below in the context of [interaction with other networks](#interaction-with-other-networks).
+
+We can use the constraints of NAT both to understand application behavior and as an opportunity to model Tor's behavior as a type of NAT.
+In fact, Tor's many exit nodes already share similarity with some types of carrier-grade NAT.
+Applications will need to assume very little about the IP address their outbound UDP originates on, and we can use that to our advantage in implementing UDP for Tor.
+
+This body of work is invaluable for understanding the scope of the problem and for defining common terminology.
+Let's take inspiration from these documents while also keeping in mind that the analogy between Tor and a NAT is imperfect.
+For example, in analyzing Tor as a type of carrier-grade NAT, we may consider the "pooling behavior" defined in RFC4787: the choice of which external addresses map to an internal address.
+Tor by necessity must carefully limit how predictable these mappings can ever be, to preserve its anonymity properties.
+A literal application of RFC6888 would find trouble in REQ-2 and REQ-9, as well as the various per-subscriber limiting requirements.
+
+#### Mapping and Filtering Behaviors
+
+RFC4787 defines a framework for understanding the behavior of NAT by analyzing both its "mapping" and "filtering" behavior separately.
+Mappings are the NAT's unit of state tracking.
+Filters are layered on top of mappings, potentially rejecting incoming datagrams that don't match an already-expected address.
+Both RFC4787 and the demands of peer-to-peer applications make a good case for always using an **Endpoint-Independent Mapping**.
+
+Choice of filtering strategy is left open by the BEHAVE-WG recommendations.
+RFC4787 does not make one single recommendation for all circumstances,
+instead it defines three behavior options with different properties:
+
+- **Endpoint-Independent Filtering** allows incoming datagrams from any peer once a mapping has been established.
+
+ RFC4787 recommends this approach, with the concession that it may not be ideal for all security requirements.
+
+ This technique cannot be safely applied in the context of Tor.
+ It makes [traffic injection](#traffic-injection) attacks possible from any source address, provided you can guess the UDP port number used at an exit.
+ It also makes possible clear-net hosting of UDP servers using an exit node's IP, which may have undesirable abuse properties.
+
+ This permissive filter is also incompatible with our proposed mitigation to [local port exhaustion](#local-port-exhaustion) on exit relays. Even with per-circuit rate limiting, an attacker could trivially overwhelm the local port capacity of all combined UDP-capable Tor exits.
+
+ It is still common for present-day applications to *prefer* endpoint-independent filtering, as it allows incoming connections from peers which cannot use STUN or a similar address fixing protocol.
+ Choosing endpoint-independent filtering would have *some* compatibility benefit, but among modern protocols which use ICE and STUN there would be no improvement.
+ The cost, on the other hand, would be an uncomfortably low-cost traffic injection attack and additional risks toward exit nodes.
+
+- **Address-Dependent Filtering**
+
+ This is a permitted alternative according to RFC4787, in which incoming datagrams are allowed from only IP addresses we have previously sent to, but any port on that IP may be the sender.
+
+ The intended benefits of this approach versus the port-dependent filtering below are unclear, and may no longer be relevant. In theory they would be:
+
+ - To support a class of applications that rely on, for a single local port, multiple remote ports achieving filter acceptance status when only one of those ports has been sent a datagram.
+ We are currently lacking examples of applications in this category.
+ Any application using ICE should be outside this category, as each port would have its own connectivity check datagrams exchanged in each direction.
+
+ - REQ-8 in RFC4787 claims the existence of a scenario in which this approach facilitates ICE connections with a remote peer that disregards REQ-1 (the peer does not use **Endpoint-Independent Mapping**). It is not clear that this claim is still relevant.
+
+ One security hazard of address-dependent and non-port-dependent filtering, identified in RFC4787, is that a peer on a NAT effectively negates the security benefits of this host filtering.
+ In fact, this should raise additional red flags as applied to either Tor or carrier grade NAT.
+ If supporting peer-to-peer applications, it should be commonplace to establish UDP flows between two Tor exit nodes.
+ When this takes place, non-port-dependent filtering would then allow anyone on Tor to connect via those same nodes and perform traffic injection.
+ The resulting security properties really become uncomfortably similar to endpoint-independent filtering.
+
+- **Address- and Port-Dependent Filtering**
+
+ This is the strictest variety of filtering, and it is an allowed alternative under RFC4787.
+ It provides opportunities for increased security and opportunities for reduced compatibility, both of which in practice may depend on other factors.
+
+ For every application we've analyzed so far, port-dependent filtering is not a problem.
+ Usage of ICE will open all required filters during the connectivity check phase.
+
+ This is the only type of filtering that provides any barrier at all between cross-circuit traffic injection when the communicating parties are known.
+
+RFC4787 recommends that filtering style be configurable.
+We would like to implement that advice, but only to the extent it can be done safely and meaningfully in the context of an anonymity system.
+When possible, it would provide additional compatibility at no mandatory cost to allow applications to optionally request **Address-Dependent Filtering**.
+Otherwise, **Address- and Port-Dependent Filtering** is the most appropriate default setting.
+
+### Common Protocols
+
+Applications that want to use UDP are increasingly making use of higher-level protocols to avoid creating bespoke solutions for problems like NAT traversal, connection establishment, and reliable delivery.
+
+This section looks at how these protocols affect Tor's UDP traffic requirements.
+
+#### QUIC
+
+[RFC9000](https://www.rfc-editor.org/rfc/rfc9000.html) defines QUIC, a multiplexed secure point-to-point protocol which supports reliable and unreliable delivery. The most common use is as an optional HTTP replacement, especially among Google services.
+
+QUIC does not normally try to traverse NAT; as an HTTP replacement, the server is expected to have an address reachable without any prior connection setup.
+
+QUIC provides its own flexible connection lifetimes which may outlive individual network links or NAT mappings.
+The intention is to provide transparent roaming as mobile users change networks.
+This automated path discovery opens additional opportunities for malicious traffic, for which the RFC also offers mitigations. See *path validation* in section `8.2`, and the additional mitigations from section `9.3`.
+
+When QUIC is used as an optional upgrade path, we must compare any proposed UDP support against the baseline of a non-upgraded original connection.
+In these cases the goal is not a compatibility enhancement but an avoidance of regression.
+
+In cases where QUIC is used as a primary protocol without TCP fallback, UDP compatibility will be vital.
+These applications are currently niche but we expect they may rise in popularity.
+
+#### WebRTC
+
+WebRTC is a large collection of protocols tuned to work together for media transport and NAT traversal.
+It is increasingly common, both for browser-based telephony and for peer-to-peer data transfer.
+Non-browser apps often implement WebRTC as well, for example using [`libwebrtc`](https://github.com/webrtc-sdk/libwebrtc).
+Even non-WebRTC apps sometimes have significant overlaps in their technology stacks, due to the independent history of ICE, RTP, and SDP adoption.
+
+Of particular importance to us, WebRTC uses the Interactive Connection Establishment (ICE) protocol to establish a bidirectional channel between endpoints that may or may not be behind a NAT with unknown configuration.
+
+Any generalized solution to connection establishment, like ICE, will require sending connectivity test probes. These have an inherent hazard to anonymity: assuming no delays are inserted intentionally, the result is a broadcast of similar traffic across all available network interfaces. This could form a convenient correlation beacon for an attacker attempting to de-anonymize users who use WebRTC over a Tor VPN. This is the risk enumerated below as [*interaction with other networks*](#interaction-with-other-networks).
+
+See
+[RFC8825](https://www.rfc-editor.org/rfc/rfc8825.html) *Overview: Real-Time Protocols for Browser-Based Applications*,
+[RFC8445](https://www.rfc-editor.org/rfc/rfc8445.html) *Interactive Connectivity Establishment (ICE): A Protocol for Network Address Translator (NAT) Traversal*,
+[RFC8838](https://www.rfc-editor.org/rfc/rfc8838.html) *Trickle ICE: Incremental Provisioning of Candidates for the Interactive Connectivity Establishment (ICE) Protocol*,
+[RFC5389](https://www.rfc-editor.org/rfc/rfc5389.html) *Session Traversal Utilities for NAT (STUN)*,
+and others.
+
+### Common Applications
+
+With applications exhibiting such a wide variety of behaviors, how do we know what to expect from a good implementation?
+How do we know which compatibility decisions will be most important to users?
+For this it's helpful to look at specific application behaviors.
+This is a best-effort analysis conducted at a point in time.
+It's not meant to be a definitive reference, think of it as a site survey taken before planning a building.
+
+In alphabetical order:
+
+| Application | Type | Protocol features | Current behavior | Expected outcome |
+| ---------------------- | -------------- | --------------------------------- | ------------------ | -------------------------------------------------- |
+| BitTorrent | File sharing | Many peers per local port | Fails without UDP | Works, new source of nuisance traffic |
+| BigBlueButton | Telecom | WebRTC, TURN, TURN-over-TLS | Works | Slight latency improvement |
+| Discord | Telecom | Proprietary, client/server | Fails without UDP | Starts working |
+| DNS | Infrastructure | Might want IP fragmentation | Limited | Full DNS support, for better and worse |
+| FaceTime | Telecom | WebRTC, TURN, TURN-over-TCP | Works | Slight latency improvement |
+| Google Meet | Telecom | STUN/TURN, TURN-over-TCP | Works | Slight latency improvement |
+| Jitsi (meet.jit.si) | Telecom | WebRTC, TURN-over-TLS, Cloudflare | Fails on Tor | No change, problem does not appear UDP-related |
+| Jitsi (docker-compose) | Telecom | WebRTC, centralized STUN only | Fails without UDP | Starts working |
+| Linphone | Telecom (SIP) | SIP-over-TLS, STUN, TURN | Fails without UDP | Starts working |
+| Signal | Telecom | WebRTC, TURN, TURN-over-TCP | Works | Slight latency improvement |
+| Skype | Telecom | P2P, STUN, TURN-over-TLS | Works | Slight latency improvement |
+| WhatsApp | Telecom | STUN, TURN-over-TCP. Multi server | Works | Slight latency improvement |
+| WiFi Calling | Telecom | IPsec tunnel | Out of scope | Still out of scope |
+| Zoom | Telecom | client/server or P2P, UDP/TCP | Works | Slight latency improvement |
+
+## Overview of Possible Solutions
+
+This section starts to examine different high-level implementation techniques we could adopt.
+Broadly they can be split into *datagram routing* and *tunneling*.
+
+### Datagram Routing
+
+These approaches seek to use a network that can directly route datagrams from place to place. These approaches are the most obviously suitable for implementing UDP, but they also form the widest departure from classic Tor.
+
+#### Intentional UDP Leak
+
+The simplest approach would be to allow UDP traffic to bypass the anonymity layer. This is an unacceptable loss of anonymity in many cases, given that the client's real IP address is made visible to web application providers.
+
+In other cases, this is an acceptable or even preferable approach. For example, VPN users may be more concerned with achieving censorship-resistant network connectivity than hiding personal identifiers from application vendors.
+
+In threat models where application vendors are more trustworthy than the least trustworthy Tor exits, it may be more appropriate to allow direct peer-to-peer connections than to trust Tor exits with unencrypted connection establishment traffic.
+
+#### 3rd Party Implementations
+
+Another option would be to use an unrelated anonymizer system for datagram traffic. It's not clear that a suitable system already exists. I2P provides a technical solution for routing anonymized datagrams, but not a Tor-style infrastructure of exit node operators.
+
+This points to the key weakness of relying on a separate network for UDP: Tor has an especially well-developed community of volunteers running relays. Any UDP solution that is inconvenient for relay operators has little chance of adoption.
+
+#### Future Work on Tor
+
+There may be room for future changes to Tor which allow it to somehow transfer and route datagrams directly, without a separate process of establishing circuits and tunnels.
+If this is practical it may prove to be the simplest and highest performance route to achieving high quality UDP support in the long term.
+A specific design is out of the scope of this document.
+
+It is worth thinking early about how we can facilitate combinations of approaches.
+Even without bringing any new network configurations to Tor, achieving interoperable support for both exit nodes and onion services in a Tor UDP implementation requires some attention to how multiple UDP providers can share protocol responsibilities.
+This may warrant the introduction of some additional routing layer.
+
+### Tunneling
+
+The approaches in this section add a new construct which does not exist in UDP itself: a point-to-point tunnel between clients and some other location at which they establish the capability to send and receive UDP datagrams.
+
+Any tunneling approach requires some way to discover tunnel endpoints.
+For the best usability and adoption this should come as an extension of Tor's existing process for distributing consensus and representing exit policy.
+
+In practice, exit policies for UDP will have limited practical amounts of diversity.
+VPN implementations will need to know ahead of time which tunnel circuits to build, or they will suffer a significant spike in latency for the first outgoing datagram to a new peer.
+Additionally, it's common for UDP port numbers to be randomly assigned.
+This would make highly specific Tor exit policies even less useful and even higher overhead than they are with TCP.
+
+#### TURN Encapsulated in Tor Streams
+
+The scope of this tunnel is quite similar to the existing TURN relays, used commonly by WebRTC applications to implement fallbacks for clients who cannot find a more direct connection path.
+
+TURN is defined by [RFC8656](https://www.rfc-editor.org/rfc/rfc8656) as a set of extensions built on the framework from STUN in [RFC8489](https://www.rfc-editor.org/rfc/rfc8489.html). The capabilities are a good match for our needs, offering clients the ability to encapsulate UDP datagrams within a TCP stream, and to allocate local port mappings on the server.
+
+TURN was designed to be a set of modular and extensible pieces, which might be too distant from Tor's design philosophy of providing single canonical representations. Any adoption of TURN will need to consider the potential for malicious implementations to mark traffic, facilitating de-anonymization attacks.
+
+TURN has a popular embeddable C-language implementation, [coturn](https://github.com/coturn/coturn), which may be suitable for including alongside or inside C tor.
+
+#### Tor Stream Tunnel to an Exit
+
+Most of the discussion on UDP implementation in Tor so far has assumed this approach. Essentially it's the same strategy as TCP exits, but for UDP. When the OP initializes support for UDP, it pre-builds circuits to exits that support required UDP exit policies. These pre-built circuits can then be used as tunnels for UDP datagrams.
+
+Within this overall approach, there are various ways to assign Tor *streams* for the UDP traffic. This will be considered below.
+
+#### Tor Stream Tunnel to a Rendezvous Point
+
+To implement onion services which advertise UDP ports, we can use additional tunnels.
+A new type of tunnel could end at a rendezvous point rather than an exit node.
+Clients could establish the ability to allocate a temporary virtual datagram mailbox at these rendezvous nodes.
+
+This leaves more open questions about how outgoing traffic is routed, and which addressing format would be used for the datagram mailbox.
+The most immediate challenge in UDP rendezvous would then become application support. Protocols like STUN and ICE deal directly with IPv4 and IPv6 formats in order to advertise a reachable address to their peer. Supporting onion services in WebRTC would require protocol extensions and software modifications for STUN, TURN, ICE, and SDP at minimum.
+
+UDP-like rendezvous extensions would have limited meaning unless they form part of a long-term strategy to forward datagrams in some new way for enhanced performance or compatibility. Otherwise, application authors might as well stick with Tor's existing reliable circuit rendezvous functionality.
+
+## Specific Designs Using Tor Streams
+
+Let's look more closely at Tor *streams*, the multiplexing layer right below circuits.
+
+Streams have an opaque 16-bit identifier, allocated from the onion proxy (OP) endpoint.
+Stream lifetimes are subject to some slight ambiguity still in the Tor spec.
+They are always allocated from the OP end but may be destroyed asynchronously by either circuit endpoint.
+
+We have an opportunity to use this additional existing multiplexing layer to serve a useful function in the new protocol, or we can opt to interact with streams as little as possible in order to keep the protocol features more orthogonal.
+
+### One Stream per Tunnel (VPN)
+
+It's possible to transport arbitrary UDP traffic using only a single Tor stream ID within the circuit. In this case, both the source and destination address would need to be represented somehow within an added per-datagram header.
+
+The most common examples of this approach might be TUN/TAP forwarding over SSH, or any VPN that uses a TCP transport.
+
+This design might be preferable if 16-bit stream IDs are found to be in short supply, but otherwise we would expect some benefit from using multiple streams IDs and therefore allowing a shorter per-datagram header.
+
+### One Stream per Local port (TURN)
+
+With the standard TURN relay protocol, implemented over a TCP transport,
+the "allocation" of a relayed port can be performed once per tuple of `(protocol, source IP, source port, destination IP, destination port)`.
+Put another way, TURN does not amplify the number of local ports available.
+An application that wishes to use two relayed ports will need two separate TCP connections, or in this context two separate Tor stream IDs.
+
+As with the SSH example above, TURN could be implemented without any new Tor message types.
+TURN adds a 4-byte "channel data" header to normal datagrams, to facilitate message framing and peer identification.
+
+We could choose to implement protocol support for bundling TURN relay functionality with a normal Tor exit node.
+In that case, we would want a single new Tor message type:
+
+- `CONNECT_TURN`
+
+ - Establish a stream as a connection to the exit relay's built-in (or configured) TURN server.
+
+ This would logically be a TURN-over-TCP connection, though it does not need to correspond to any real TCP socket if the TURN server is implemented in-process with tor.
+
+Note that RFC8656 requires authentication before data can be relayed, which is a good default best practice for the internet perhaps but is the opposite of what Tor is trying to do. We would either deviate from the specification to relax this auth requirement, or provide a way for clients to discover credentials: perhaps by fixing them ahead of time or by including them in the relay descriptor.
+
+If authentication is used, we must consider the protocol's privacy limitations.
+STUN/TURN usernames are conveyed in plaintext unless an additional TLS layer is also in use.
+For anonymity, use a randomly generated username.
+The [`draft-uberti-behave-turn-rest-00`](https://datatracker.ietf.org/doc/html/draft-uberti-behave-turn-rest-00) document describes a method for generating time-limited credentials, as implemented through `--use-auth-secret` in `coturn`.
+Username timestamps should be randomized, to avoid exposing the precise local system clock.
+
+### One Stream per Local Port (Proposal 339)
+
+One stream **per socket** was the approach suggested in [Proposal 339](https://spec.torproject.org/proposals/339-udp-over-tor.html) by Nick Mathewson in 2020, defining a per-local-port approach using slightly different terminology than TURN.
+
+Proposal 339 chooses a different UDP subset to support, but otherwise the main technical distinction vs. TURN's per-local-port stream comes down to the framing layer.
+TURN defines an additional header to be used within a TCP-like stream, whereas proposal 339 avoids the two redundant length bytes by defining new Tor message types: `CONNECT_UDP`, `CONNECTED_UDP`, and `DATAGRAM`.
+
+Similar to TURN, each stream's lifetime would match the lifetime of a local port allocation.
+Unlike TURN, there would be a single peer `(remote address, remote port)` allowed per `local port`.
+This matches the usage of BSD-style sockets on which `connect()` has completed, but it's incompatible with many of the applications analyzed.
+Multiple peers are typically needed for a variety of reasons, like connectivity checks or multi-region servers.
+
+This approach would be simplest to implement and specify, especially in the existing C tor implementation.
+It also unfortunately has very limited compatibility, and no clear path toward incremental upgrades if we wish to improve compatibility later.
+
+A simple one-to-one mapping between streams and sockets would preclude the optimizations necessary to address [local port exhaustion](#local-port-exhaustion) risks below. Solutions under this design are possible, but only by decoupling logical protocol-level sockets from the ultimate implementation-level sockets and reintroducing much of the complexity that we attempted to avoid by choosing this design.
+
+### One Stream per Local Port (NAT Mapping)
+
+We could improve the compatibility of Proposal 339 while retaining its very low per-datagram overhead by updating it to align with terminology and requirements from [RFC4787](https://www.rfc-editor.org/rfc/rfc4787) where practical.
+
+This approach would use each stream to represent one **endpoint-independent mapping**, for use as a local UDP port in communication with multiple peers.
+
+A mapping would always be allocated from the OP (client) side.
+It could explicitly specify a filtering style, if we wish to allow applications to request non-port-dependent filtering for compatibility.
+Each datagram within the stream would still need to be tagged with a peer address/port in some way.
+
+This approach would involve a single new type of stream, and two new messages that pertain to these *mapping* streams:
+
+- `NEW_UDP_MAPPING`
+
+ - Always client-to-exit.
+ - Creates a new mapping, with a specified stream ID.
+ - Succeeds instantly; no reply is expected, early data is ok.
+ - Externally-visible local port number is arbitrary, and must be determined through interaction with other endpoints.
+ - Might contain an IP "don't fragment" flag.
+ - Might contain a requested filtering mode.
+ - Lifetime is until circuit teardown or `END` message.
+
+- `UDP_MAPPING_DATAGRAM`
+
+ - Conveys one datagram on a stream previously defined by `NEW_UDP_MAPPING`.
+ - Includes peer address (IPv4/IPv6) as well as datagram content.
+
+This updated approach is more compatible than Proposal 339 but it's not yet as efficient as TURN.
+Peers are almost always repeated over the course of a tunnel's lifetime, so the header space needed for addressing could be compressed by keeping some persistent information about peers as well as mappings.
+
+### One Stream per Flow
+
+One stream **per flow** has also been suggested.
+Specifically, Mike Perry brought this up during our conversations about UDP recently and we spent some time analyzing it from a RFC4787 perspective.
+This approach has some interesting properties but also hidden complexity that may ultimately make other options more easily applicable.
+
+This would assign a stream ID to the tuple consisting of at least `(local port, remote address, remote port)`. Additional flags may be included for features like transmit and receive filtering, IPv4/v6 choice, and IP *Don't Fragment*.
+
+This has advantages in keeping the datagram cells simple, with no additional IDs beyond the existing circuit ID.
+It may also have advantages in DoS-prevention and in privacy analysis.
+
+Stream lifetimes, in this case, would not have any specific meaning other than the lifetime of the ID itself.
+The bundle of flows associated with one local port would still all be limited to the lifetime of a Tor circuit, by scoping the local port identifier to be contained within the lifetime of its circuit.
+
+It would be necessary to allocate a new stream ID any time a new `(local port, remote address, remote port)` tuple is seen.
+This would most commonly happen as a result of a first datagram sent to a new peer, coinciding with the establishment of a NAT-style mapping and the possible allocation of a socket on the exit.
+
+A less common case needs to be considered too: what if the parameter tuple first occurs on the exit side?
+We don't yet have a way to allocate stream IDs from either end of a circuit.
+This would need to be considered.
+One simple solution would be to statically partition the stream ID space into a portion that can be independently allocated by each side.
+
+When is this exit-originated circuit ID allocation potentially needed?
+It is clearly needed when using **address-dependent filtering**.
+An incoming datagram from a previously-unseen peer port is expected to be deliverable, and the exit would need to allocate an ID for it.
+
+Even with the stricter **address and port-dependent filtering** clients may still be exposed to exit-originated circuit IDs if there are mismatches in the lifetime of the filter and the stream.
+
+This approach thus requires some attention to either correctly allocating stream IDs on both sides of the circuit, or choosing a filtering strategy and filter/mapping lifetime that does not ever leave stream IDs undefined when expecting incoming datagrams.
+
+### Hybrid Mapping and Flow Approach
+
+We can extend the approach above with an optimization that addresses the undesirable space overhead from redundant address headers.
+This uses two new types of stream, in order to have streams **per mapping** and **per flow** at the same time.
+
+The per-mapping stream remains the sole interface for managing the lifetime of a mapped UDP port. Mappings are created explicitly by the client. As an optimization, within the lifetime of a mapping there may exist some number of *flows*, each assigned their own ID.
+
+This tries to combine the strengths of both approaches, using the lifetime of one stream to define a mapping and to carry otherwise-unbundled traffic while also allowing additional streams to bundle datagrams that would otherwise have repetitive headers.
+It avoids the space overhead of a purely **per mapping** approach and avoids the ID allocation and lifetime complexity introduced with **per flow**.
+
+This approach takes some inspiration from TURN, where commonly used peers will be defined as a "channel" with an especially short header.
+Incoming datagrams with no channel can always be represented in the long form, so TURN never has to allocate channels unexpectedly.
+
+The implementation here could be a strict superset of the **per mapping** implementation, adding new commands for flows while retaining existing behavior for mappings. There would be a total of four new message types:
+
+- `NEW_UDP_MAPPING`
+
+ - Same as above.
+
+- `UDP_MAPPING_DATAGRAM`
+
+ - Same as above.
+
+- `NEW_UDP_FLOW`
+
+ - Allocates a stream ID as a *flow*, given the ID to be allocated and the ID of its parent *mapping* stream.
+ - Includes a peer address (IPv4/IPv6).
+ - The *flow* has a lifetime strictly bounded by the outer *mapping*. It is deleted by an explicit `END` or when the mapping is de-allocated for any reason.
+
+- `UDP_FLOW_DATAGRAM`
+
+ - Datagram contents only, without address.
+ - Only appears on *flow* streams.
+
+We must consider the traffic marking opportunities provided when allowing an exit to represent one incoming datagram as either a *flow* or *mapping* datagram.
+
+It's possible this traffic injection potential is not worse than the baseline amount of injection potential than every UDP protocol presents. See more on [risks](#risks) below. For this hybrid stream approach specifically, there's a limited mitigation available which allows exits only a bounded amount of leaked information per UDP peer:
+
+Ideally exits may not choose to send a `UDP_MAPPING_DATAGRAM` when they could have sent a `UDP_FLOW_DATAGRAM`.
+Sometimes it is genuinely unclear though: an exit may have received this datagram in-between processing `NEW_UDP_MAPPING` and `NEW_UDP_FLOW`.
+A partial mitigation would terminate circuits which send a `UDP_MAPPING_DATAGRAM` for a peer that has already been referenced in a `UDP_FLOW_DATAGRAM`.
+The exit is thereby given a one-way gate allowing it to switch from using *mapping* datagrams to using *flow* datagrams at some point, but not to switch back and forth repeatedly.
+
+Mappings that do not request port-specific filtering may always get unexpected `UDP_MAPPING_DATAGRAM`s. Mappings that do use port-specific filtering could make a flow for their only expected peers, then expect to never see `UDP_MAPPING_DATAGRAM`.
+
+`NEW_UDP_MAPPING` could have an option requiring that only `UDP_FLOW_DATAGRAM` is to be used, never `UDP_MAPPING_DATAGRAM`.
+This would remove the potential for ambiguity, but costs in compatibility as it's no longer possible to implement non-port-specific filtering.
+
+## Risks
+
+Any proposed UDP support involves significant risks to user privacy and software maintainability.
+This section elaborates some of these risks, so they can be compared against expected benefits.
+
+### Behavior Regressions
+
+In some applications it is possible that Tor's implementation of a UDP compatibility layer will cause a regression in the ultimate level of performance or security.
+
+Performance regressions can occur accidentally due to bugs or compatibility glitches.
+They may also occur for more fundamental reasons of protocol layering.
+For example, the redundant error correction layers when tunneling QUIC over TCP.
+These performance degradations are expected to be minor, but there's some unavoidable risk.
+
+The risk of severe performance or compatibility regressions may be mitigated by giving users a way to toggle UDP support per-application.
+
+Privacy and security regressions have more severe consequences and they can be much harder to detect.
+There are straightforward downgrades, like WebRTC apps that give up TURN-over-TLS for plaintext TURN-over-UDP.
+More subtly, the act of centralizing connection establishment traffic in Tor exit nodes can make users an easier target for other attacks.
+
+### Bandwidth Usage
+
+We should expect an increase in overall exit bandwidth requirements due to peer-to-peer file sharing applications.
+
+Current users attempting to use BitTorrent over Tor are hampered by the lack of UDP compatibility. Interoperability with common file-sharing peers would make Tor more appealing to users with a large and sustained appetite for anonymized bandwidth.
+
+### Local Port Exhaustion
+
+Exit routers will have a limited number of local UDP ports. In the most constrained scenario, an exit may have a single IP with 16384 or fewer ephemeral ports available. These ports could each be allocated by one client for an unbounded amount of exclusive use.
+
+In order to enforce high levels of isolation between different subsequent users of the same local UDP port, we may wish to enforce an extended delay between allocations during which nobody may own the port. Effective isolation requires this timer duration to be greater than any timer encountered on a peer or a NAT. In RFC4787's recommendations a NAT's mapping timer must be longer than 2 minutes. Our timer should ideally be *much* longer than 2 minutes.
+
+An attacker who allocates ports for only this minimum duration of 2 minutes would need to send 136.5 requests per second to achieve sustained use of all available ports. With multiple simultaneous clients this could easily be done while bypassing per-circuit rate limiting.
+
+The expanded definition of "Port overlapping" from [RFC7857 section 3](https://datatracker.ietf.org/doc/html/rfc7857#section-3), may form at least a partial mitigation:
+
+> This document clarifies that this port overlapping behavior may be extended to connections originating from different internal source IP addresses and ports as long as their destinations are different.
+
+This gives us an opportunity for a vast reduction in the number of required ports and file descriptors.
+Exit routers can automatically allocate local ports for use with a specific peer when that peer is first added to the client's filter.
+
+Due to the general requirements of NAT traversal, UDP applications with any NAT support will always need to communicate with a relatively well known server prior to any attempts at peer-to-peer communication.
+This early peer could be an entire application server, or it could be a STUN endpoint.
+In any case, the identity of this first peer gives us a hint about the set of all potential peers.
+
+Within the exit router, each local port will track a separate mapping owner for each peer.
+When processing that first outgoing datagram, the exit may choose any local port where the specific peer is not taken.
+Subsequent outgoing datagrams on the same port may communicate with a different peer, and there's no guarantee all these future peers will be claimed successfully.
+
+When is this a problem?
+An un-claimable peer represents a case where the exact `(local ip, local port, remote ip, remote port)` tuple is in use already for a different mapping in some other Tor stream.
+For example, imagine two clients are running different types of telecom apps which are nevertheless inter-compatible and capable of both calling the same peers.
+Alternatively, consider the same app but with servers in several regions.
+The two apps will begin by communicating with different sets of peers, due to different application servers and different bundled STUN servers.
+This is our hint that it's likely appropriate to overlap their local port allocations.
+At this point, both of these applications may be successfully sharing a `(local ip, local port)` tuple on the exit.
+As soon as one of these apps calls a peer with some `(remote ip, remote port)`, the other app will be unable to contact that specific peer.
+
+The lack of connectivity may seem like a niche inconvenience, and perhaps that is the extent of the issue.
+It seems likely this heuristic could result in a problematic information disclosure under some circumstances, and it deserves closer study.
+
+### Application Fingerprinting
+
+UDP applications present an increased surface of plaintext data that may be available for user fingerprinting by malicious exits.
+
+Exposed values can include short-lived identifiers like STUN usernames.
+Typically it will also be possible to determine what type of software is in use, and maybe what version of that software.
+
+Short-lived identifiers are still quite valuable to attackers, because they may reliably track application sessions across changes to the Tor exit. If longer-lived identifiers exist for any reason, that of course provides a powerful tool for call metadata gathering.
+
+### Peer-to-Peer Metadata Collection
+
+One of our goals was to achieve the compatibility and perhaps performance benefits of allowing "peer-to-peer" (in our case really exit-to-exit) UDP connections.
+We expect this to enable the subset of applications that lack a fallback path which loops traffic through an app-provided server.
+
+This goal may be at odds with our privacy requirements. At minimum, a pool of malicious exit nodes could passively collect metadata about these connections as a noisy proxy for call metadata.
+
+Any additional signals like [application fingerprints](#application-fingerprinting) or [injected](#traffic-injection) markers may be used to enrich this metadata graph, possibly tracking users across sessions or across changes to the tunnel endpoint.
+
+### Interaction with Other Networks
+
+Any application using an ICE-like interactive connection establishment scheme will easily leak information across network boundaries if it ever has access to multiple networks at once.
+
+In applications that are not privacy conscious this is often desired behavior. For example, a video call to someone in your household may typically transit directly over Wifi, decreasing service costs and improving latency. This implies that some type of local identifier accompanies the call signaling info, allowing the devices to find each other's LAN address.
+
+Privacy-preserving solutions for this use case are still an active area of standardization effort. The [IETF draft on mDNS ICE candidates](https://www.ietf.org/archive/id/draft-ietf-mmusic-mdns-ice-candidates-02.html) proposes one way to accomplish this by generating short-lived unique IDs which are only useful to peers with physical access to the same mDNS services.
+
+Without special attention to privacy, the typical implementation is to share all available IP addresses and to initiate simultaneous connectivity tests using any IP pairs which cannot be trivially discarded. This applies to ICE as specified, but also to any proprietary protocol which operates in the same design space as ICE. This has multiple issues in a privacy-conscious environment: The IP address disclosures alone can be fatal to anonymity under common threat models. Even if meaningful IP addresses are not disclosed, the timing correlation from connectivity checks can provide confirmation beacons that alert an attacker to some connection between a LAN user and a Tor exit.
+
+### Traffic Injection
+
+Some forms of UDP support would have obvious and severe traffic injection vulnerabilities. For example, the very permissive *endpoint-independent filtering* strategy would allow any host on the internet to send datagrams in bulk to all available local ports on a Tor exit in order to map that traffic's effect on any guards they control.
+
+Any vehicle for malicious parties to mark traffic can be abused to de-anonymize users. Even if there is a more restrictive filtering policy, UDP's lack of sequence numbers make header spoofing attacks considerably easier than in TCP. Third parties capable of routing datagrams to an exit with a spoofed source address could bypass filtering when the communicating parties are known or can be guessed. For example, a malicious superuser at an ISP without egress filtering could send packets with the source IPs set to various common DNS servers and application STUN/TURN servers. If a specific application is being targeted, only the exit node and local port numbers need to be guessed by brute force.
+
+In case of malicious exit relays, whole datagrams can be inserted and dropped, and datagrams may be padded with additional data, both without any specific knowledge of the application protocol. With specific protocol insights, a malicious relay may make arbitrary edits to plaintext data.
+
+Of particular interest is the plaintext STUN, TURN, and ICE traffic used by most WebRTC apps. These applications rely on higher-level protocols (SRTP, DTLS) to provide end-to-end encryption and authentication. A compromise at the connection establishment layer would not violate application-level end-to-end security requirements, making it outside the threat model of WebRTC but very much still a concern for Tor.
+
+These attacks are not fully unique to the proposed UDP support, but UDP may increase exposure. In cases where the application already has a fallback using TURN-over-TLS, the proposal is a clear regression over previous behaviors. Even when comparing plaintext to plaintext, there may be a serious downside to centralizing all connection establishment traffic through a small number of exit IPs. Depending on your threat model, it could very well be more private to allow the UDP traffic to bypass Tor entirely.
+
+### Malicious Outgoing Traffic
+
+We can expect UDP compatibility in Tor will give malicious actors additional opportunities to transmit unwanted traffic.
+
+In general, exit abuse will need to be filtered administratively somehow.
+This is not unique to UDP support, and exit relay administration typically involves some type of filtering response tooling that falls outside the scope of Tor itself.
+
+Exit administrators may choose to modify their exit policy, or to silently drop problematic traffic.
+Silent dropping is discouraged in most cases, as Tor prioritizes the accuracy of an exit's advertised policy.
+Detailed exit policies have a significant space overhead in the overall Tor consensus document, but it's still seen as a valuable resource for clients during circuit establishment.
+
+Exit policy filtering may be less useful in UDP than with TCP due to the inconvenient latency spike when establishing a new [tunnel](#tunneling).
+Applications that are sensitive to RTT measurements made during connection establishment may fail entirely when the tunnel cannot be pre-built.
+
+This section lists a few potential hazards, but the real-world impact may be hard to predict owing to a diversity of custom UDP protocols implemented across the internet.
+
+- Amplification attacks against arbitrary targets
+
+ These are possible only in limited circumstances where the protocol allows an arbitrary reply address, like SIP.
+The peer is often at fault for having an overly permissive configuration.
+Nevertheless, any of these *easy* amplification targets can be exploited from Tor with little consequence, creating a nuisance for the ultimate target and for exit operators.
+
+- Amplification attacks against an exit relay
+
+ An amplification peer which doesn't allow arbitrary destinations can still be used to attack the exit relay itself or other users of that relay.
+This is essentially the same attack that is possible against any NAT the attacker is behind.
+
+- Malicious fragmented traffic
+
+ If we allow sending large UDP datagrams over IPv4 without the *Don't Fragment* flag set, we allow attackers to generate fragmented IP datagrams.
+This is not itself a problem, but it has historically been a common source of inconsistencies in firewall behavior.
+
+- Excessive sends to an uninterested peer
+
+ Whereas TCP mandates a successful handshake, UDP will happily send unlimited amounts of traffic to a peer that has never responded.
+To prevent denial of service attacks we have an opportunity and perhaps a responsibility to define our supported subset of UDP to include true bidirectional traffic but exclude continued sends to peers who do not respond.
+
+ See also [RFC7675](https://www.rfc-editor.org/rfc/rfc7675.html) and STUN's concept of "Send consent".
+
+- Excessive number of peers
+
+ We may want to place conservative limits on the maximum number of peers per mapping or per circuit, in order to make bulk scanning of UDP port space less convenient.
+
+ The limit would need to be on peers, not stream IDs as we presently do for TCP.
+In this proposal stream IDs are not necessarily meaningful except as a representational choice made by clients.
+
+## Next Steps
+
+At this point we have perhaps too many possibilities for how to proceed. We could integrate UDP quite closely with Tor itself or not at all.
+
+Choosing a route forward is both a risk/benefit tradeoff and a guess about the future of Tor. If we expect that some future version of Tor will provide its own datagram transport, we should plot a course aiming in that direction. If not, we might be better served by keeping compatibility features confined to separate protocol layers when that's practical.
+
+### Requiring a Long-Term Datagram Plan
+
+If we choose to add new long-term maintenance burdens to our protocol stack, we should ensure they serve our long-term goals for UDP adoption as well as these shorter-term application compatibility goals.
+
+This work so far has been done with the assumption that end-to-end datagram support is out of scope. If we intend to proceed down any path which encodes a datagram-specific protocol into Tor proper, we should prioritize additional protocol research and standardization work.
+
+### Alternatively, Modular Application-Level Support
+
+Without a clear way to implement fully generic UDP support, we're left with application-level goals.
+Different applications may have contrasting needs, and we can only achieve high levels of both compatibility and privacy by delegating some choices to app authors or per-app VPN settings.
+
+This points to an alternative in which UDP support is excluded from Tor as much as possible while still supporting application requirements.
+For example, this could motivate the [TURN Encapsulated in Tor Streams](#turn-encapsulated-in-tor-streams) design, or even simpler designs where TURN servers are maintained independently from the Tor exit infrastructure.
+
+The next prototyping step we would need at this stage is a version of `onionmasq` extended to support NAT-style UDP mappings using TURN allocations provided through TURN-over-TCP or TURN-over-TLS.
+This can be a platform for further application compatibility experiments.
+It could potentially become a low-cost minimal implementation of UDP application compatibility, serving to assess which remaining user needs are still unmet.
diff --git a/proposals/349-command-state-validation.md b/proposals/349-command-state-validation.md
new file mode 100644
index 0000000..47598e6
--- /dev/null
+++ b/proposals/349-command-state-validation.md
@@ -0,0 +1,666 @@
+```
+Filename: 349-command-state-validation.md
+Title: Client-Side Command Acceptance Validation
+Author: Mike Perry
+Created: 2023-08-17
+Status: Draft
+```
+
+# Introduction
+
+The ability of relays to inject end-to-end relay cells that are ignored by
+clients allows malicious relays to create a covert channel to verify that they
+are present in multiple positions of a path. This covert channel allows a
+Guard to deanonymize 100% of its traffic, or just all the traffic of a
+particular client IP address.
+
+This attack was first documented in [DROPMARK]. Proposal 344 describes the
+severity of this attack, and how this kind of end-to-end covert channel leads
+to full deanonymization, in a reliable way, in practice. (Recall that dropped
+cell attacks are most severe when an adversary can inject arbitrary end-to-end
+data patterns at times when the circuit is known to be idle, before it is used
+for traffic; injection at this point enables path bias attacks which can
+ensure that only malicious Guard+Exit relays are present in all circuits used
+by a particular target client IP address. For further details, see Proposal
+344.)
+
+This proposal is targeting arti-client, not C-Tor. This proposal is specific
+to client-side checks of relay cells and relay messages. Its primary change to
+behavior is the definition of state machines that enforce what relay message
+commands are acceptable on a given circuit, and when.
+
+By applying and enforcing these state machine rules, we prevent the end-to-end
+transmission of arbitrary amounts of data, and ensure that predictable periods
+of the protocol are happening as expected, and not filled with side channel
+packet patterns.
+
+
+
+## Overview of dropped cell types
+
+Dropped cells are cells that a relay can inject that end up ignored and
+discarded by a Tor client.
+
+These include:
+ 1. Unparsable cells
+ 2. invalid relay commands
+ 3. Unrecognized cells (ie: wrong source hop, or decrypt failures)
+ 4. unsupported (or consensus-disabled) relay commands or extensions
+ 5. out-of-context relay commands
+ 6. duplicate relay commands
+ 7. relay commands that hit any error codepaths
+ 8. relay commands for an invalid or already-closed stream ID
+ 9. semantically void relay cells (incl relay data len == 0, or PING)
+ 10. onion descriptor-appended junk
+
+Items 1-4 and 8 are handled by the existing relay command parsers in arti. In
+these cases, arti closes the circuit already.
+
+> XXX: Arti's relay parser is lazy; see https://gitlab.torproject.org/tpo/core/arti/-/merge_requests/1978
+> Does this mean that individual components need to properly propagate error
+> information in order for circuits to get closed, when a command does not
+> parse?
+
+The state machines of this proposal handle 5-7 in a rigorous way. (In many
+cases of out-of-context relay cells, arti already closes the circuit;
+our goal here is to centralize this validation so that we can ensure that
+it is not possible for any relay commands to omit checks or allow unbounded
+activity.)
+
+> XXX: Does arti allow extra onion-descriptor junk to be appended after the
+> descriptor signature? C-Tor does...
+
+
+# Architectural Patterns and Behavior
+
+Ideally, the handling of invalid protocol behavior should be centralized,
+so that validation can happen in one easy-to-audit place, rather than spread
+across the codebase (as it currently is with C-Tor).
+
+For some narrow cases of invalid protocol activity, this is trivial. The relay
+command acceptance is centralized in arti, which allows arti to immediately
+reject unknown or disabled relay commands. This kind of validation is
+necessary, but not sufficient, in order to prevent dropped cell vectors.
+
+Things quickly get complicated when handling parsable relay cells sent during
+an inappropriate time, or other activity such as duplicate relay commands,
+semantically void cells, or commands that would hit an error condition, or
+lazy parsing failure, deep in the code and be silently accepted without
+closing the circuit.
+
+To handle such cases, we propose adding a relay command message state machine
+pattern. Each relay protocol, when it becomes active on a circuit, must
+register a state machine that handles validating its messages.
+
+Because multiple relay protocols can be active at a time, multiple validation
+state machines can be attached to a circuit. This also allows protocols to
+create their own validation without needing to modify the entire validation
+process. Relay messages that are not accepted by any active protocol
+validation handler MUST result in circuit close.
+
+
+## Architectural Patterns
+
+In order to handle these cases, we rely on some architectural patterns:
+ 1. No relay message command may be sent to the client unless it is unless
+ explicitly allowed by the specification, advertised as supported, and
+ negotiated on a particular channel or circuit. (Prop#346)
+ 2. Any relay commands or extension fields not successfully negotiated
+ on a circuit are invalid. This includes cells from intermediate hops,
+ which must also negotiate their use (example: padding machine
+ negotiation to middles).
+ 3. By following the above principles, state machines can be developed
+ that govern when a relay command is acceptable. This covers the
+ majority of protocol activity. See Section 3.
+ 4. For some commands, additional checks must be performed by using
+ context of the protocol itself.
+
+The following relay commands require additional module state to enforce
+limitations, beyond what is known by a state machine, for #4:
+ - RELAY_COMMAND_SENDME
+ - Requires checking that the auth digest hash is accurate
+ - RELAY_COMMAND_XOFF and RELAY_COMMAND_XON
+ - Context and rate limiting is stream-dependent
+ - Packing enforcement via prop#340 is context-dependent
+ - RELAY_COMMAND_CONFLUX_SWITCH
+ - Packing enforcement via prop#340 is context-dependent
+ - RELAY_COMMAND_DROP:
+ - This can only be accepted from a hop if there is a padding
+ machine at that hop.
+ - RELAY_COMMAND_INTRODUCE2
+ - Requires inspecting replay cache (however, circuits should not get
+ closed because replays can come from the client)
+
+## Behavior
+
+When an invalid relay cell or relay message is encountered, the corresponding
+circuit should be immediately closed.
+
+Initially, this can be accomplished by sending a DESTROY cell to the Guard
+relay.
+
+Additionally, when closing circuits in this way, clients must take care not to
+allow cases of adversarially-induced infinite circuit creation in non-onion
+service protocols that are not protected by Vanguards/Vanguards-lite, by
+limiting the number of retries they perform. (One such example of this is a
+malicious conflux exit that repeatedly kills only one leg by injecting dropped
+cells to close the circuit.)
+
+While we also specify some cases where the channel to the Guard should be
+closed, this is not necessary in the general case.
+
+> XXX: I can't think of any issues severe enough to actually warrant the
+> following, but Florentin pointed it out as a possibility: A malicious Guard
+> may withhold the DESTROY, and still allow full identifier transmission before
+> the circuit is closed. While this does not directly allow full deanonymization
+> because the client won't actually use the circuit, it may still be enough to
+> make the vector useful for other attacks. For completeness against this
+> vector, we may want to consider sending a new RELAY_DESTROY command to the
+> middle node, such that it has responsibility for tearing down a circuit by
+> sending its own DESTROYS in both directions, and then have the client send its
+> own DESTROY if the client does not get a DESTROY from the Guard.
+> >>> See torspec#220: https://gitlab.torproject.org/tpo/core/torspec/-/issues/220
+
+
+
+# State machine descriptions
+
+These state machines apply only at the client. (There is no information leak
+from extra cells in the protocol on the relay side, so we will not be specifying
+relay-side enforcement, or implementing it for C-Tor.)
+
+There are multiple state machines, describing particular circuit purposes
+and/or components of the Tor relay protocol.
+
+Each state machine has a "Trigger", and a "Message Scope". The "Trigger" is
+the condition, relay command, or action that causes the state machine to get
+added to a circuit's command state validator set. The Message Scope is where the state
+machine applies: to specific a hop number, stream ID, or both.
+
+A circuit can have multiple state machines attached at one time.
+ * If no state machine accepts a relay command, then the circuit MUST be
+ closed.
+ * When we say "receive X" we mean "receive a _valid_ cell of
+ type X". If the cell is invalid, we MUST kill the circuit
+
+## Relay message handlers
+
+The state machines process enveloped relay message commands. Ie, with respect
+to prop#340, they operate on the message bodies, with associated stream ID.
+
+With respect to Proposal #340, the calls to state machine validation would go
+after converting cells to messages, but before parsing the message body
+itself, to still minimize exposure of the parser attack surfaces.
+
+> XXX: Again, some validation will require early parsing, not lazy parsing
+
+There are multiple relay message handlers that can be registered with each
+circuit ID, for a specific hop on that circuit ID, depending on the protocols
+that are in use on that circuit with that hop, as well as the streams to that
+hop.
+
+Each handler has a Message Scope, that acts as a filter such that only relay
+command messages from this scope are processed by that handler.
+
+If a message is not accepted by any active handler, the circuit MUST be
+closed.
+
+
+### Base Handler
+
+Purpose: This handler validates commands for circuit construction and
+circuit-level SENDME activity.
+
+Trigger: Creation of a circuit; ntor handhshake success for a hop
+
+Message Scope: The circuit ID and hop number must match for this handler to
+apply. (Because of leaky pipes, each hop of the circuit has a base handler
+added when that hop completes an ntor handshake and is added to the circuit.)
+
+```text
+START:
+ Upon sending EXTEND:
+ Enter EXTEND_SENT.
+
+ Receive SENDME:
+ Ensure expected auth digest matches; close circuit otherwise
+ No transition.
+
+EXTEND_SENT:
+ Receiving EXTENDED:
+ Enter START.
+
+ Receive SENDME:
+ Ensure expected auth digest matches; close circuit otherwise
+ No transition.
+```
+
+### Client Introducing Handler
+
+Purpose: Circuits used by clients to connect to a service introduction point
+have this handler attached.
+
+Trigger: Usage of a circuit for client introduction
+
+Message Scope: Circuit ID and hop number must match
+
+```text
+CLIENT_INTRO_START:
+ Upon sending INTRODUCE1:
+ Enter CLIENT_INTRO_WAIT
+
+CLIENT_INTRO_WAIT
+ Receieve INTRODUCE_ACK:
+ Accept
+ Transition to CLIENT_INTRO_END
+
+CLIENT_INTRO_END:
+ No transitions possible
+ - XXX: Enforce that no new handlers can be added? We may still have padding
+ handlers though.
+```
+
+
+### Service Introduce Handler
+
+Purpose: Service-side onion service introduction circuits have this handler
+attached.
+
+Trigger: Onion service establishing an introduction point circuit
+
+Message Scope: Circuit ID and hop number must match
+
+```text
+SERVICE_INTRO_START:
+ Upon sending ESTABLISH_INTRO:
+ Enter SERVICE_INTRO_ESTABLISH
+
+SERVICE_INTRO_ESTABLISH:
+ Receiving INTRO_ESTABLISHED:
+ Enter SERVICE_INTRO_ESTABLISHED
+
+SERVICE_INTRO_ESTABLISHED:
+ Receiving INTRODUCE2
+ Accept
+```
+
+
+### Client Rendezvous Handler
+
+Purpose: Circuits used by clients to build a rendezvous point have this handler
+attached.
+
+Trigger: Client rendezvous initiation
+
+Message Scope: Circuit ID and hop number must match
+
+```text
+CLIENT_REND_START:
+ Upon Sending RENDEZVOUS1:
+ Enter CLIENT_REND_WAIT
+
+CLIENT_REND_WAIT:
+ Receive RENDEZVOUS2:
+ Enter CLIENT_REND_ESTABLISHED
+
+CLIENT_REND_ESTABLISHED:
+ Remain in this state; launch TCP, UDP, or Conflux handlers for streams
+```
+
+
+### Service Rendezvous Handler
+
+Purpose: Circuits used by services to connect to a rendezvous point have this
+handler attached.
+
+Trigger: Incoming introduce cell/service rend initiation
+
+Message Scope: Circuit ID and hop number must match
+
+```text
+SERVICE_REND_START:
+ Upon sending ESTABLISH_RENDEZVOUS:
+ Enter SERVICE_REND_WAIT
+
+SERVICE_REND_WAIT:
+ Receive RENDEZVOUS_ESTABLISHED:
+ Enter SERVICE_REND_ESTABLISHED
+
+SERVICE_REND_ESTABLISHED:
+ Remain in this state; launch TCP, UDP, or Conflux handlers for streams
+```
+
+
+### CircPad Handler
+
+Purpose: Circuit-level padding is negotiated with a particular hop in the
+circuit; when it is negotiated, we need to allow padding cells from that hop.
+
+Trigger: Negotiation of a circuit padding machine
+
+Message Scope: Circuit ID and hop must match; padding machine must be active
+
+```text
+PADDING_START:
+ Upon sending PADDING_NEGOTIATE:
+ Enter PADDING_NEGOTIATING
+
+PADDING_NEGOTIATING:
+ Receiving PADDING_NEGOTIATED:
+ Enter PADDING_ACTIVE
+
+PADDING_ACTIVE:
+ Receiving DROP:
+ Accept (if from correct hop)
+ - XXX: We could perform more sophisticated rate limiting accounting here
+ too?
+```
+
+### Resolve Stream Handler
+
+Purpose: This handler is created on circuits when a resolve happens.
+
+Trigger: RESOLVE message
+
+Message Scope: Circuit ID, stream ID, and hop number must all match
+
+```text
+RESOLVE_START:
+ Send a RESOLVE message:
+ Enter RESOLVE_SENT
+
+RESOLVE_SENT:
+ Receive a RESOLVED or an END:
+ Enter RESOLVE_START.
+```
+
+
+### TCP Stream handler
+
+Purpose: This handler is created when the client creates a new stream ID, using either
+BEGIN or BEGIN_DIR.
+
+Trigger: New AP or DirConn stream
+
+Message Scope: Circuit ID, stream ID, and hop number must all match; stream ID
+must be open or half-open (half-open is END_SENT).
+
+```text
+TCP_STREAM_START:
+ Send a BEGIN or BEGIN_DIR message:
+ Enter BEGIN_SENT.
+
+BEGIN_SENT:
+ Receive an END:
+ Enter TCP_STREAM_START.
+ Receive a CONNECTED:
+ Enter STREAM_OPEN.
+
+STREAM_OPEN:
+ Receive DATA:
+ Verify length is > 0
+ XXX: Handle [HSDIRINFLATION] here?
+ Process.
+
+ Receive XOFF:
+ Enter STREAM_XOFF
+
+ Send END:
+ Enter END_SENT.
+
+ Receive END:
+ Enter TCP_STREAM_START
+
+STREAM_XOFF:
+ Receive DATA:
+ Verify length is > 0
+ XXX: Handle [HSDIRINFLATION] here?
+ Process.
+
+ Send END:
+ Enter END_SENT.
+
+ Receive XON:
+ Enter STREAM_XON
+
+ Receive END:
+ Enter TCP_STREAM_START
+
+STREAM_XON:
+ Receive DATA:
+ Verify length is > 0
+ XXX: Handle [HSDIRINFLATION] here?
+ Process.
+
+ Receive XOFF:
+ If prop#340 is enabled, verify packed with SENDME
+ Enter STREAM_XOFF
+
+ Receive XON:
+ If prop#340 is enabled, verify packed with SENDME
+ Verify rate has changed
+
+ Send END:
+ Enter END_SENT.
+
+ Receive END:
+ Enter TCP_STREAM_START
+
+END_SENT:
+ Same as STREAM_OPEN, except do not actually deliver data.
+ Only remain in this state for one RTT_max, or until END_ACK.
+```
+
+
+### Conflux Handler
+
+Purpose: Circuits that are a part of a conflux set have a conflux handler, associated
+with the last hop.
+
+Trigger: Creation of a conflux set
+
+Message Scope: Circuit ID and hop number must match
+ - XXX: Linked circuits must accept stream ids from either circuit for other
+ handlers :/
+
+```text
+CONFLUX_START: (all conflux leg circuits start here)
+ Upon sending CONFLUX_LINK:
+ Enter CONFLUX_LINKING
+
+CONFLUX_LINKING:
+ Receiving CONFLUX_LINKED:
+ Send CONFLUX_LINKED_ACK
+ Enter CONFLUX_LINKED
+
+CONFLUX_LINKED:
+ Receiving CONFLUX_SWITCH:
+ If prop#340 is negotiated, ensure packed with a DATA cell
+```
+
+
+### UDP Stream Handler
+
+Purpose: Circuits that are using prop#339
+
+Trigger: UDP stream creation
+
+Message Scope: Circuit ID, hop number, and stream-id must match
+
+```text
+UDP_STREAM_START:
+ If no other udp streams used on circuit:
+ Send CONNECT_UDP for any stream, enter UDP_CONNECTING
+ else:
+ Immediately enter UDP_CONNECTING
+ (CONNECTED_UDP MAY arrive without a CONNECT_UDP, after the first UDP
+ stream on a circuit is established)
+
+UDP_CONNECTING:
+ Upon receipt of CONNECTED_UDP, enter UDP_CONNECTED
+
+UDP_CONNECTED:
+ Receive DATAGRAM:
+ Verify length > 0
+ Verify Prop#344 NAT rules are obeyed, including srcport and stream limits
+ Process.
+
+ Send END:
+ Enter UDP_END_SENT
+
+UDP_END_SENT:
+ Same as UDP_CONNECTED, except do not actually deliver data.
+ Only remain in this state for one RTT_max, or until END_ACK,
+ then transition to UDP_STREAM_START.
+```
+
+
+# HSDIR Inflation { #HSDIRINFLATION }
+
+XXX: This can be folded into the state machines and/or rend-spec.. The state
+machines should actually be able to handle this, once they are ready for it.
+
+One of the most common questions about dropped cells is "what about data cells
+with a 1 byte payload?". As Prop#344 makes clear, this is not a dropped cell
+attack, but is instead an instance of an Active Traffic Manipulation Covert
+Channel, described in Section 1.3.2. The lower severity of active traffic
+manipulation is due to the fact that it cannot be used to deanonymize 100% of
+a target client's circuits, where as the combination of path bias and
+pre-usage dropped cells can.
+
+However, there is one case where one can construct a potent attack from this
+Active Traffic Manipulation: by making use of onion service circuits being
+built on demand by an application. Further, because the onion service
+handshake is uniquely fingerprintable (see Section 1.2.1 of Prop#344), it is
+possible to use this vector in this specific case to encode an identifier in
+the timing and traffic patterns of the onion service descriptor download,
+similar to how the CMU attack operated, and use both the onion service
+fingerprint and descriptor traffic pattern to transmit the fact that a
+particular onion service was visited, to the Guard or possibly even a local
+network observer.
+
+A normal hidden service descriptor occupies only ~10 cells (with a hard max of
+30KB, or ~60 cells). This is not enough to reliably encode the full address of
+the onion service in a timing-based covert channel.
+
+However, there are two ways to cause this descriptor download to transmit
+enough data to encode such a covert channel, and replicate the CMU attack
+using timing information of this data.
+
+First, the actual descriptor payload can be spread across many DATA cells that
+are filled only partially with data (which does not happen if the HSDIR is
+honest and well-behaved, because it always has the full descriptor on hand).
+
+Second, in C-tor, additional junk can be appended at the end of a onion service
+descriptor document that does not count against the 30KB maximum, which the
+client will happily download and then ignore.
+
+Neither of these things are necessary to preserve, and neither can happen in
+normal operation. They can either be addressed directly by checks on
+HSDIR-based RELAY_COMMAND_DATA lengths and descriptor parsing, or by simply
+enforcing that circuits used to fetch service descriptors can *only* receive
+as many bytes as the maximum descriptor size, before being closed.
+
+XXX: Consider RELAY_COMMAND_END_ACK also..
+ - https://gitlab.torproject.org/tpo/core/torspec/-/issues/196
+
+XXX: Tickets to grovel through for other stuff:
+https://gitlab.torproject.org/tpo/core/torspec/-/issues/38
+https://gitlab.torproject.org/tpo/core/torspec/-/issues/39
+https://gitlab.torproject.org/tpo/core/arti/-/issues/525
+
+
+# Command Allowlist enumeration { #CTORALLOWLIST }
+
+XXX: We are planning to remove this section after we finish the state
+machines; keeping it for reference until then for cross-checking.
+
+Formerly, in C-Tor, we took the approach of performing a series of checks for
+each message command, ad-hoc. Here's those rules, for spot-checking that the
+above state machines cover them.
+
+All relay commands are rejected by clients and serviced unless a rule says
+they are OK.
+
+Here's a list of those rules, by relay command:
+
+ - RELAY_COMMAND_DATA 2
+ - This command MUST only arrive for valid open or half-open stream ID
+ - This command MUST have data length > 0
+ - On HSDIR circuits, ONLY ONE command is allowed to have a non-full
+ payload (the last command). See Section 4.
+
+ - RELAY_COMMAND_END 3
+ - This command MUST only arrive ONCE for each valid open or half-open
+ stream ID
+
+ - RELAY_COMMAND_CONNECTED 4
+ - This command MUST ONLY be accepted ONCE by clients if they sent a BEGIN
+ or BEGIN_DIR
+ - The stream ID MUST match the stream ID from BEGIN (or BEGIN_DIR)
+
+ - RELAY_COMMAND_DROP 10
+ - This command is accepted by clients from any hop that they
+ have negotiated an active circuit padding machine with
+
+ - RELAY_COMMAND_CONFLUX_LINKED 20
+ - Ensure that a LINK cell was sent to the hop that sent this
+ - Ensure that no previous LINKED cell has arrived on this circuit
+
+ - RELAY_COMMAND_CONFLUX_SWITCH 22
+ - Ensure that conflux is enabled and linked
+ - If Prop#340 is in use, this cell MUST be packed with a valid
+ multiplexed RELAY_COMMAND_DATA cell.
+
+ - RELAY_COMMAND_INTRODUCE2 35
+ - Services MUST check:
+ - The intro is for a valid service identity and auth
+ - The command has a valid sub-credential
+ - The command is not a replay (possibly not close circuit?)
+
+ - RELAY_COMMAND_RENDEZVOUS2 37
+ - This command MUST ONLY arrive ONCE in response to a sent REND1 cell,
+ on the appropriate circuit
+ - The ntor handshake must succeed with MAC validation
+
+ - RELAY_COMMAND_INTRO_ESTABLISHED 38
+ - Services MUST check:
+ - This cell MUST ONLY come ONCE in response to
+ RELAY_COMMAND_ESTABLISH_INTRO, for the appropriate service identity
+
+ - RELAY_COMMAND_RENDEZVOUS_ESTABLISHED 39
+ - This command MUST ONLY be accepted ONCE in response to
+ RELAY_COMMAND_ESTABLISH_RENDEZVOUS
+
+ - RELAY_COMMAND_INTRODUCE_ACK 40
+ - This command MUST ONLY be accepted ONCE by clients, in response to
+ RELAY_COMMAND_INTRODUCE1
+
+ - RELAY_COMMAND_PADDING_NEGOTIATED 42
+ - This command MUST ONLY be accepted by clients in response to
+ PADDING_NEGOTIATE
+
+ - RELAY_COMMAND_XOFF 43
+ - Ensure that congestion control is enabled and negotiated
+ - Ensure that the stream id is either opened or half-open
+ - Ensure that the stream id is in "XON" state
+
+ - RELAY_COMMAND_XON 44
+ - Ensure that congestion control is enabled and negotiated
+ - Ensure that the stream id is either opened or half-open
+ - Enforce always packing this to a SENDME with Prop#340?
+
+ - RELAY_COMMAND_CONNECTED_UDP
+ - The stream id in this command MUST match that from
+ RELAY_COMMAND_CONNECT_UDP
+ - This command is only accepted once per UDP stream id
+
+ - RELAY_COMMAND_DATAGRAM
+ - This command MUST only arrive for valid open or half-open stream ID
+ - This command MUST have data length > 0
+
+
+
+References:
+
+[DROPMARK]: https://petsymposium.org/2018/files/papers/issue2/popets-2018-0011.pdf
diff --git a/proposals/BY_INDEX.md b/proposals/BY_INDEX.md
index 0e9aa1d..96e52b0 100644
--- a/proposals/BY_INDEX.md
+++ b/proposals/BY_INDEX.md
@@ -11,250 +11,260 @@ of these proposals are implemented; some are works in progress; and some
will never be implemented.
Below are a list of proposals sorted by their proposal number. See
-[README.md](/proposals/README.md) for a list of proposals sorted by status.
+[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 [META]
-* [`099-misc.txt`](/proposals/099-misc.txt): Miscellaneous proposals [META]
-* [`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 [ACCEPTED]
-* [`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 [NEEDS-REVISION]
-* [`292-mesh-vanguards.txt`](/proposals/292-mesh-vanguards.txt): Mesh-based vanguards [ACCEPTED]
-* [`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 [OPEN]
-* [`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 [OPEN]
-* [`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 [OPEN]
-* [`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 [OPEN]
-* [`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 [OPEN]
-* [`325-packed-relay-cells.md`](/proposals/325-packed-relay-cells.md): Packed relay cells: saving space on small commands [OPEN]
-* [`326-tor-relay-well-known-uri-rfc8615.md`](/proposals/326-tor-relay-well-known-uri-rfc8615.md): The "tor-relay" Well-Known Resource Identifier [OPEN]
-* [`327-pow-over-intro.txt`](/proposals/327-pow-over-intro.txt): A First Take at PoW Over Introduction Circuits [DRAFT]
-* [`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 [DRAFT]
-* [`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 [FINISHED]
-* [`333-vanguards-lite.md`](/proposals/333-vanguards-lite.md): Vanguards lite [FINISHED]
-* [`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 [ACCEPTED]
-* [`337-simpler-guard-usability.md`](/proposals/337-simpler-guard-usability.md): A simpler way to decide, "Is this guard usable?" [ACCEPTED]
-* [`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 [DRAFT]
+* [`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\]
+* [`348-udp-app-support.md`](/proposals/348-udp-app-support.md): UDP Application Support in Tor \[OPEN\]
+* [`349-command-state-validation.md`](/proposals/349-command-state-validation.md): Client-Side Command Acceptance Validation \[DRAFT\]
diff --git a/proposals/BY_INDEX_template.md b/proposals/BY_INDEX_template.md
index d18dc60..2c8d425 100644
--- a/proposals/BY_INDEX_template.md
+++ b/proposals/BY_INDEX_template.md
@@ -11,6 +11,6 @@ of these proposals are implemented; some are works in progress; and some
will never be implemented.
Below are a list of proposals sorted by their proposal number. See
-[README.md](/proposals/README.md) for a list of proposals sorted by status.
+[BY_STATUS.md](/proposals/BY_STATUS.md) for a list of proposals sorted by status.
{BY_INDEX}
diff --git a/proposals/BY_STATUS.md b/proposals/BY_STATUS.md
new file mode 100644
index 0000000..84345ac
--- /dev/null
+++ b/proposals/BY_STATUS.md
@@ -0,0 +1,371 @@
+# Tor proposals by status
+
+<!-- DO NOT EDIT THIS FILE -->
+
+<!-- If you want to make changes here, make sure to edit the -->
+<!-- README_template.md file. The README.md file is generated by the -->
+<!-- reindex.py script. -->
+
+Here we have a set of proposals for changes to the Tor protocol. Some
+of these proposals are implemented; some are works in progress; and some
+will never be implemented.
+
+Below are a list of proposals sorted by status. See
+[BY_INDEX.md](/proposals/BY_INDEX.md) for a list of proposals sorted by number.
+
+# Active proposals by status
+
+## OPEN proposals: under discussion
+
+These are proposals that we think are likely to be complete, and ripe
+for discussion.
+
+* [`239-consensus-hash-chaining.txt`](/proposals/239-consensus-hash-chaining.txt): Consensus Hash Chaining
+* [`240-auth-cert-revocation.txt`](/proposals/240-auth-cert-revocation.txt): Early signing key revocation for directory authorities
+* [`265-load-balancing-with-overhead.txt`](/proposals/265-load-balancing-with-overhead.txt): Load Balancing with Overhead Parameters
+* [`267-tor-consensus-transparency.txt`](/proposals/267-tor-consensus-transparency.txt): Tor Consensus Transparency
+* [`277-detect-id-sharing.txt`](/proposals/277-detect-id-sharing.txt): Detect multiple relay instances running with same ID
+* [`287-reduce-lifetime.txt`](/proposals/287-reduce-lifetime.txt): Reduce circuit lifetime without overloading the network
+* [`295-relay-crypto-with-adl.txt`](/proposals/295-relay-crypto-with-adl.txt): Using ADL for relay cryptography (solving the crypto-tagging attack)
+* [`303-protover-removal-policy.txt`](/proposals/303-protover-removal-policy.txt): When and how to remove support for protocol versions
+* [`306-ipv6-happy-eyeballs.txt`](/proposals/306-ipv6-happy-eyeballs.txt): A Tor Implementation of IPv6 Happy Eyeballs
+* [`309-optimistic-socks-in-tor.txt`](/proposals/309-optimistic-socks-in-tor.txt): Optimistic SOCKS Data
+* [`322-dirport-linkspec.md`](/proposals/322-dirport-linkspec.md): Extending link specifiers to include the directory port
+* [`323-walking-onions-full.md`](/proposals/323-walking-onions-full.md): Specification for Walking Onions
+* [`326-tor-relay-well-known-uri-rfc8615.md`](/proposals/326-tor-relay-well-known-uri-rfc8615.md): The "tor-relay" Well-Known Resource Identifier
+* [`330-authority-contact.md`](/proposals/330-authority-contact.md): Modernizing authority contact entries
+* [`340-packed-and-fragmented.md`](/proposals/340-packed-and-fragmented.md): Packed and fragmented relay messages
+* [`341-better-oos.md`](/proposals/341-better-oos.md): A better algorithm for out-of-sockets eviction
+* [`343-rend-caa.txt`](/proposals/343-rend-caa.txt): CAA Extensions for the Tor Rendezvous Specification
+* [`344-protocol-info-leaks.txt`](/proposals/344-protocol-info-leaks.txt): Prioritizing Protocol Information Leaks in Tor
+* [`346-protovers-again.md`](/proposals/346-protovers-again.md): Clarifying and extending the use of protocol versioning
+* [`347-domain-separation.md`](/proposals/347-domain-separation.md): Domain separation for certificate signing keys
+* [`348-udp-app-support.md`](/proposals/348-udp-app-support.md): UDP Application Support in Tor
+
+
+## ACCEPTED proposals: slated for implementation
+
+These are the proposals that we agree we'd like to implement. They
+might or might not have a specific timeframe planned for their
+implementation.
+
+* [`282-remove-named-from-consensus.txt`](/proposals/282-remove-named-from-consensus.txt): Remove "Named" and "Unnamed" handling from consensus voting
+* [`285-utf-8.txt`](/proposals/285-utf-8.txt): Directory documents should be standardized as UTF-8
+* [`311-relay-ipv6-reachability.txt`](/proposals/311-relay-ipv6-reachability.txt): Tor Relay IPv6 Reachability
+* [`312-relay-auto-ipv6-addr.txt`](/proposals/312-relay-auto-ipv6-addr.txt): Tor Relay Automatic IPv6 Address Discovery
+* [`313-relay-ipv6-stats.txt`](/proposals/313-relay-ipv6-stats.txt): Tor Relay IPv6 Statistics
+* [`321-happy-families.md`](/proposals/321-happy-families.md): Better performance and usability for the MyFamily option (v2)
+* [`338-netinfo-y2038.md`](/proposals/338-netinfo-y2038.md): Use an 8-byte timestamp in NETINFO cells
+* [`339-udp-over-tor.md`](/proposals/339-udp-over-tor.md): UDP traffic over Tor
+
+
+## FINISHED proposals: implemented, specs not merged
+
+These proposals are implemented in some version of Tor; the proposals
+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
+* [`329-traffic-splitting.txt`](/proposals/329-traffic-splitting.txt): Overcoming Tor's Bottlenecks with Traffic Splitting
+
+
+## META proposals: about the proposal process
+
+These proposals describe ongoing policies and changes to the proposals
+process.
+
+* [`000-index.txt`](/proposals/000-index.txt): Index of Tor Proposals
+* [`001-process.txt`](/proposals/001-process.txt): The Tor Proposal Process
+* [`202-improved-relay-crypto.txt`](/proposals/202-improved-relay-crypto.txt): Two improved relay encryption protocols for Tor cells
+* [`257-hiding-authorities.txt`](/proposals/257-hiding-authorities.txt): Refactoring authorities and making them more isolated from the net
+* [`290-deprecate-consensus-methods.txt`](/proposals/290-deprecate-consensus-methods.txt): Continuously update consensus methods
+
+
+## INFORMATIONAL proposals: not actually specifications
+
+These proposals describe a process or project, but aren't actually
+proposed changes in the Tor specifications.
+
+* [`159-exit-scanning.txt`](/proposals/159-exit-scanning.txt): Exit Scanning
+* [`300-walking-onions.txt`](/proposals/300-walking-onions.txt): Walking Onions: Scaling and Saving Bandwidth
+
+
+# Preliminary proposals
+
+## DRAFT proposals: incomplete works
+
+These proposals have been marked as a draft by their author or the editors,
+indicating that they aren't yet in a complete form. They're still open for
+discussion.
+
+* [`294-tls-1.3.txt`](/proposals/294-tls-1.3.txt): TLS 1.3 Migration
+* [`316-flashflow.md`](/proposals/316-flashflow.md): FlashFlow: A Secure Speed Test for Tor (Parent Proposal)
+* [`331-res-tokens-for-anti-dos.md`](/proposals/331-res-tokens-for-anti-dos.md): Res tokens: Anonymous Credentials for Onion Service DoS Resilience
+* [`342-decouple-hs-interval.md`](/proposals/342-decouple-hs-interval.md): Decoupling hs_interval and SRV lifetime
+* [`349-command-state-validation.md`](/proposals/349-command-state-validation.md): Client-Side Command Acceptance Validation
+
+
+## NEEDS-REVISION proposals: ideas that we can't implement as-is
+
+These proposals have some promise, but we can't implement them without
+certain changes.
+
+* [`212-using-old-consensus.txt`](/proposals/212-using-old-consensus.txt): Increase Acceptable Consensus Age
+* [`219-expanded-dns.txt`](/proposals/219-expanded-dns.txt): Support for full DNS and DNSSEC resolution in Tor
+* [`245-tap-out.txt`](/proposals/245-tap-out.txt): Deprecating and removing the TAP circuit extension protocol
+* [`248-removing-rsa-identities.txt`](/proposals/248-removing-rsa-identities.txt): Remove all RSA identity keys
+* [`269-hybrid-handshake.txt`](/proposals/269-hybrid-handshake.txt): Transitionally secure hybrid handshakes
+* [`279-naming-layer-api.txt`](/proposals/279-naming-layer-api.txt): A Name System API for Tor Onion Services
+* [`317-secure-dns-name-resolution.txt`](/proposals/317-secure-dns-name-resolution.txt): Improve security aspects of DNS name resolution
+
+
+## NEEDS-RESEARCH proposals: blocking on research
+
+These proposals are interesting ideas, but there's more research that would
+need to happen before we can know whether to implement them or not, or to
+fill in certain details.
+
+(There are no proposals in this category)
+
+
+# Inactive proposals by status
+
+## CLOSED proposals: implemented and specified
+
+These proposals have been implemented in some version of Tor, and the
+changes from the proposals have been merged into the specifications as
+necessary.
+
+* [`101-dir-voting.txt`](/proposals/101-dir-voting.txt): Voting on the Tor Directory System
+* [`102-drop-opt.txt`](/proposals/102-drop-opt.txt): Dropping "opt" from the directory format
+* [`103-multilevel-keys.txt`](/proposals/103-multilevel-keys.txt): Splitting identity key from regularly used signing key
+* [`104-short-descriptors.txt`](/proposals/104-short-descriptors.txt): Long and Short Router Descriptors
+* [`105-handshake-revision.txt`](/proposals/105-handshake-revision.txt): Version negotiation for the Tor protocol
+* [`106-less-tls-constraint.txt`](/proposals/106-less-tls-constraint.txt): Checking fewer things during TLS handshakes
+* [`107-uptime-sanity-checking.txt`](/proposals/107-uptime-sanity-checking.txt): Uptime Sanity Checking
+* [`108-mtbf-based-stability.txt`](/proposals/108-mtbf-based-stability.txt): Base "Stable" Flag on Mean Time Between Failures
+* [`109-no-sharing-ips.txt`](/proposals/109-no-sharing-ips.txt): No more than one server per IP address
+* [`110-avoid-infinite-circuits.txt`](/proposals/110-avoid-infinite-circuits.txt): Avoiding infinite length circuits
+* [`111-local-traffic-priority.txt`](/proposals/111-local-traffic-priority.txt): Prioritizing local traffic over relayed traffic
+* [`114-distributed-storage.txt`](/proposals/114-distributed-storage.txt): Distributed Storage for Tor Hidden Service Descriptors
+* [`117-ipv6-exits.txt`](/proposals/117-ipv6-exits.txt): IPv6 exits
+* [`119-controlport-auth.txt`](/proposals/119-controlport-auth.txt): New PROTOCOLINFO command for controllers
+* [`121-hidden-service-authentication.txt`](/proposals/121-hidden-service-authentication.txt): Hidden Service Authentication
+* [`122-unnamed-flag.txt`](/proposals/122-unnamed-flag.txt): Network status entries need a new Unnamed flag
+* [`123-autonaming.txt`](/proposals/123-autonaming.txt): Naming authorities automatically create bindings
+* [`125-bridges.txt`](/proposals/125-bridges.txt): Behavior for bridge users, bridge relays, and bridge authorities
+* [`126-geoip-reporting.txt`](/proposals/126-geoip-reporting.txt): Getting GeoIP data and publishing usage summaries
+* [`129-reject-plaintext-ports.txt`](/proposals/129-reject-plaintext-ports.txt): Block Insecure Protocols by Default
+* [`130-v2-conn-protocol.txt`](/proposals/130-v2-conn-protocol.txt): Version 2 Tor connection protocol
+* [`135-private-tor-networks.txt`](/proposals/135-private-tor-networks.txt): Simplify Configuration of Private Tor Networks
+* [`136-legacy-keys.txt`](/proposals/136-legacy-keys.txt): Mass authority migration with legacy keys
+* [`137-bootstrap-phases.txt`](/proposals/137-bootstrap-phases.txt): Keep controllers informed as Tor bootstraps
+* [`138-remove-down-routers-from-consensus.txt`](/proposals/138-remove-down-routers-from-consensus.txt): Remove routers that are not Running from consensus documents
+* [`139-conditional-consensus-download.txt`](/proposals/139-conditional-consensus-download.txt): Download consensus documents only when it will be trusted
+* [`140-consensus-diffs.txt`](/proposals/140-consensus-diffs.txt): Provide diffs between consensuses
+* [`148-uniform-client-end-reason.txt`](/proposals/148-uniform-client-end-reason.txt): Stream end reasons from the client side should be uniform
+* [`150-exclude-exit-nodes.txt`](/proposals/150-exclude-exit-nodes.txt): Exclude Exit Nodes from a circuit
+* [`151-path-selection-improvements.txt`](/proposals/151-path-selection-improvements.txt): Improving Tor Path Selection
+* [`152-single-hop-circuits.txt`](/proposals/152-single-hop-circuits.txt): Optionally allow exit from single-hop circuits
+* [`155-four-hidden-service-improvements.txt`](/proposals/155-four-hidden-service-improvements.txt): Four Improvements of Hidden Service Performance
+* [`157-specific-cert-download.txt`](/proposals/157-specific-cert-download.txt): Make certificate downloads specific
+* [`158-microdescriptors.txt`](/proposals/158-microdescriptors.txt): Clients download consensus + microdescriptors
+* [`160-bandwidth-offset.txt`](/proposals/160-bandwidth-offset.txt): Authorities vote for bandwidth offsets in consensus
+* [`161-computing-bandwidth-adjustments.txt`](/proposals/161-computing-bandwidth-adjustments.txt): Computing Bandwidth Adjustments
+* [`162-consensus-flavors.txt`](/proposals/162-consensus-flavors.txt): Publish the consensus in multiple flavors
+* [`166-statistics-extra-info-docs.txt`](/proposals/166-statistics-extra-info-docs.txt): Including Network Statistics in Extra-Info Documents
+* [`167-params-in-consensus.txt`](/proposals/167-params-in-consensus.txt): Vote on network parameters in consensus
+* [`171-separate-streams.txt`](/proposals/171-separate-streams.txt): Separate streams across circuits by connection metadata
+* [`174-optimistic-data-server.txt`](/proposals/174-optimistic-data-server.txt): Optimistic Data for Tor: Server Side
+* [`176-revising-handshake.txt`](/proposals/176-revising-handshake.txt): Proposed version-3 link handshake for Tor
+* [`178-param-voting.txt`](/proposals/178-param-voting.txt): Require majority of authorities to vote for consensus parameters
+* [`179-TLS-cert-and-parameter-normalization.txt`](/proposals/179-TLS-cert-and-parameter-normalization.txt): TLS certificate and parameter normalization
+* [`180-pluggable-transport.txt`](/proposals/180-pluggable-transport.txt): Pluggable transports for circumvention
+* [`181-optimistic-data-client.txt`](/proposals/181-optimistic-data-client.txt): Optimistic Data for Tor: Client Side
+* [`183-refillintervals.txt`](/proposals/183-refillintervals.txt): Refill Intervals
+* [`184-v3-link-protocol.txt`](/proposals/184-v3-link-protocol.txt): Miscellaneous changes for a v3 Tor link protocol
+* [`186-multiple-orports.txt`](/proposals/186-multiple-orports.txt): Multiple addresses for one OR or bridge
+* [`187-allow-client-auth.txt`](/proposals/187-allow-client-auth.txt): Reserve a cell type to allow client authorization
+* [`193-safe-cookie-authentication.txt`](/proposals/193-safe-cookie-authentication.txt): Safe cookie authentication for Tor controllers
+* [`196-transport-control-ports.txt`](/proposals/196-transport-control-ports.txt): Extended ORPort and TransportControlPort
+* [`198-restore-clienthello-semantics.txt`](/proposals/198-restore-clienthello-semantics.txt): Restore semantics of TLS ClientHello
+* [`200-new-create-and-extend-cells.txt`](/proposals/200-new-create-and-extend-cells.txt): Adding new, extensible CREATE, EXTEND, and related cells
+* [`204-hidserv-subdomains.txt`](/proposals/204-hidserv-subdomains.txt): Subdomain support for Hidden Service addresses
+* [`205-local-dnscache.txt`](/proposals/205-local-dnscache.txt): Remove global client-side DNS caching
+* [`206-directory-sources.txt`](/proposals/206-directory-sources.txt): Preconfigured directory sources for bootstrapping
+* [`207-directory-guards.txt`](/proposals/207-directory-guards.txt): Directory guards
+* [`208-ipv6-exits-redux.txt`](/proposals/208-ipv6-exits-redux.txt): IPv6 Exits Redux
+* [`214-longer-circids.txt`](/proposals/214-longer-circids.txt): Allow 4-byte circuit IDs in a new link protocol
+* [`215-update-min-consensus-ver.txt`](/proposals/215-update-min-consensus-ver.txt): Let the minimum consensus method change with time
+* [`216-ntor-handshake.txt`](/proposals/216-ntor-handshake.txt): Improved circuit-creation key exchange
+* [`217-ext-orport-auth.txt`](/proposals/217-ext-orport-auth.txt): Tor Extended ORPort Authentication
+* [`218-usage-controller-events.txt`](/proposals/218-usage-controller-events.txt): Controller events to better understand connection/circuit usage
+* [`220-ecc-id-keys.txt`](/proposals/220-ecc-id-keys.txt): Migrate server identity keys to Ed25519
+* [`221-stop-using-create-fast.txt`](/proposals/221-stop-using-create-fast.txt): Stop using CREATE_FAST
+* [`222-remove-client-timestamps.txt`](/proposals/222-remove-client-timestamps.txt): Stop sending client timestamps
+* [`224-rend-spec-ng.txt`](/proposals/224-rend-spec-ng.txt): Next-Generation Hidden Services in Tor
+* [`227-vote-on-package-fingerprints.txt`](/proposals/227-vote-on-package-fingerprints.txt): Include package fingerprints in consensus documents
+* [`228-cross-certification-onionkeys.txt`](/proposals/228-cross-certification-onionkeys.txt): Cross-certifying identity keys with onion keys
+* [`232-pluggable-transports-through-proxy.txt`](/proposals/232-pluggable-transports-through-proxy.txt): Pluggable Transport through SOCKS proxy
+* [`235-kill-named-flag.txt`](/proposals/235-kill-named-flag.txt): Stop assigning (and eventually supporting) the Named flag
+* [`236-single-guard-node.txt`](/proposals/236-single-guard-node.txt): The move to a single guard node
+* [`237-directory-servers-for-all.txt`](/proposals/237-directory-servers-for-all.txt): All relays are directory servers
+* [`238-hs-relay-stats.txt`](/proposals/238-hs-relay-stats.txt): Better hidden service stats from Tor relays
+* [`243-hsdir-flag-need-stable.txt`](/proposals/243-hsdir-flag-need-stable.txt): Give out HSDir flag only to relays with Stable flag
+* [`244-use-rfc5705-for-tls-binding.txt`](/proposals/244-use-rfc5705-for-tls-binding.txt): Use RFC5705 Key Exporting in our AUTHENTICATE calls
+* [`250-commit-reveal-consensus.txt`](/proposals/250-commit-reveal-consensus.txt): Random Number Generation During Tor Voting
+* [`251-netflow-padding.txt`](/proposals/251-netflow-padding.txt): Padding for netflow record resolution reduction
+* [`254-padding-negotiation.txt`](/proposals/254-padding-negotiation.txt): Padding Negotiation
+* [`264-subprotocol-versions.txt`](/proposals/264-subprotocol-versions.txt): Putting version numbers on the Tor subprotocols
+* [`271-another-guard-selection.txt`](/proposals/271-another-guard-selection.txt): Another algorithm for guard selection
+* [`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
+* [`274-rotate-onion-keys-less.txt`](/proposals/274-rotate-onion-keys-less.txt): Rotate onion keys less frequently
+* [`275-md-published-time-is-silly.txt`](/proposals/275-md-published-time-is-silly.txt): Stop including meaningful "published" time in microdescriptor consensus
+* [`278-directory-compression-scheme-negotiation.txt`](/proposals/278-directory-compression-scheme-negotiation.txt): Directory Compression Scheme Negotiation
+* [`283-ipv6-in-micro-consensus.txt`](/proposals/283-ipv6-in-micro-consensus.txt): Move IPv6 ORPorts from microdescriptors to the microdesc consensus
+* [`284-hsv3-control-port.txt`](/proposals/284-hsv3-control-port.txt): Hidden Service v3 Control Port
+* [`289-authenticated-sendmes.txt`](/proposals/289-authenticated-sendmes.txt): Authenticating sendme cells to mitigate bandwidth attacks
+* [`292-mesh-vanguards.txt`](/proposals/292-mesh-vanguards.txt): Mesh-based vanguards
+* [`293-know-when-to-publish.txt`](/proposals/293-know-when-to-publish.txt): Other ways for relays to know when to publish
+* [`296-expose-bandwidth-files.txt`](/proposals/296-expose-bandwidth-files.txt): Have Directory Authorities expose raw bandwidth list files
+* [`297-safer-protover-shutdowns.txt`](/proposals/297-safer-protover-shutdowns.txt): Relaxing the protover-based shutdown rules
+* [`298-canonical-families.txt`](/proposals/298-canonical-families.txt): Putting family lines in canonical form
+* [`301-dont-vote-on-package-fingerprints.txt`](/proposals/301-dont-vote-on-package-fingerprints.txt): Don't include package fingerprints in consensus documents
+* [`302-padding-machines-for-onion-clients.txt`](/proposals/302-padding-machines-for-onion-clients.txt): Hiding onion service clients using padding
+* [`304-socks5-extending-hs-error-codes.txt`](/proposals/304-socks5-extending-hs-error-codes.txt): Extending SOCKS5 Onion Service Error Codes
+* [`305-establish-intro-dos-defense-extention.txt`](/proposals/305-establish-intro-dos-defense-extention.txt): ESTABLISH_INTRO Cell DoS Defense Extension
+* [`310-bandaid-on-guard-selection.txt`](/proposals/310-bandaid-on-guard-selection.txt): Towards load-balancing in Prop 271
+* [`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
+* [`335-middle-only-redux.md`](/proposals/335-middle-only-redux.md): An authority-only design for MiddleOnly
+* [`336-randomize-guard-retries.md`](/proposals/336-randomize-guard-retries.md): Randomized schedule for guard retries
+* [`337-simpler-guard-usability.md`](/proposals/337-simpler-guard-usability.md): A simpler way to decide, "Is this guard usable?"
+* [`345-specs-in-mdbook.md`](/proposals/345-specs-in-mdbook.md): Migrating the tor specifications to mdbook
+
+
+## RESERVE proposals: saving for later
+
+These proposals aren't anything we plan to implement soon, but for one
+reason or another we think they might be a good idea in the
+future. We're keeping them around as a reference in case we someday
+confront the problems that they try to solve.
+
+* [`133-unreachable-ors.txt`](/proposals/133-unreachable-ors.txt): Incorporate Unreachable ORs into the Tor Network
+* [`172-circ-getinfo-option.txt`](/proposals/172-circ-getinfo-option.txt): GETINFO controller option for circuit information
+* [`177-flag-abstention.txt`](/proposals/177-flag-abstention.txt): Abstaining from votes on individual flags
+* [`188-bridge-guards.txt`](/proposals/188-bridge-guards.txt): Bridge Guards and other anti-enumeration defenses
+* [`201-bridge-v3-reqs-stats.txt`](/proposals/201-bridge-v3-reqs-stats.txt): Make bridges report statistics on daily v3 network status requests
+* [`211-mapaddress-tor-status.txt`](/proposals/211-mapaddress-tor-status.txt): Internal Mapaddress for Tor Configuration Testing
+* [`223-ace-handshake.txt`](/proposals/223-ace-handshake.txt): Ace: Improved circuit-creation key exchange
+* [`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"
+* [`255-hs-load-balancing.txt`](/proposals/255-hs-load-balancing.txt): Controller features to allow for load-balancing hidden services
+* [`256-key-revocation.txt`](/proposals/256-key-revocation.txt): Key revocation for relays and authorities
+* [`262-rekey-circuits.txt`](/proposals/262-rekey-circuits.txt): Re-keying live circuits with new cryptographic material
+* [`273-exit-relay-pinning.txt`](/proposals/273-exit-relay-pinning.txt): Exit relay pinning for web services
+* [`281-bulk-md-download.txt`](/proposals/281-bulk-md-download.txt): Downloading microdescriptors in bulk
+* [`288-privcount-with-shamir.txt`](/proposals/288-privcount-with-shamir.txt): Privacy-Preserving Statistics with Privcount in Tor (Shamir version)
+* [`307-onionbalance-v3.txt`](/proposals/307-onionbalance-v3.txt): Onion Balance Support for Onion Service v3
+
+
+## SUPERSEDED proposals: replaced by something else
+
+These proposals were obsoleted by a later proposal before they were
+implemented.
+
+* [`112-bring-back-pathlencoinweight.txt`](/proposals/112-bring-back-pathlencoinweight.txt): Bring Back Pathlen Coin Weight
+* [`113-fast-authority-interface.txt`](/proposals/113-fast-authority-interface.txt): Simplifying directory authority administration
+* [`118-multiple-orports.txt`](/proposals/118-multiple-orports.txt): Advertising multiple ORPorts at once
+* [`124-tls-certificates.txt`](/proposals/124-tls-certificates.txt): Blocking resistant TLS certificate usage
+* [`143-distributed-storage-improvements.txt`](/proposals/143-distributed-storage-improvements.txt): Improvements of Distributed Storage for Tor Hidden Service Descriptors
+* [`145-newguard-flag.txt`](/proposals/145-newguard-flag.txt): Separate "suitable as a guard" from "suitable as a new guard"
+* [`146-long-term-stability.txt`](/proposals/146-long-term-stability.txt): Add new flag to reflect long-term stability
+* [`149-using-netinfo-data.txt`](/proposals/149-using-netinfo-data.txt): Using data from NETINFO cells
+* [`153-automatic-software-update-protocol.txt`](/proposals/153-automatic-software-update-protocol.txt): Automatic software update protocol
+* [`154-automatic-updates.txt`](/proposals/154-automatic-updates.txt): Automatic Software Update Protocol
+* [`156-tracking-blocked-ports.txt`](/proposals/156-tracking-blocked-ports.txt): Tracking blocked ports on the client side
+* [`163-detecting-clients.txt`](/proposals/163-detecting-clients.txt): Detecting whether a connection comes from a client
+* [`169-eliminating-renegotiation.txt`](/proposals/169-eliminating-renegotiation.txt): Eliminate TLS renegotiation for the Tor connection handshake
+* [`170-user-path-config.txt`](/proposals/170-user-path-config.txt): Configuration options regarding circuit building
+* [`185-dir-without-dirport.txt`](/proposals/185-dir-without-dirport.txt): Directory caches without DirPort
+* [`194-mnemonic-urls.txt`](/proposals/194-mnemonic-urls.txt): Mnemonic .onion URLs
+* [`210-faster-headless-consensus-bootstrap.txt`](/proposals/210-faster-headless-consensus-bootstrap.txt): Faster Headless Consensus Bootstrapping
+* [`225-strawman-shared-rand.txt`](/proposals/225-strawman-shared-rand.txt): Strawman proposal: commit-and-reveal shared rng
+* [`242-better-families.txt`](/proposals/242-better-families.txt): Better performance and usability for the MyFamily option
+* [`247-hs-guard-discovery.txt`](/proposals/247-hs-guard-discovery.txt): Defending Against Guard Discovery Attacks using Vanguards
+* [`249-large-create-cells.txt`](/proposals/249-large-create-cells.txt): Allow CREATE cells with >505 bytes of handshake data
+* [`252-single-onion.txt`](/proposals/252-single-onion.txt): Single Onion Services
+* [`266-removing-current-obsolete-clients.txt`](/proposals/266-removing-current-obsolete-clients.txt): Removing current obsolete clients from the Tor network
+* [`280-privcount-in-tor.txt`](/proposals/280-privcount-in-tor.txt): Privacy-Preserving Statistics with Privcount in Tor
+* [`299-ip-failure-count.txt`](/proposals/299-ip-failure-count.txt): Preferring IPv4 or IPv6 based on IP Version Failure Count
+* [`308-counter-galois-onion.txt`](/proposals/308-counter-galois-onion.txt): Counter Galois Onion: A New Proposal for Forward-Secure Relay Cryptography
+* [`334-middle-only-flag.txt`](/proposals/334-middle-only-flag.txt): A Directory Authority Flag To Mark Relays As Middle-only
+
+
+## DEAD, REJECTED, OBSOLETE proposals: not in our plans
+
+These proposals are not on-track for discussion or
+implementation. Either discussion has stalled out (the proposal is
+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\]
+
+
+
+
diff --git a/proposals/README_template.md b/proposals/BY_STATUS_template.md
index 55a913d..c8c2963 100644
--- a/proposals/README_template.md
+++ b/proposals/BY_STATUS_template.md
@@ -11,7 +11,7 @@ of these proposals are implemented; some are works in progress; and some
will never be implemented.
Below are a list of proposals sorted by status. See
-[INDEX.md](/proposals/INDEX.md) for a list of proposals sorted by number.
+[BY_INDEX.md](/proposals/BY_INDEX.md) for a list of proposals sorted by number.
# Active proposals by status
diff --git a/proposals/README.md b/proposals/README.md
index 643cf53..abaeebf 100644
--- a/proposals/README.md
+++ b/proposals/README.md
@@ -1,361 +1,17 @@
-# Tor proposals by status
-
-<!-- DO NOT EDIT THIS FILE -->
-
-<!-- If you want to make changes here, make sure to edit the -->
-<!-- README_template.md file. The README.md file is generated by the -->
-<!-- reindex.py script. -->
-
-Here we have a set of proposals for changes to the Tor protocol. Some
-of these proposals are implemented; some are works in progress; and some
-will never be implemented.
-
-Below are a list of proposals sorted by status. See
-[INDEX.md](/proposals/INDEX.md) for a list of proposals sorted by number.
-
-# Active proposals by status
-
-## OPEN proposals: under discussion
-
-These are proposals that we think are likely to be complete, and ripe
-for discussion.
-
-* [`239-consensus-hash-chaining.txt`](/proposals/239-consensus-hash-chaining.txt): Consensus Hash Chaining
-* [`240-auth-cert-revocation.txt`](/proposals/240-auth-cert-revocation.txt): Early signing key revocation for directory authorities
-* [`267-tor-consensus-transparency.txt`](/proposals/267-tor-consensus-transparency.txt): Tor Consensus Transparency
-* [`277-detect-id-sharing.txt`](/proposals/277-detect-id-sharing.txt): Detect multiple relay instances running with same ID
-* [`287-reduce-lifetime.txt`](/proposals/287-reduce-lifetime.txt): Reduce circuit lifetime without overloading the network
-* [`295-relay-crypto-with-adl.txt`](/proposals/295-relay-crypto-with-adl.txt): Using ADL for relay cryptography (solving the crypto-tagging attack)
-* [`296-expose-bandwidth-files.txt`](/proposals/296-expose-bandwidth-files.txt): Have Directory Authorities expose raw bandwidth list files
-* [`301-dont-vote-on-package-fingerprints.txt`](/proposals/301-dont-vote-on-package-fingerprints.txt): Don't include package fingerprints in consensus documents
-* [`303-protover-removal-policy.txt`](/proposals/303-protover-removal-policy.txt): When and how to remove support for protocol versions
-* [`306-ipv6-happy-eyeballs.txt`](/proposals/306-ipv6-happy-eyeballs.txt): A Tor Implementation of IPv6 Happy Eyeballs
-* [`308-counter-galois-onion.txt`](/proposals/308-counter-galois-onion.txt): Counter Galois Onion: A New Proposal for Forward-Secure Relay Cryptography
-* [`309-optimistic-socks-in-tor.txt`](/proposals/309-optimistic-socks-in-tor.txt): Optimistic SOCKS Data
-* [`319-wide-everything.md`](/proposals/319-wide-everything.md): RELAY_FRAGMENT cells
-* [`322-dirport-linkspec.md`](/proposals/322-dirport-linkspec.md): Extending link specifiers to include the directory port
-* [`323-walking-onions-full.md`](/proposals/323-walking-onions-full.md): Specification for Walking Onions
-* [`324-rtt-congestion-control.txt`](/proposals/324-rtt-congestion-control.txt): RTT-based Congestion Control for Tor
-* [`325-packed-relay-cells.md`](/proposals/325-packed-relay-cells.md): Packed relay cells: saving space on small commands
-* [`326-tor-relay-well-known-uri-rfc8615.md`](/proposals/326-tor-relay-well-known-uri-rfc8615.md): The "tor-relay" Well-Known Resource Identifier
-* [`330-authority-contact.md`](/proposals/330-authority-contact.md): Modernizing authority contact entries
-
-
-## ACCEPTED proposals: slated for implementation
-
-These are the proposals that we agree we'd like to implement. They
-might or might not have a specific timeframe planned for their
-implementation.
-
-* [`265-load-balancing-with-overhead.txt`](/proposals/265-load-balancing-with-overhead.txt): Load Balancing with Overhead Parameters
-* [`282-remove-named-from-consensus.txt`](/proposals/282-remove-named-from-consensus.txt): Remove "Named" and "Unnamed" handling from consensus voting
-* [`285-utf-8.txt`](/proposals/285-utf-8.txt): Directory documents should be standardized as UTF-8
-* [`292-mesh-vanguards.txt`](/proposals/292-mesh-vanguards.txt): Mesh-based vanguards
-* [`311-relay-ipv6-reachability.txt`](/proposals/311-relay-ipv6-reachability.txt): Tor Relay IPv6 Reachability
-* [`312-relay-auto-ipv6-addr.txt`](/proposals/312-relay-auto-ipv6-addr.txt): Tor Relay Automatic IPv6 Address Discovery
-* [`313-relay-ipv6-stats.txt`](/proposals/313-relay-ipv6-stats.txt): Tor Relay IPv6 Statistics
-* [`321-happy-families.md`](/proposals/321-happy-families.md): Better performance and usability for the MyFamily option (v2)
-* [`336-randomize-guard-retries.md`](/proposals/336-randomize-guard-retries.md): Randomized schedule for guard retries
-* [`337-simpler-guard-usability.md`](/proposals/337-simpler-guard-usability.md): A simpler way to decide, "Is this guard usable?"
-* [`338-netinfo-y2038.md`](/proposals/338-netinfo-y2038.md): Use an 8-byte timestamp in NETINFO cells
-
-
-## FINISHED proposals: implemented, specs not merged
-
-These proposals are implemented in some version of Tor; the proposals
-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
-* [`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
-
-
-## META proposals: about the proposal process
-
-These proposals describe ongoing policies and changes to the proposals
-process.
-
-* [`000-index.txt`](/proposals/000-index.txt): Index of Tor Proposals
-* [`001-process.txt`](/proposals/001-process.txt): The Tor Proposal Process
-* [`098-todo.txt`](/proposals/098-todo.txt): Proposals that should be written
-* [`099-misc.txt`](/proposals/099-misc.txt): Miscellaneous proposals
-* [`202-improved-relay-crypto.txt`](/proposals/202-improved-relay-crypto.txt): Two improved relay encryption protocols for Tor cells
-* [`257-hiding-authorities.txt`](/proposals/257-hiding-authorities.txt): Refactoring authorities and making them more isolated from the net
-* [`290-deprecate-consensus-methods.txt`](/proposals/290-deprecate-consensus-methods.txt): Continuously update consensus methods
-
-
-## INFORMATIONAL proposals: not actually specifications
-
-These proposals describe a process or project, but aren't actually
-proposed changes in the Tor specifications.
-
-* [`159-exit-scanning.txt`](/proposals/159-exit-scanning.txt): Exit Scanning
-* [`300-walking-onions.txt`](/proposals/300-walking-onions.txt): Walking Onions: Scaling and Saving Bandwidth
-
-
-# Preliminary proposals
-
-## DRAFT proposals: incomplete works
-
-These proposals have been marked as a draft by their author or the editors,
-indicating that they aren't yet in a complete form. They're still open for
-discussion.
-
-* [`294-tls-1.3.txt`](/proposals/294-tls-1.3.txt): TLS 1.3 Migration
-* [`316-flashflow.md`](/proposals/316-flashflow.md): FlashFlow: A Secure Speed Test for Tor (Parent Proposal)
-* [`327-pow-over-intro.txt`](/proposals/327-pow-over-intro.txt): A First Take at PoW Over Introduction Circuits
-* [`329-traffic-splitting.txt`](/proposals/329-traffic-splitting.txt): Overcoming Tor's Bottlenecks with Traffic Splitting
-* [`331-res-tokens-for-anti-dos.md`](/proposals/331-res-tokens-for-anti-dos.md): Res tokens: Anonymous Credentials for Onion Service DoS Resilience
-* [`339-udp-over-tor.md`](/proposals/339-udp-over-tor.md): UDP traffic over Tor
-
-
-## NEEDS-REVISION proposals: ideas that we can't implement as-is
-
-These proposals have some promise, but we can't implement them without
-certain changes.
-
-* [`212-using-old-consensus.txt`](/proposals/212-using-old-consensus.txt): Increase Acceptable Consensus Age
-* [`219-expanded-dns.txt`](/proposals/219-expanded-dns.txt): Support for full DNS and DNSSEC resolution in Tor
-* [`245-tap-out.txt`](/proposals/245-tap-out.txt): Deprecating and removing the TAP circuit extension protocol
-* [`248-removing-rsa-identities.txt`](/proposals/248-removing-rsa-identities.txt): Remove all RSA identity keys
-* [`269-hybrid-handshake.txt`](/proposals/269-hybrid-handshake.txt): Transitionally secure hybrid handshakes
-* [`279-naming-layer-api.txt`](/proposals/279-naming-layer-api.txt): A Name System API for Tor Onion Services
-* [`291-two-guard-nodes.txt`](/proposals/291-two-guard-nodes.txt): The move to two guard nodes
-* [`317-secure-dns-name-resolution.txt`](/proposals/317-secure-dns-name-resolution.txt): Improve security aspects of DNS name resolution
-
-
-## NEEDS-RESEARCH proposals: blocking on research
-
-These proposals are interesting ideas, but there's more research that would
-need to happen before we can know whether to implement them or not, or to
-fill in certain details.
-
-(There are no proposals in this category)
-
-
-# Inactive proposals by status
-
-## CLOSED proposals: implemented and specified
-
-These proposals have been implemented in some version of Tor, and the
-changes from the proposals have been merged into the specifications as
-necessary.
-
-* [`101-dir-voting.txt`](/proposals/101-dir-voting.txt): Voting on the Tor Directory System
-* [`102-drop-opt.txt`](/proposals/102-drop-opt.txt): Dropping "opt" from the directory format
-* [`103-multilevel-keys.txt`](/proposals/103-multilevel-keys.txt): Splitting identity key from regularly used signing key
-* [`104-short-descriptors.txt`](/proposals/104-short-descriptors.txt): Long and Short Router Descriptors
-* [`105-handshake-revision.txt`](/proposals/105-handshake-revision.txt): Version negotiation for the Tor protocol
-* [`106-less-tls-constraint.txt`](/proposals/106-less-tls-constraint.txt): Checking fewer things during TLS handshakes
-* [`107-uptime-sanity-checking.txt`](/proposals/107-uptime-sanity-checking.txt): Uptime Sanity Checking
-* [`108-mtbf-based-stability.txt`](/proposals/108-mtbf-based-stability.txt): Base "Stable" Flag on Mean Time Between Failures
-* [`109-no-sharing-ips.txt`](/proposals/109-no-sharing-ips.txt): No more than one server per IP address
-* [`110-avoid-infinite-circuits.txt`](/proposals/110-avoid-infinite-circuits.txt): Avoiding infinite length circuits
-* [`111-local-traffic-priority.txt`](/proposals/111-local-traffic-priority.txt): Prioritizing local traffic over relayed traffic
-* [`114-distributed-storage.txt`](/proposals/114-distributed-storage.txt): Distributed Storage for Tor Hidden Service Descriptors
-* [`117-ipv6-exits.txt`](/proposals/117-ipv6-exits.txt): IPv6 exits
-* [`119-controlport-auth.txt`](/proposals/119-controlport-auth.txt): New PROTOCOLINFO command for controllers
-* [`121-hidden-service-authentication.txt`](/proposals/121-hidden-service-authentication.txt): Hidden Service Authentication
-* [`122-unnamed-flag.txt`](/proposals/122-unnamed-flag.txt): Network status entries need a new Unnamed flag
-* [`123-autonaming.txt`](/proposals/123-autonaming.txt): Naming authorities automatically create bindings
-* [`125-bridges.txt`](/proposals/125-bridges.txt): Behavior for bridge users, bridge relays, and bridge authorities
-* [`126-geoip-reporting.txt`](/proposals/126-geoip-reporting.txt): Getting GeoIP data and publishing usage summaries
-* [`129-reject-plaintext-ports.txt`](/proposals/129-reject-plaintext-ports.txt): Block Insecure Protocols by Default
-* [`130-v2-conn-protocol.txt`](/proposals/130-v2-conn-protocol.txt): Version 2 Tor connection protocol
-* [`135-private-tor-networks.txt`](/proposals/135-private-tor-networks.txt): Simplify Configuration of Private Tor Networks
-* [`136-legacy-keys.txt`](/proposals/136-legacy-keys.txt): Mass authority migration with legacy keys
-* [`137-bootstrap-phases.txt`](/proposals/137-bootstrap-phases.txt): Keep controllers informed as Tor bootstraps
-* [`138-remove-down-routers-from-consensus.txt`](/proposals/138-remove-down-routers-from-consensus.txt): Remove routers that are not Running from consensus documents
-* [`139-conditional-consensus-download.txt`](/proposals/139-conditional-consensus-download.txt): Download consensus documents only when it will be trusted
-* [`140-consensus-diffs.txt`](/proposals/140-consensus-diffs.txt): Provide diffs between consensuses
-* [`148-uniform-client-end-reason.txt`](/proposals/148-uniform-client-end-reason.txt): Stream end reasons from the client side should be uniform
-* [`150-exclude-exit-nodes.txt`](/proposals/150-exclude-exit-nodes.txt): Exclude Exit Nodes from a circuit
-* [`151-path-selection-improvements.txt`](/proposals/151-path-selection-improvements.txt): Improving Tor Path Selection
-* [`152-single-hop-circuits.txt`](/proposals/152-single-hop-circuits.txt): Optionally allow exit from single-hop circuits
-* [`155-four-hidden-service-improvements.txt`](/proposals/155-four-hidden-service-improvements.txt): Four Improvements of Hidden Service Performance
-* [`157-specific-cert-download.txt`](/proposals/157-specific-cert-download.txt): Make certificate downloads specific
-* [`158-microdescriptors.txt`](/proposals/158-microdescriptors.txt): Clients download consensus + microdescriptors
-* [`160-bandwidth-offset.txt`](/proposals/160-bandwidth-offset.txt): Authorities vote for bandwidth offsets in consensus
-* [`161-computing-bandwidth-adjustments.txt`](/proposals/161-computing-bandwidth-adjustments.txt): Computing Bandwidth Adjustments
-* [`162-consensus-flavors.txt`](/proposals/162-consensus-flavors.txt): Publish the consensus in multiple flavors
-* [`166-statistics-extra-info-docs.txt`](/proposals/166-statistics-extra-info-docs.txt): Including Network Statistics in Extra-Info Documents
-* [`167-params-in-consensus.txt`](/proposals/167-params-in-consensus.txt): Vote on network parameters in consensus
-* [`171-separate-streams.txt`](/proposals/171-separate-streams.txt): Separate streams across circuits by connection metadata
-* [`174-optimistic-data-server.txt`](/proposals/174-optimistic-data-server.txt): Optimistic Data for Tor: Server Side
-* [`176-revising-handshake.txt`](/proposals/176-revising-handshake.txt): Proposed version-3 link handshake for Tor
-* [`178-param-voting.txt`](/proposals/178-param-voting.txt): Require majority of authorities to vote for consensus parameters
-* [`179-TLS-cert-and-parameter-normalization.txt`](/proposals/179-TLS-cert-and-parameter-normalization.txt): TLS certificate and parameter normalization
-* [`180-pluggable-transport.txt`](/proposals/180-pluggable-transport.txt): Pluggable transports for circumvention
-* [`181-optimistic-data-client.txt`](/proposals/181-optimistic-data-client.txt): Optimistic Data for Tor: Client Side
-* [`183-refillintervals.txt`](/proposals/183-refillintervals.txt): Refill Intervals
-* [`184-v3-link-protocol.txt`](/proposals/184-v3-link-protocol.txt): Miscellaneous changes for a v3 Tor link protocol
-* [`186-multiple-orports.txt`](/proposals/186-multiple-orports.txt): Multiple addresses for one OR or bridge
-* [`187-allow-client-auth.txt`](/proposals/187-allow-client-auth.txt): Reserve a cell type to allow client authorization
-* [`193-safe-cookie-authentication.txt`](/proposals/193-safe-cookie-authentication.txt): Safe cookie authentication for Tor controllers
-* [`196-transport-control-ports.txt`](/proposals/196-transport-control-ports.txt): Extended ORPort and TransportControlPort
-* [`198-restore-clienthello-semantics.txt`](/proposals/198-restore-clienthello-semantics.txt): Restore semantics of TLS ClientHello
-* [`200-new-create-and-extend-cells.txt`](/proposals/200-new-create-and-extend-cells.txt): Adding new, extensible CREATE, EXTEND, and related cells
-* [`204-hidserv-subdomains.txt`](/proposals/204-hidserv-subdomains.txt): Subdomain support for Hidden Service addresses
-* [`205-local-dnscache.txt`](/proposals/205-local-dnscache.txt): Remove global client-side DNS caching
-* [`206-directory-sources.txt`](/proposals/206-directory-sources.txt): Preconfigured directory sources for bootstrapping
-* [`207-directory-guards.txt`](/proposals/207-directory-guards.txt): Directory guards
-* [`208-ipv6-exits-redux.txt`](/proposals/208-ipv6-exits-redux.txt): IPv6 Exits Redux
-* [`214-longer-circids.txt`](/proposals/214-longer-circids.txt): Allow 4-byte circuit IDs in a new link protocol
-* [`215-update-min-consensus-ver.txt`](/proposals/215-update-min-consensus-ver.txt): Let the minimum consensus method change with time
-* [`216-ntor-handshake.txt`](/proposals/216-ntor-handshake.txt): Improved circuit-creation key exchange
-* [`217-ext-orport-auth.txt`](/proposals/217-ext-orport-auth.txt): Tor Extended ORPort Authentication
-* [`218-usage-controller-events.txt`](/proposals/218-usage-controller-events.txt): Controller events to better understand connection/circuit usage
-* [`220-ecc-id-keys.txt`](/proposals/220-ecc-id-keys.txt): Migrate server identity keys to Ed25519
-* [`221-stop-using-create-fast.txt`](/proposals/221-stop-using-create-fast.txt): Stop using CREATE_FAST
-* [`222-remove-client-timestamps.txt`](/proposals/222-remove-client-timestamps.txt): Stop sending client timestamps
-* [`224-rend-spec-ng.txt`](/proposals/224-rend-spec-ng.txt): Next-Generation Hidden Services in Tor
-* [`227-vote-on-package-fingerprints.txt`](/proposals/227-vote-on-package-fingerprints.txt): Include package fingerprints in consensus documents
-* [`228-cross-certification-onionkeys.txt`](/proposals/228-cross-certification-onionkeys.txt): Cross-certifying identity keys with onion keys
-* [`232-pluggable-transports-through-proxy.txt`](/proposals/232-pluggable-transports-through-proxy.txt): Pluggable Transport through SOCKS proxy
-* [`235-kill-named-flag.txt`](/proposals/235-kill-named-flag.txt): Stop assigning (and eventually supporting) the Named flag
-* [`236-single-guard-node.txt`](/proposals/236-single-guard-node.txt): The move to a single guard node
-* [`237-directory-servers-for-all.txt`](/proposals/237-directory-servers-for-all.txt): All relays are directory servers
-* [`238-hs-relay-stats.txt`](/proposals/238-hs-relay-stats.txt): Better hidden service stats from Tor relays
-* [`243-hsdir-flag-need-stable.txt`](/proposals/243-hsdir-flag-need-stable.txt): Give out HSDir flag only to relays with Stable flag
-* [`244-use-rfc5705-for-tls-binding.txt`](/proposals/244-use-rfc5705-for-tls-binding.txt): Use RFC5705 Key Exporting in our AUTHENTICATE calls
-* [`250-commit-reveal-consensus.txt`](/proposals/250-commit-reveal-consensus.txt): Random Number Generation During Tor Voting
-* [`251-netflow-padding.txt`](/proposals/251-netflow-padding.txt): Padding for netflow record resolution reduction
-* [`254-padding-negotiation.txt`](/proposals/254-padding-negotiation.txt): Padding Negotiation
-* [`264-subprotocol-versions.txt`](/proposals/264-subprotocol-versions.txt): Putting version numbers on the Tor subprotocols
-* [`271-another-guard-selection.txt`](/proposals/271-another-guard-selection.txt): Another algorithm for guard selection
-* [`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
-* [`274-rotate-onion-keys-less.txt`](/proposals/274-rotate-onion-keys-less.txt): Rotate onion keys less frequently
-* [`275-md-published-time-is-silly.txt`](/proposals/275-md-published-time-is-silly.txt): Stop including meaningful "published" time in microdescriptor consensus
-* [`278-directory-compression-scheme-negotiation.txt`](/proposals/278-directory-compression-scheme-negotiation.txt): Directory Compression Scheme Negotiation
-* [`283-ipv6-in-micro-consensus.txt`](/proposals/283-ipv6-in-micro-consensus.txt): Move IPv6 ORPorts from microdescriptors to the microdesc consensus
-* [`284-hsv3-control-port.txt`](/proposals/284-hsv3-control-port.txt): Hidden Service v3 Control Port
-* [`289-authenticated-sendmes.txt`](/proposals/289-authenticated-sendmes.txt): Authenticating sendme cells to mitigate bandwidth attacks
-* [`293-know-when-to-publish.txt`](/proposals/293-know-when-to-publish.txt): Other ways for relays to know when to publish
-* [`297-safer-protover-shutdowns.txt`](/proposals/297-safer-protover-shutdowns.txt): Relaxing the protover-based shutdown rules
-* [`298-canonical-families.txt`](/proposals/298-canonical-families.txt): Putting family lines in canonical form
-* [`302-padding-machines-for-onion-clients.txt`](/proposals/302-padding-machines-for-onion-clients.txt): Hiding onion service clients using padding
-* [`304-socks5-extending-hs-error-codes.txt`](/proposals/304-socks5-extending-hs-error-codes.txt): Extending SOCKS5 Onion Service Error Codes
-* [`305-establish-intro-dos-defense-extention.txt`](/proposals/305-establish-intro-dos-defense-extention.txt): ESTABLISH_INTRO Cell DoS Defense Extension
-* [`310-bandaid-on-guard-selection.txt`](/proposals/310-bandaid-on-guard-selection.txt): Towards load-balancing in Prop 271
-* [`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
-* [`328-relay-overload-report.md`](/proposals/328-relay-overload-report.md): Make Relays Report When They Are Overloaded
-* [`335-middle-only-redux.md`](/proposals/335-middle-only-redux.md): An authority-only design for MiddleOnly
-
-
-## RESERVE proposals: saving for later
-
-These proposals aren't anything we plan to implement soon, but for one
-reason or another we think they might be a good idea in the
-future. We're keeping them around as a reference in case we someday
-confront the problems that they try to solve.
-
-* [`133-unreachable-ors.txt`](/proposals/133-unreachable-ors.txt): Incorporate Unreachable ORs into the Tor Network
-* [`172-circ-getinfo-option.txt`](/proposals/172-circ-getinfo-option.txt): GETINFO controller option for circuit information
-* [`177-flag-abstention.txt`](/proposals/177-flag-abstention.txt): Abstaining from votes on individual flags
-* [`188-bridge-guards.txt`](/proposals/188-bridge-guards.txt): Bridge Guards and other anti-enumeration defenses
-* [`201-bridge-v3-reqs-stats.txt`](/proposals/201-bridge-v3-reqs-stats.txt): Make bridges report statistics on daily v3 network status requests
-* [`211-mapaddress-tor-status.txt`](/proposals/211-mapaddress-tor-status.txt): Internal Mapaddress for Tor Configuration Testing
-* [`223-ace-handshake.txt`](/proposals/223-ace-handshake.txt): Ace: Improved circuit-creation key exchange
-* [`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"
-* [`255-hs-load-balancing.txt`](/proposals/255-hs-load-balancing.txt): Controller features to allow for load-balancing hidden services
-* [`256-key-revocation.txt`](/proposals/256-key-revocation.txt): Key revocation for relays and authorities
-* [`262-rekey-circuits.txt`](/proposals/262-rekey-circuits.txt): Re-keying live circuits with new cryptographic material
-* [`273-exit-relay-pinning.txt`](/proposals/273-exit-relay-pinning.txt): Exit relay pinning for web services
-* [`281-bulk-md-download.txt`](/proposals/281-bulk-md-download.txt): Downloading microdescriptors in bulk
-* [`288-privcount-with-shamir.txt`](/proposals/288-privcount-with-shamir.txt): Privacy-Preserving Statistics with Privcount in Tor (Shamir version)
-* [`307-onionbalance-v3.txt`](/proposals/307-onionbalance-v3.txt): Onion Balance Support for Onion Service v3
-
-
-## SUPERSEDED proposals: replaced by something else
-
-These proposals were obsoleted by a later proposal before they were
-implemented.
-
-* [`112-bring-back-pathlencoinweight.txt`](/proposals/112-bring-back-pathlencoinweight.txt): Bring Back Pathlen Coin Weight
-* [`113-fast-authority-interface.txt`](/proposals/113-fast-authority-interface.txt): Simplifying directory authority administration
-* [`118-multiple-orports.txt`](/proposals/118-multiple-orports.txt): Advertising multiple ORPorts at once
-* [`124-tls-certificates.txt`](/proposals/124-tls-certificates.txt): Blocking resistant TLS certificate usage
-* [`143-distributed-storage-improvements.txt`](/proposals/143-distributed-storage-improvements.txt): Improvements of Distributed Storage for Tor Hidden Service Descriptors
-* [`145-newguard-flag.txt`](/proposals/145-newguard-flag.txt): Separate "suitable as a guard" from "suitable as a new guard"
-* [`146-long-term-stability.txt`](/proposals/146-long-term-stability.txt): Add new flag to reflect long-term stability
-* [`149-using-netinfo-data.txt`](/proposals/149-using-netinfo-data.txt): Using data from NETINFO cells
-* [`153-automatic-software-update-protocol.txt`](/proposals/153-automatic-software-update-protocol.txt): Automatic software update protocol
-* [`154-automatic-updates.txt`](/proposals/154-automatic-updates.txt): Automatic Software Update Protocol
-* [`156-tracking-blocked-ports.txt`](/proposals/156-tracking-blocked-ports.txt): Tracking blocked ports on the client side
-* [`163-detecting-clients.txt`](/proposals/163-detecting-clients.txt): Detecting whether a connection comes from a client
-* [`169-eliminating-renegotiation.txt`](/proposals/169-eliminating-renegotiation.txt): Eliminate TLS renegotiation for the Tor connection handshake
-* [`170-user-path-config.txt`](/proposals/170-user-path-config.txt): Configuration options regarding circuit building
-* [`185-dir-without-dirport.txt`](/proposals/185-dir-without-dirport.txt): Directory caches without DirPort
-* [`194-mnemonic-urls.txt`](/proposals/194-mnemonic-urls.txt): Mnemonic .onion URLs
-* [`210-faster-headless-consensus-bootstrap.txt`](/proposals/210-faster-headless-consensus-bootstrap.txt): Faster Headless Consensus Bootstrapping
-* [`225-strawman-shared-rand.txt`](/proposals/225-strawman-shared-rand.txt): Strawman proposal: commit-and-reveal shared rng
-* [`242-better-families.txt`](/proposals/242-better-families.txt): Better performance and usability for the MyFamily option
-* [`247-hs-guard-discovery.txt`](/proposals/247-hs-guard-discovery.txt): Defending Against Guard Discovery Attacks using Vanguards
-* [`249-large-create-cells.txt`](/proposals/249-large-create-cells.txt): Allow CREATE cells with >505 bytes of handshake data
-* [`252-single-onion.txt`](/proposals/252-single-onion.txt): Single Onion Services
-* [`266-removing-current-obsolete-clients.txt`](/proposals/266-removing-current-obsolete-clients.txt): Removing current obsolete clients from the Tor network
-* [`280-privcount-in-tor.txt`](/proposals/280-privcount-in-tor.txt): Privacy-Preserving Statistics with Privcount in Tor
-* [`299-ip-failure-count.txt`](/proposals/299-ip-failure-count.txt): Preferring IPv4 or IPv6 based on IP Version Failure Count
-* [`334-middle-only-flag.txt`](/proposals/334-middle-only-flag.txt): A Directory Authority Flag To Mark Relays As Middle-only
-
-
-## DEAD, REJECTED, OBSOLETE proposals: not in our plans
-
-These proposals are not on-track for discussion or
-implementation. Either discussion has stalled out (the proposal is
-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).
-
-* [`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]
-* [`320-tap-out-again.md`](/proposals/320-tap-out-again.md): Removing TAP usage from v2 onion services [REJECTED]
+# Proposals for changes in the Tor protocols
+This "book" is a list of proposals that people have made over the
+years, (dating back to 2007) for protocol changes in Tor.
+Some of these proposals are already implemented or rejected;
+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 [`BY_STATUS.md`](./BY_STATUS.md).
+For information on creating a new proposal, you would ideally look at
+[`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
new file mode 100644
index 0000000..09e1270
--- /dev/null
+++ b/proposals/SUMMARY.md
@@ -0,0 +1,265 @@
+# Summary
+
+[Tor Proposals](README.md)
+[All proposals, by number](BY_INDEX.md)
+[All proposals, by status](BY_STATUS.md)
+
+# Proposals
+
+ - [`000-index`](./000-index.txt): Index of Tor Proposals (META)
+ - [`001-process`](./001-process.txt): The Tor Proposal Process (META)
+ - [`098-todo`](./098-todo.txt): Proposals that should be written (OBSOLETE)
+ - [`099-misc`](./099-misc.txt): Miscellaneous proposals (OBSOLETE)
+ - [`100-tor-spec-udp`](./100-tor-spec-udp.txt): Tor Unreliable Datagram Extension Proposal (DEAD)
+ - [`101-dir-voting`](./101-dir-voting.txt): Voting on the Tor Directory System (CLOSED)
+ - [`102-drop-opt`](./102-drop-opt.txt): Dropping "opt" from the directory format (CLOSED)
+ - [`103-multilevel-keys`](./103-multilevel-keys.txt): Splitting identity key from regularly used signing key (CLOSED)
+ - [`104-short-descriptors`](./104-short-descriptors.txt): Long and Short Router Descriptors (CLOSED)
+ - [`105-handshake-revision`](./105-handshake-revision.txt): Version negotiation for the Tor protocol (CLOSED)
+ - [`106-less-tls-constraint`](./106-less-tls-constraint.txt): Checking fewer things during TLS handshakes (CLOSED)
+ - [`107-uptime-sanity-checking`](./107-uptime-sanity-checking.txt): Uptime Sanity Checking (CLOSED)
+ - [`108-mtbf-based-stability`](./108-mtbf-based-stability.txt): Base "Stable" Flag on Mean Time Between Failures (CLOSED)
+ - [`109-no-sharing-ips`](./109-no-sharing-ips.txt): No more than one server per IP address (CLOSED)
+ - [`110-avoid-infinite-circuits`](./110-avoid-infinite-circuits.txt): Avoiding infinite length circuits (CLOSED)
+ - [`111-local-traffic-priority`](./111-local-traffic-priority.txt): Prioritizing local traffic over relayed traffic (CLOSED)
+ - [`112-bring-back-pathlencoinweight`](./112-bring-back-pathlencoinweight.txt): Bring Back Pathlen Coin Weight (SUPERSEDED)
+ - [`113-fast-authority-interface`](./113-fast-authority-interface.txt): Simplifying directory authority administration (SUPERSEDED)
+ - [`114-distributed-storage`](./114-distributed-storage.txt): Distributed Storage for Tor Hidden Service Descriptors (CLOSED)
+ - [`115-two-hop-paths`](./115-two-hop-paths.txt): Two Hop Paths (DEAD)
+ - [`116-two-hop-paths-from-guard`](./116-two-hop-paths-from-guard.txt): Two hop paths from entry guards (DEAD)
+ - [`117-ipv6-exits`](./117-ipv6-exits.txt): IPv6 exits (CLOSED)
+ - [`118-multiple-orports`](./118-multiple-orports.txt): Advertising multiple ORPorts at once (SUPERSEDED)
+ - [`119-controlport-auth`](./119-controlport-auth.txt): New PROTOCOLINFO command for controllers (CLOSED)
+ - [`120-shutdown-descriptors`](./120-shutdown-descriptors.txt): Shutdown descriptors when Tor servers stop (DEAD)
+ - [`121-hidden-service-authentication`](./121-hidden-service-authentication.txt): Hidden Service Authentication (CLOSED)
+ - [`122-unnamed-flag`](./122-unnamed-flag.txt): Network status entries need a new Unnamed flag (CLOSED)
+ - [`123-autonaming`](./123-autonaming.txt): Naming authorities automatically create bindings (CLOSED)
+ - [`124-tls-certificates`](./124-tls-certificates.txt): Blocking resistant TLS certificate usage (SUPERSEDED)
+ - [`125-bridges`](./125-bridges.txt): Behavior for bridge users, bridge relays, and bridge authorities (CLOSED)
+ - [`126-geoip-reporting`](./126-geoip-reporting.txt): Getting GeoIP data and publishing usage summaries (CLOSED)
+ - [`127-dirport-mirrors-downloads`](./127-dirport-mirrors-downloads.txt): Relaying dirport requests to Tor download site / website (OBSOLETE)
+ - [`128-bridge-families`](./128-bridge-families.txt): Families of private bridges (DEAD)
+ - [`129-reject-plaintext-ports`](./129-reject-plaintext-ports.txt): Block Insecure Protocols by Default (CLOSED)
+ - [`130-v2-conn-protocol`](./130-v2-conn-protocol.txt): Version 2 Tor connection protocol (CLOSED)
+ - [`131-verify-tor-usage`](./131-verify-tor-usage.txt): Help users to verify they are using Tor (OBSOLETE)
+ - [`132-browser-check-tor-service`](./132-browser-check-tor-service.txt): A Tor Web Service For Verifying Correct Browser Configuration (OBSOLETE)
+ - [`133-unreachable-ors`](./133-unreachable-ors.txt): Incorporate Unreachable ORs into the Tor Network (RESERVE)
+ - [`134-robust-voting`](./134-robust-voting.txt): More robust consensus voting with diverse authority sets (REJECTED)
+ - [`135-private-tor-networks`](./135-private-tor-networks.txt): Simplify Configuration of Private Tor Networks (CLOSED)
+ - [`136-legacy-keys`](./136-legacy-keys.txt): Mass authority migration with legacy keys (CLOSED)
+ - [`137-bootstrap-phases`](./137-bootstrap-phases.txt): Keep controllers informed as Tor bootstraps (CLOSED)
+ - [`138-remove-down-routers-from-consensus`](./138-remove-down-routers-from-consensus.txt): Remove routers that are not Running from consensus documents (CLOSED)
+ - [`139-conditional-consensus-download`](./139-conditional-consensus-download.txt): Download consensus documents only when it will be trusted (CLOSED)
+ - [`140-consensus-diffs`](./140-consensus-diffs.txt): Provide diffs between consensuses (CLOSED)
+ - [`141-jit-sd-downloads`](./141-jit-sd-downloads.txt): Download server descriptors on demand (OBSOLETE)
+ - [`142-combine-intro-and-rend-points`](./142-combine-intro-and-rend-points.txt): Combine Introduction and Rendezvous Points (DEAD)
+ - [`143-distributed-storage-improvements`](./143-distributed-storage-improvements.txt): Improvements of Distributed Storage for Tor Hidden Service Descriptors (SUPERSEDED)
+ - [`144-enforce-distinct-providers`](./144-enforce-distinct-providers.txt): Increase the diversity of circuits by detecting nodes belonging the same provider (OBSOLETE)
+ - [`145-newguard-flag`](./145-newguard-flag.txt): Separate "suitable as a guard" from "suitable as a new guard" (SUPERSEDED)
+ - [`146-long-term-stability`](./146-long-term-stability.txt): Add new flag to reflect long-term stability (SUPERSEDED)
+ - [`147-prevoting-opinions`](./147-prevoting-opinions.txt): Eliminate the need for v2 directories in generating v3 directories (REJECTED)
+ - [`148-uniform-client-end-reason`](./148-uniform-client-end-reason.txt): Stream end reasons from the client side should be uniform (CLOSED)
+ - [`149-using-netinfo-data`](./149-using-netinfo-data.txt): Using data from NETINFO cells (SUPERSEDED)
+ - [`150-exclude-exit-nodes`](./150-exclude-exit-nodes.txt): Exclude Exit Nodes from a circuit (CLOSED)
+ - [`151-path-selection-improvements`](./151-path-selection-improvements.txt): Improving Tor Path Selection (CLOSED)
+ - [`152-single-hop-circuits`](./152-single-hop-circuits.txt): Optionally allow exit from single-hop circuits (CLOSED)
+ - [`153-automatic-software-update-protocol`](./153-automatic-software-update-protocol.txt): Automatic software update protocol (SUPERSEDED)
+ - [`154-automatic-updates`](./154-automatic-updates.txt): Automatic Software Update Protocol (SUPERSEDED)
+ - [`155-four-hidden-service-improvements`](./155-four-hidden-service-improvements.txt): Four Improvements of Hidden Service Performance (CLOSED)
+ - [`156-tracking-blocked-ports`](./156-tracking-blocked-ports.txt): Tracking blocked ports on the client side (SUPERSEDED)
+ - [`157-specific-cert-download`](./157-specific-cert-download.txt): Make certificate downloads specific (CLOSED)
+ - [`158-microdescriptors`](./158-microdescriptors.txt): Clients download consensus + microdescriptors (CLOSED)
+ - [`159-exit-scanning`](./159-exit-scanning.txt): Exit Scanning (INFORMATIONAL)
+ - [`160-bandwidth-offset`](./160-bandwidth-offset.txt): Authorities vote for bandwidth offsets in consensus (CLOSED)
+ - [`161-computing-bandwidth-adjustments`](./161-computing-bandwidth-adjustments.txt): Computing Bandwidth Adjustments (CLOSED)
+ - [`162-consensus-flavors`](./162-consensus-flavors.txt): Publish the consensus in multiple flavors (CLOSED)
+ - [`163-detecting-clients`](./163-detecting-clients.txt): Detecting whether a connection comes from a client (SUPERSEDED)
+ - [`164-reporting-server-status`](./164-reporting-server-status.txt): Reporting the status of server votes (OBSOLETE)
+ - [`165-simple-robust-voting`](./165-simple-robust-voting.txt): Easy migration for voting authority sets (REJECTED)
+ - [`166-statistics-extra-info-docs`](./166-statistics-extra-info-docs.txt): Including Network Statistics in Extra-Info Documents (CLOSED)
+ - [`167-params-in-consensus`](./167-params-in-consensus.txt): Vote on network parameters in consensus (CLOSED)
+ - [`168-reduce-circwindow`](./168-reduce-circwindow.txt): Reduce default circuit window (REJECTED)
+ - [`169-eliminating-renegotiation`](./169-eliminating-renegotiation.txt): Eliminate TLS renegotiation for the Tor connection handshake (SUPERSEDED)
+ - [`170-user-path-config`](./170-user-path-config.txt): Configuration options regarding circuit building (SUPERSEDED)
+ - [`171-separate-streams`](./171-separate-streams.txt): Separate streams across circuits by connection metadata (CLOSED)
+ - [`172-circ-getinfo-option`](./172-circ-getinfo-option.txt): GETINFO controller option for circuit information (RESERVE)
+ - [`173-getinfo-option-expansion`](./173-getinfo-option-expansion.txt): GETINFO Option Expansion (OBSOLETE)
+ - [`174-optimistic-data-server`](./174-optimistic-data-server.txt): Optimistic Data for Tor: Server Side (CLOSED)
+ - [`175-automatic-node-promotion`](./175-automatic-node-promotion.txt): Automatically promoting Tor clients to nodes (REJECTED)
+ - [`176-revising-handshake`](./176-revising-handshake.txt): Proposed version-3 link handshake for Tor (CLOSED)
+ - [`177-flag-abstention`](./177-flag-abstention.txt): Abstaining from votes on individual flags (RESERVE)
+ - [`178-param-voting`](./178-param-voting.txt): Require majority of authorities to vote for consensus parameters (CLOSED)
+ - [`179-TLS-cert-and-parameter-normalization`](./179-TLS-cert-and-parameter-normalization.txt): TLS certificate and parameter normalization (CLOSED)
+ - [`180-pluggable-transport`](./180-pluggable-transport.txt): Pluggable transports for circumvention (CLOSED)
+ - [`181-optimistic-data-client`](./181-optimistic-data-client.txt): Optimistic Data for Tor: Client Side (CLOSED)
+ - [`182-creditbucket`](./182-creditbucket.txt): Credit Bucket (OBSOLETE)
+ - [`183-refillintervals`](./183-refillintervals.txt): Refill Intervals (CLOSED)
+ - [`184-v3-link-protocol`](./184-v3-link-protocol.txt): Miscellaneous changes for a v3 Tor link protocol (CLOSED)
+ - [`185-dir-without-dirport`](./185-dir-without-dirport.txt): Directory caches without DirPort (SUPERSEDED)
+ - [`186-multiple-orports`](./186-multiple-orports.txt): Multiple addresses for one OR or bridge (CLOSED)
+ - [`187-allow-client-auth`](./187-allow-client-auth.txt): Reserve a cell type to allow client authorization (CLOSED)
+ - [`188-bridge-guards`](./188-bridge-guards.txt): Bridge Guards and other anti-enumeration defenses (RESERVE)
+ - [`189-authorize-cell`](./189-authorize-cell.txt): AUTHORIZE and AUTHORIZED cells (OBSOLETE)
+ - [`190-shared-secret-bridge-authorization`](./190-shared-secret-bridge-authorization.txt): Bridge Client Authorization Based on a Shared Secret (OBSOLETE)
+ - [`191-mitm-bridge-detection-resistance`](./191-mitm-bridge-detection-resistance.txt): Bridge Detection Resistance against MITM-capable Adversaries (OBSOLETE)
+ - [`192-store-bridge-information`](./192-store-bridge-information.txt): Automatically retrieve and store information about bridges (OBSOLETE)
+ - [`193-safe-cookie-authentication`](./193-safe-cookie-authentication.txt): Safe cookie authentication for Tor controllers (CLOSED)
+ - [`194-mnemonic-urls`](./194-mnemonic-urls.txt): Mnemonic .onion URLs (SUPERSEDED)
+ - [`195-TLS-normalization-for-024`](./195-TLS-normalization-for-024.txt): TLS certificate normalization for Tor 0.2.4.x (DEAD)
+ - [`196-transport-control-ports`](./196-transport-control-ports.txt): Extended ORPort and TransportControlPort (CLOSED)
+ - [`197-postmessage-ipc`](./197-postmessage-ipc.txt): Message-based Inter-Controller IPC Channel (REJECTED)
+ - [`198-restore-clienthello-semantics`](./198-restore-clienthello-semantics.txt): Restore semantics of TLS ClientHello (CLOSED)
+ - [`199-bridgefinder-integration`](./199-bridgefinder-integration.txt): Integration of BridgeFinder and BridgeFinderHelper (OBSOLETE)
+ - [`200-new-create-and-extend-cells`](./200-new-create-and-extend-cells.txt): Adding new, extensible CREATE, EXTEND, and related cells (CLOSED)
+ - [`201-bridge-v3-reqs-stats`](./201-bridge-v3-reqs-stats.txt): Make bridges report statistics on daily v3 network status requests (RESERVE)
+ - [`202-improved-relay-crypto`](./202-improved-relay-crypto.txt): Two improved relay encryption protocols for Tor cells (META)
+ - [`203-https-frontend`](./203-https-frontend.txt): Avoiding censorship by impersonating an HTTPS server (OBSOLETE)
+ - [`204-hidserv-subdomains`](./204-hidserv-subdomains.txt): Subdomain support for Hidden Service addresses (CLOSED)
+ - [`205-local-dnscache`](./205-local-dnscache.txt): Remove global client-side DNS caching (CLOSED)
+ - [`206-directory-sources`](./206-directory-sources.txt): Preconfigured directory sources for bootstrapping (CLOSED)
+ - [`207-directory-guards`](./207-directory-guards.txt): Directory guards (CLOSED)
+ - [`208-ipv6-exits-redux`](./208-ipv6-exits-redux.txt): IPv6 Exits Redux (CLOSED)
+ - [`209-path-bias-tuning`](./209-path-bias-tuning.txt): Tuning the Parameters for the Path Bias Defense (OBSOLETE)
+ - [`210-faster-headless-consensus-bootstrap`](./210-faster-headless-consensus-bootstrap.txt): Faster Headless Consensus Bootstrapping (SUPERSEDED)
+ - [`211-mapaddress-tor-status`](./211-mapaddress-tor-status.txt): Internal Mapaddress for Tor Configuration Testing (RESERVE)
+ - [`212-using-old-consensus`](./212-using-old-consensus.txt): Increase Acceptable Consensus Age (NEEDS-REVISION)
+ - [`213-remove-stream-sendmes`](./213-remove-stream-sendmes.txt): Remove stream-level sendmes from the design (DEAD)
+ - [`214-longer-circids`](./214-longer-circids.txt): Allow 4-byte circuit IDs in a new link protocol (CLOSED)
+ - [`215-update-min-consensus-ver`](./215-update-min-consensus-ver.txt): Let the minimum consensus method change with time (CLOSED)
+ - [`216-ntor-handshake`](./216-ntor-handshake.txt): Improved circuit-creation key exchange (CLOSED)
+ - [`217-ext-orport-auth`](./217-ext-orport-auth.txt): Tor Extended ORPort Authentication (CLOSED)
+ - [`218-usage-controller-events`](./218-usage-controller-events.txt): Controller events to better understand connection/circuit usage (CLOSED)
+ - [`219-expanded-dns`](./219-expanded-dns.txt): Support for full DNS and DNSSEC resolution in Tor (NEEDS-REVISION)
+ - [`220-ecc-id-keys`](./220-ecc-id-keys.txt): Migrate server identity keys to Ed25519 (CLOSED)
+ - [`221-stop-using-create-fast`](./221-stop-using-create-fast.txt): Stop using CREATE_FAST (CLOSED)
+ - [`222-remove-client-timestamps`](./222-remove-client-timestamps.txt): Stop sending client timestamps (CLOSED)
+ - [`223-ace-handshake`](./223-ace-handshake.txt): Ace: Improved circuit-creation key exchange (RESERVE)
+ - [`224-rend-spec-ng`](./224-rend-spec-ng.txt): Next-Generation Hidden Services in Tor (CLOSED)
+ - [`225-strawman-shared-rand`](./225-strawman-shared-rand.txt): Strawman proposal: commit-and-reveal shared rng (SUPERSEDED)
+ - [`226-bridgedb-database-improvements`](./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`](./227-vote-on-package-fingerprints.txt): Include package fingerprints in consensus documents (CLOSED)
+ - [`228-cross-certification-onionkeys`](./228-cross-certification-onionkeys.txt): Cross-certifying identity keys with onion keys (CLOSED)
+ - [`229-further-socks5-extensions`](./229-further-socks5-extensions.txt): Further SOCKS5 extensions (REJECTED)
+ - [`230-rsa1024-relay-id-migration`](./230-rsa1024-relay-id-migration.txt): How to change RSA1024 relay identity keys (OBSOLETE)
+ - [`231-migrate-authority-rsa1024-ids`](./231-migrate-authority-rsa1024-ids.txt): Migrating authority RSA1024 identity keys (OBSOLETE)
+ - [`232-pluggable-transports-through-proxy`](./232-pluggable-transports-through-proxy.txt): Pluggable Transport through SOCKS proxy (CLOSED)
+ - [`233-quicken-tor2web-mode`](./233-quicken-tor2web-mode.txt): Making Tor2Web mode faster (REJECTED)
+ - [`234-remittance-addresses`](./234-remittance-addresses.txt): Adding remittance field to directory specification (REJECTED)
+ - [`235-kill-named-flag`](./235-kill-named-flag.txt): Stop assigning (and eventually supporting) the Named flag (CLOSED)
+ - [`236-single-guard-node`](./236-single-guard-node.txt): The move to a single guard node (CLOSED)
+ - [`237-directory-servers-for-all`](./237-directory-servers-for-all.txt): All relays are directory servers (CLOSED)
+ - [`238-hs-relay-stats`](./238-hs-relay-stats.txt): Better hidden service stats from Tor relays (CLOSED)
+ - [`239-consensus-hash-chaining`](./239-consensus-hash-chaining.txt): Consensus Hash Chaining (OPEN)
+ - [`240-auth-cert-revocation`](./240-auth-cert-revocation.txt): Early signing key revocation for directory authorities (OPEN)
+ - [`241-suspicious-guard-turnover`](./241-suspicious-guard-turnover.txt): Resisting guard-turnover attacks (REJECTED)
+ - [`242-better-families`](./242-better-families.txt): Better performance and usability for the MyFamily option (SUPERSEDED)
+ - [`243-hsdir-flag-need-stable`](./243-hsdir-flag-need-stable.txt): Give out HSDir flag only to relays with Stable flag (CLOSED)
+ - [`244-use-rfc5705-for-tls-binding`](./244-use-rfc5705-for-tls-binding.txt): Use RFC5705 Key Exporting in our AUTHENTICATE calls (CLOSED)
+ - [`245-tap-out`](./245-tap-out.txt): Deprecating and removing the TAP circuit extension protocol (NEEDS-REVISION)
+ - [`246-merge-hsdir-and-intro`](./246-merge-hsdir-and-intro.txt): Merging Hidden Service Directories and Introduction Points (REJECTED)
+ - [`247-hs-guard-discovery`](./247-hs-guard-discovery.txt): Defending Against Guard Discovery Attacks using Vanguards (SUPERSEDED)
+ - [`248-removing-rsa-identities`](./248-removing-rsa-identities.txt): Remove all RSA identity keys (NEEDS-REVISION)
+ - [`249-large-create-cells`](./249-large-create-cells.txt): Allow CREATE cells with >505 bytes of handshake data (SUPERSEDED)
+ - [`250-commit-reveal-consensus`](./250-commit-reveal-consensus.txt): Random Number Generation During Tor Voting (CLOSED)
+ - [`251-netflow-padding`](./251-netflow-padding.txt): Padding for netflow record resolution reduction (CLOSED)
+ - [`252-single-onion`](./252-single-onion.txt): Single Onion Services (SUPERSEDED)
+ - [`253-oob-hmac`](./253-oob-hmac.txt): Out of Band Circuit HMACs (DEAD)
+ - [`254-padding-negotiation`](./254-padding-negotiation.txt): Padding Negotiation (CLOSED)
+ - [`255-hs-load-balancing`](./255-hs-load-balancing.txt): Controller features to allow for load-balancing hidden services (RESERVE)
+ - [`256-key-revocation`](./256-key-revocation.txt): Key revocation for relays and authorities (RESERVE)
+ - [`257-hiding-authorities`](./257-hiding-authorities.txt): Refactoring authorities and making them more isolated from the net (META)
+ - [`258-dirauth-dos`](./258-dirauth-dos.txt): Denial-of-service resistance for directory authorities (DEAD)
+ - [`259-guard-selection`](./259-guard-selection.txt): New Guard Selection Behaviour (OBSOLETE)
+ - [`260-rend-single-onion`](./260-rend-single-onion.txt): Rendezvous Single Onion Services (FINISHED)
+ - [`261-aez-crypto`](./261-aez-crypto.txt): AEZ for relay cryptography (OBSOLETE)
+ - [`262-rekey-circuits`](./262-rekey-circuits.txt): Re-keying live circuits with new cryptographic material (RESERVE)
+ - [`263-ntru-for-pq-handshake`](./263-ntru-for-pq-handshake.txt): Request to change key exchange protocol for handshake v1.2 (OBSOLETE)
+ - [`264-subprotocol-versions`](./264-subprotocol-versions.txt): Putting version numbers on the Tor subprotocols (CLOSED)
+ - [`265-load-balancing-with-overhead`](./265-load-balancing-with-overhead.txt): Load Balancing with Overhead Parameters (OPEN)
+ - [`266-removing-current-obsolete-clients`](./266-removing-current-obsolete-clients.txt): Removing current obsolete clients from the Tor network (SUPERSEDED)
+ - [`267-tor-consensus-transparency`](./267-tor-consensus-transparency.txt): Tor Consensus Transparency (OPEN)
+ - [`268-guard-selection`](./268-guard-selection.txt): New Guard Selection Behaviour (OBSOLETE)
+ - [`269-hybrid-handshake`](./269-hybrid-handshake.txt): Transitionally secure hybrid handshakes (NEEDS-REVISION)
+ - [`270-newhope-hybrid-handshake`](./270-newhope-hybrid-handshake.txt): RebelAlliance: A Post-Quantum Secure Hybrid Handshake Based on NewHope (OBSOLETE)
+ - [`271-another-guard-selection`](./271-another-guard-selection.txt): Another algorithm for guard selection (CLOSED)
+ - [`272-valid-and-running-by-default`](./272-valid-and-running-by-default.txt): Listed routers should be Valid, Running, and treated as such (CLOSED)
+ - [`273-exit-relay-pinning`](./273-exit-relay-pinning.txt): Exit relay pinning for web services (RESERVE)
+ - [`274-rotate-onion-keys-less`](./274-rotate-onion-keys-less.txt): Rotate onion keys less frequently (CLOSED)
+ - [`275-md-published-time-is-silly`](./275-md-published-time-is-silly.txt): Stop including meaningful "published" time in microdescriptor consensus (CLOSED)
+ - [`276-lower-bw-granularity`](./276-lower-bw-granularity.txt): Report bandwidth with lower granularity in consensus documents (DEAD)
+ - [`277-detect-id-sharing`](./277-detect-id-sharing.txt): Detect multiple relay instances running with same ID (OPEN)
+ - [`278-directory-compression-scheme-negotiation`](./278-directory-compression-scheme-negotiation.txt): Directory Compression Scheme Negotiation (CLOSED)
+ - [`279-naming-layer-api`](./279-naming-layer-api.txt): A Name System API for Tor Onion Services (NEEDS-REVISION)
+ - [`280-privcount-in-tor`](./280-privcount-in-tor.txt): Privacy-Preserving Statistics with Privcount in Tor (SUPERSEDED)
+ - [`281-bulk-md-download`](./281-bulk-md-download.txt): Downloading microdescriptors in bulk (RESERVE)
+ - [`282-remove-named-from-consensus`](./282-remove-named-from-consensus.txt): Remove "Named" and "Unnamed" handling from consensus voting (ACCEPTED)
+ - [`283-ipv6-in-micro-consensus`](./283-ipv6-in-micro-consensus.txt): Move IPv6 ORPorts from microdescriptors to the microdesc consensus (CLOSED)
+ - [`284-hsv3-control-port`](./284-hsv3-control-port.txt): Hidden Service v3 Control Port (CLOSED)
+ - [`285-utf-8`](./285-utf-8.txt): Directory documents should be standardized as UTF-8 (ACCEPTED)
+ - [`286-hibernation-api`](./286-hibernation-api.txt): Controller APIs for hibernation access on mobile (REJECTED)
+ - [`287-reduce-lifetime`](./287-reduce-lifetime.txt): Reduce circuit lifetime without overloading the network (OPEN)
+ - [`288-privcount-with-shamir`](./288-privcount-with-shamir.txt): Privacy-Preserving Statistics with Privcount in Tor (Shamir version) (RESERVE)
+ - [`289-authenticated-sendmes`](./289-authenticated-sendmes.txt): Authenticating sendme cells to mitigate bandwidth attacks (CLOSED)
+ - [`290-deprecate-consensus-methods`](./290-deprecate-consensus-methods.txt): Continuously update consensus methods (META)
+ - [`291-two-guard-nodes`](./291-two-guard-nodes.txt): The move to two guard nodes (FINISHED)
+ - [`292-mesh-vanguards`](./292-mesh-vanguards.txt): Mesh-based vanguards (CLOSED)
+ - [`293-know-when-to-publish`](./293-know-when-to-publish.txt): Other ways for relays to know when to publish (CLOSED)
+ - [`294-tls-1.3`](./294-tls-1.3.txt): TLS 1.3 Migration (DRAFT)
+ - [`295-relay-crypto-with-adl`](./295-relay-crypto-with-adl.txt): Using ADL for relay cryptography (solving the crypto-tagging attack) (OPEN)
+ - [`296-expose-bandwidth-files`](./296-expose-bandwidth-files.txt): Have Directory Authorities expose raw bandwidth list files (CLOSED)
+ - [`297-safer-protover-shutdowns`](./297-safer-protover-shutdowns.txt): Relaxing the protover-based shutdown rules (CLOSED)
+ - [`298-canonical-families`](./298-canonical-families.txt): Putting family lines in canonical form (CLOSED)
+ - [`299-ip-failure-count`](./299-ip-failure-count.txt): Preferring IPv4 or IPv6 based on IP Version Failure Count (SUPERSEDED)
+ - [`300-walking-onions`](./300-walking-onions.txt): Walking Onions: Scaling and Saving Bandwidth (INFORMATIONAL)
+ - [`301-dont-vote-on-package-fingerprints`](./301-dont-vote-on-package-fingerprints.txt): Don't include package fingerprints in consensus documents (CLOSED)
+ - [`302-padding-machines-for-onion-clients`](./302-padding-machines-for-onion-clients.txt): Hiding onion service clients using padding (CLOSED)
+ - [`303-protover-removal-policy`](./303-protover-removal-policy.txt): When and how to remove support for protocol versions (OPEN)
+ - [`304-socks5-extending-hs-error-codes`](./304-socks5-extending-hs-error-codes.txt): Extending SOCKS5 Onion Service Error Codes (CLOSED)
+ - [`305-establish-intro-dos-defense-extention`](./305-establish-intro-dos-defense-extention.txt): ESTABLISH_INTRO Cell DoS Defense Extension (CLOSED)
+ - [`306-ipv6-happy-eyeballs`](./306-ipv6-happy-eyeballs.txt): A Tor Implementation of IPv6 Happy Eyeballs (OPEN)
+ - [`307-onionbalance-v3`](./307-onionbalance-v3.txt): Onion Balance Support for Onion Service v3 (RESERVE)
+ - [`308-counter-galois-onion`](./308-counter-galois-onion.txt): Counter Galois Onion: A New Proposal for Forward-Secure Relay Cryptography (SUPERSEDED)
+ - [`309-optimistic-socks-in-tor`](./309-optimistic-socks-in-tor.txt): Optimistic SOCKS Data (OPEN)
+ - [`310-bandaid-on-guard-selection`](./310-bandaid-on-guard-selection.txt): Towards load-balancing in Prop 271 (CLOSED)
+ - [`311-relay-ipv6-reachability`](./311-relay-ipv6-reachability.txt): Tor Relay IPv6 Reachability (ACCEPTED)
+ - [`312-relay-auto-ipv6-addr`](./312-relay-auto-ipv6-addr.txt): Tor Relay Automatic IPv6 Address Discovery (ACCEPTED)
+ - [`313-relay-ipv6-stats`](./313-relay-ipv6-stats.txt): Tor Relay IPv6 Statistics (ACCEPTED)
+ - [`314-allow-markdown-proposals`](./314-allow-markdown-proposals.md): Allow Markdown for proposal format (CLOSED)
+ - [`315-update-dir-required-fields`](./315-update-dir-required-fields.txt): Updating the list of fields required in directory documents (CLOSED)
+ - [`316-flashflow`](./316-flashflow.md): FlashFlow: A Secure Speed Test for Tor (Parent Proposal) (DRAFT)
+ - [`317-secure-dns-name-resolution`](./317-secure-dns-name-resolution.txt): Improve security aspects of DNS name resolution (NEEDS-REVISION)
+ - [`318-limit-protovers`](./318-limit-protovers.md): Limit protover values to 0-63 (CLOSED)
+ - [`319-wide-everything`](./319-wide-everything.md): RELAY_FRAGMENT cells (OBSOLETE)
+ - [`320-tap-out-again`](./320-tap-out-again.md): Removing TAP usage from v2 onion services (REJECTED)
+ - [`321-happy-families`](./321-happy-families.md): Better performance and usability for the MyFamily option (v2) (ACCEPTED)
+ - [`322-dirport-linkspec`](./322-dirport-linkspec.md): Extending link specifiers to include the directory port (OPEN)
+ - [`323-walking-onions-full`](./323-walking-onions-full.md): Specification for Walking Onions (OPEN)
+ - [`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 (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)
+ - [`331-res-tokens-for-anti-dos`](./331-res-tokens-for-anti-dos.md): Res tokens: Anonymous Credentials for Onion Service DoS Resilience (DRAFT)
+ - [`332-ntor-v3-with-extra-data`](./332-ntor-v3-with-extra-data.md): Ntor protocol with extra data, version 3 (CLOSED)
+ - [`333-vanguards-lite`](./333-vanguards-lite.md): Vanguards lite (CLOSED)
+ - [`334-middle-only-flag`](./334-middle-only-flag.txt): A Directory Authority Flag To Mark Relays As Middle-only (SUPERSEDED)
+ - [`335-middle-only-redux`](./335-middle-only-redux.md): An authority-only design for MiddleOnly (CLOSED)
+ - [`336-randomize-guard-retries`](./336-randomize-guard-retries.md): Randomized schedule for guard retries (CLOSED)
+ - [`337-simpler-guard-usability`](./337-simpler-guard-usability.md): A simpler way to decide, "Is this guard usable?" (CLOSED)
+ - [`338-netinfo-y2038`](./338-netinfo-y2038.md): Use an 8-byte timestamp in NETINFO cells (ACCEPTED)
+ - [`339-udp-over-tor`](./339-udp-over-tor.md): UDP traffic over Tor (ACCEPTED)
+ - [`340-packed-and-fragmented`](./340-packed-and-fragmented.md): Packed and fragmented relay messages (OPEN)
+ - [`341-better-oos`](./341-better-oos.md): A better algorithm for out-of-sockets eviction (OPEN)
+ - [`342-decouple-hs-interval`](./342-decouple-hs-interval.md): Decoupling hs_interval and SRV lifetime (DRAFT)
+ - [`343-rend-caa`](./343-rend-caa.txt): CAA Extensions for the Tor Rendezvous Specification (OPEN)
+ - [`344-protocol-info-leaks`](./344-protocol-info-leaks.txt): Prioritizing Protocol Information Leaks in Tor (OPEN)
+ - [`345-specs-in-mdbook`](./345-specs-in-mdbook.md): Migrating the tor specifications to mdbook (CLOSED)
+ - [`346-protovers-again`](./346-protovers-again.md): Clarifying and extending the use of protocol versioning (OPEN)
+ - [`347-domain-separation`](./347-domain-separation.md): Domain separation for certificate signing keys (OPEN)
+ - [`348-udp-app-support`](./348-udp-app-support.md): UDP Application Support in Tor (OPEN)
+ - [`349-command-state-validation`](./349-command-state-validation.md): Client-Side Command Acceptance Validation (DRAFT)
+
+
+
diff --git a/proposals/SUMMARY_template.md b/proposals/SUMMARY_template.md
new file mode 100644
index 0000000..3ca7f6e
--- /dev/null
+++ b/proposals/SUMMARY_template.md
@@ -0,0 +1,11 @@
+# Summary
+
+[Tor Proposals](README.md)
+[All proposals, by number](BY_INDEX.md)
+[All proposals, by status](BY_STATUS.md)
+
+# Proposals
+
+{SUMMARY_TABLE}
+
+
diff --git a/proposals/proposal-status.txt b/proposals/proposal-status.txt
index 8a709bc..af522d1 100644
--- a/proposals/proposal-status.txt
+++ b/proposals/proposal-status.txt
@@ -1,3 +1,4 @@
+```
[Last updated 9 Sep 2015]
This is an update to the Tor proposal status overview. I last sent one
@@ -553,3 +554,4 @@ again to remind me!
this writing) and which parts of our current, more idiosyncratic,
uses of TLS can be removed.
+```
diff --git a/proposals/reindex.py b/proposals/reindex.py
deleted file mode 100755
index 72b1234..0000000
--- a/proposals/reindex.py
+++ /dev/null
@@ -1,200 +0,0 @@
-#!/usr/bin/env python
-
-import sys
-if sys.version_info[0] < 3:
- print("No support for Python 2.")
- sys.exit(1)
-
-import codecs, re, os
-class Error(Exception): pass
-
-STATUSES = """DRAFT NEEDS-REVISION NEEDS-RESEARCH OPEN ACCEPTED META FINISHED
- CLOSED SUPERSEDED DEAD REJECTED OBSOLETE RESERVE INFORMATIONAL""".split()
-REQUIRED_FIELDS = [ "Filename", "Status", "Title"]
-CONDITIONAL_FIELDS = { "OPEN" : [ "Target", "Ticket" ],
- "ACCEPTED" : [ "Target", "Ticket" ],
- "CLOSED" : [ "Implemented-In", "Ticket" ],
- "FINISHED" : [ "Implemented-In", "Ticket" ] }
-FNAME_RE = re.compile(r'^(\d\d\d)-.*[^\~]$')
-DIR = "."
-OUTFILE_TXT = "000-index.txt"
-TMPFILE_TXT = OUTFILE_TXT+".tmp"
-
-TEMPFILES = [TMPFILE_TXT]
-
-def unlink_if_present(fname):
- try:
- os.unlink(fname)
- except OSError:
- pass
-
-def indexed(seq):
- n = 0
- for i in seq:
- yield n, i
- n += 1
-
-def readProposal(fn):
- fields = { }
- f = codecs.open(fn, 'r', encoding='utf-8')
- lastField = None
- try:
- for lineno, line in indexed(f):
- line = line.rstrip()
- if not line:
- return fields
- if line[0].isspace():
- fields[lastField] += " %s"%(line.strip())
- elif line == "```":
- pass
- else:
- parts = line.split(":", 1)
- if len(parts) != 2:
- raise Error("%s:%s: Neither field, continuation, nor ```."%
- (fn,lineno))
- else:
- fields[parts[0]] = parts[1].strip()
- lastField = parts[0]
-
- return fields
- finally:
- f.close()
-
-def getProposalNumber(fn):
- """Get the proposal's assigned number from its filename `fn`."""
- parts = fn.split('-', 1)
-
- assert len(parts) == 2, \
- "Filename must have a proposal number and title separated by a '-'"
-
- return int(parts[0])
-
-def checkProposal(fn, fields):
- status = fields.get("Status")
- need_fields = REQUIRED_FIELDS + CONDITIONAL_FIELDS.get(status, [])
-
- number = getProposalNumber(fn)
- # Since prop#288 was the newest when we began requiring the 'Ticket:'
- # field, we don't require the field for it or any older proposal.
- # (Although you're encouraged to add it to your proposal, and add it for
- # older proposals where you know the correct ticket, as it greatly helps
- # newcomers find more information on the implementation.)
- if number <= 288:
- if "Ticket" in need_fields:
- need_fields.remove("Ticket")
-
- for f in need_fields:
- if f not in fields:
- raise Error("%s has no %s field"%(fn, f))
- if fn != fields['Filename']:
- raise Error("Mismatched Filename field in %s"%fn)
- if fields['Title'][-1] == '.':
- fields['Title'] = fields['Title'][:-1]
-
- status = fields['Status'] = status.upper()
- if status not in STATUSES:
- raise Error("I've never heard of status %s in %s"%(status,fn))
- if status in [ "SUPERSEDED", "DEAD" ]:
- for f in [ 'Implemented-In', 'Target' ]:
- if f in fields: del fields[f]
-
-def readProposals():
- res = []
- for fn in os.listdir(DIR):
- m = FNAME_RE.match(fn)
- if not m: continue
- if fn.endswith(".tmp"):
- continue
- if not (fn.endswith(".txt") or fn.endswith(".md")):
- raise Error("%s doesn't end with .txt or .md"%fn)
- num = m.group(1)
- fields = readProposal(fn)
- checkProposal(fn, fields)
- fields['num'] = num
- res.append(fields)
- return res
-
-def writeTextIndexFile(proposals):
- proposals.sort(key=lambda f:f['num'])
- seenStatuses = set()
- for p in proposals:
- seenStatuses.add(p['Status'])
-
- out = open(TMPFILE_TXT, 'w')
- inf = open(OUTFILE_TXT, 'r')
- for line in inf:
- out.write(line)
- if line.startswith("====="): break
- inf.close()
-
- out.write("Proposals by number:\n\n")
- for prop in proposals:
- out.write("%(num)s %(Title)s [%(Status)s]\n"%prop)
- out.write("\n\nProposals by status:\n\n")
- for s in STATUSES:
- if s not in seenStatuses: continue
- out.write(" %s:\n"%s)
- for prop in proposals:
- if s == prop['Status']:
- out.write(" %(num)s %(Title)s"%prop)
- if "Target" in prop:
- out.write(" [for %(Target)s]"%prop)
- if "Implemented-In" in prop:
- out.write(" [in %(Implemented-In)s]"%prop)
- out.write("\n")
- out.close()
- os.rename(TMPFILE_TXT, OUTFILE_TXT)
-
-def formatMarkdownEntry(prop, withStatus=False):
- if withStatus:
- fmt = "* [`{Filename}`](/proposals/{Filename}): {Title} [{Status}]\n"
- else:
- fmt = "* [`{Filename}`](/proposals/{Filename}): {Title}\n"
- return fmt.format(**prop)
-
-def writeMarkdownFile(prefix, format_inputs):
- template = prefix+"_template.md"
- output = prefix+".md"
- t = open(template).read()
- content = t.format(**format_inputs)
- with open(output, 'w') as f:
- f.write(content)
-
-def writeMarkdownIndexFiles(proposals):
- markdown_files = [ "README", "BY_INDEX" ]
- format_inputs = {}
-
- format_inputs['warning'] = "<!-- DO NOT EDIT THIS FILE -->"
-
- entries = []
- for prop in proposals:
- entries.append(formatMarkdownEntry(prop, withStatus=True))
- format_inputs["BY_INDEX"] = "".join(entries)
-
- for s in STATUSES:
- entries = []
- for prop in proposals:
- if s == prop['Status']:
- entries.append(formatMarkdownEntry(prop))
- if entries:
- format_inputs[s] = "".join(entries)
- else:
- format_inputs[s] = "(There are no proposals in this category)\n"
-
- entries = []
- for prop in proposals:
- if prop['Status'] in ('DEAD', 'REJECTED', 'OBSOLETE'):
- entries.append(formatMarkdownEntry(prop, withStatus=True))
- format_inputs['DEAD_REJECTED_OBSOLETE'] = "".join(entries)
-
- for prefix in markdown_files:
- writeMarkdownFile(prefix, format_inputs)
-
-if __name__ == '__main__':
- proposals = readProposals()
- try:
- writeTextIndexFile(proposals)
- writeMarkdownIndexFiles(proposals)
- finally:
- for tempfile in TEMPFILES:
- unlink_if_present(tempfile)