aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/HACKING/CircuitPaddingDevelopment.md9
-rw-r--r--doc/HACKING/CodingStandards.md4
-rw-r--r--doc/HACKING/CodingStandardsRust.md553
-rw-r--r--doc/HACKING/GettingStarted.md2
-rw-r--r--doc/HACKING/GettingStartedRust.md187
-rw-r--r--doc/HACKING/HelpfulTools.md4
-rw-r--r--doc/HACKING/Maintaining.md10
-rw-r--r--doc/HACKING/README.1st.md16
-rw-r--r--doc/HACKING/ReleaseSeriesLifecycle.md12
-rw-r--r--doc/HACKING/ReleasingTor.md277
-rw-r--r--doc/HACKING/ReleasingTor.md.old255
-rwxr-xr-xdoc/asciidoc-helper.sh47
-rw-r--r--doc/include.am2
-rw-r--r--doc/man/tor.1.txt180
14 files changed, 529 insertions, 1029 deletions
diff --git a/doc/HACKING/CircuitPaddingDevelopment.md b/doc/HACKING/CircuitPaddingDevelopment.md
index 95ffbae4dd..e4aa9ddd09 100644
--- a/doc/HACKING/CircuitPaddingDevelopment.md
+++ b/doc/HACKING/CircuitPaddingDevelopment.md
@@ -381,11 +381,10 @@ use case.
#### 2.2.2. Detecting and Negotiating Machine Support
When a new machine specification is added to Tor (or removed from Tor), you
-should bump the Padding subprotocol version in `src/core/or/protover.c` and
-`src/rust/protover/protover.rs`, add a field to `protover_summary_flags_t` in
-`or.h`, and set this field in `memoize_protover_summary()` in versions.c. This
-new field must then be checked in `circpad_node_supports_padding()` in
-`circuitpadding.c`.
+should bump the Padding subprotocol version in `src/core/or/protover.c`, add a
+field to `protover_summary_flags_t` in `or.h`, and set this field in
+`memoize_protover_summary()` in versions.c. This new field must then be
+checked in `circpad_node_supports_padding()` in `circuitpadding.c`.
Note that this protocol version update and associated support check is not
necessary if your experiments will *only* be using your own relays that
diff --git a/doc/HACKING/CodingStandards.md b/doc/HACKING/CodingStandards.md
index cd3417d0b5..c5dd6c744f 100644
--- a/doc/HACKING/CodingStandards.md
+++ b/doc/HACKING/CodingStandards.md
@@ -59,7 +59,7 @@ Some compatible licenses include:
Each main development series (like 0.2.1, 0.2.2, etc) has its main work
applied to a single branch. At most one series can be the development series
at a time; all other series are maintenance series that get bug-fixes only.
-The development series is built in a git branch called "master"; the
+The development series is built in a git branch called "main"; the
maintenance series are built in branches called "maint-0.2.0", "maint-0.2.1",
and so on. We regularly merge the active maint branches forward.
@@ -75,7 +75,7 @@ If you're working on a bugfix for a bug that occurs in a particular version,
base your bugfix branch on the "maint" branch for the first supported series
that has that bug. (As of June 2013, we're supporting 0.2.3 and later.)
-If you're working on a new feature, base it on the master branch. If you're
+If you're working on a new feature, base it on the main branch. If you're
working on a new feature and it will take a while to implement and/or you'd
like to avoid the possibility of unrelated bugs in Tor while you're
implementing your feature, consider branching off of the latest maint- branch.
diff --git a/doc/HACKING/CodingStandardsRust.md b/doc/HACKING/CodingStandardsRust.md
deleted file mode 100644
index c821465173..0000000000
--- a/doc/HACKING/CodingStandardsRust.md
+++ /dev/null
@@ -1,553 +0,0 @@
-# Rust Coding Standards
-
-You MUST follow the standards laid out in `doc/HACKING/CodingStandards.md`,
-where applicable.
-
-## Module/Crate Declarations
-
-Each Tor C module which is being rewritten MUST be in its own crate.
-See the structure of `src/rust` for examples.
-
-In your crate, you MUST use `lib.rs` ONLY for pulling in external
-crates (e.g. `extern crate libc;`) and exporting public objects from
-other Rust modules (e.g. `pub use mymodule::foo;`). For example, if
-you create a crate in `src/rust/yourcrate`, your Rust code should
-live in `src/rust/yourcrate/yourcode.rs` and the public interface
-to it should be exported in `src/rust/yourcrate/lib.rs`.
-
-If your code is to be called from Tor C code, you MUST define a safe
-`ffi.rs`. See the "Safety" section further down for more details.
-
-For example, in a hypothetical `tor_addition` Rust module:
-
-In `src/rust/tor_addition/addition.rs`:
-
-```rust
-pub fn get_sum(a: i32, b: i32) -> i32 {
- a + b
-}
-```
-
-In `src/rust/tor_addition/lib.rs`:
-
-```rust
-pub use addition::*;
-```
-
-In `src/rust/tor_addition/ffi.rs`:
-
-```rust
-#[no_mangle]
-pub extern "C" fn tor_get_sum(a: c_int, b: c_int) -> c_int {
- get_sum(a, b)
-}
-```
-
-If your Rust code must call out to parts of Tor's C code, you must
-declare the functions you are calling in the `external` crate, located
-at `src/rust/external`.
-
-<!-- XXX get better examples of how to declare these externs, when/how they -->
-<!-- XXX are unsafe, what they are expected to do —isis -->
-
-Modules should strive to be below 500 lines (tests excluded). Single
-responsibility and limited dependencies should be a guiding standard.
-
-If you have any external modules as dependencies (e.g. `extern crate
-libc;`), you MUST declare them in your crate's `lib.rs` and NOT in any
-other module.
-
-## Dependencies and versions
-
-In general, we use modules from only the Rust standard library
-whenever possible. We will review including external crates on a
-case-by-case basis.
-
-If a crate only contains traits meant for compatibility between Rust
-crates, such as [the digest crate](https://crates.io/crates/digest) or
-[the failure crate](https://crates.io/crates/failure), it is very likely
-permissible to add it as a dependency. However, a brief review should
-be conducted as to the usefulness of implementing external traits
-(i.e. how widespread is the usage, how many other crates either
-implement the traits or have trait bounds based upon them), as well as
-the stability of the traits (i.e. if the trait is going to change, we'll
-potentially have to re-do all our implementations of it).
-
-For large external libraries, especially which implement features which
-would be labour-intensive to reproduce/maintain ourselves, such as
-cryptographic or mathematical/statistics libraries, only crates which
-have stabilised to 1.0.0 should be considered, however, again, we may
-make exceptions on a case-by-case basis.
-
-Currently, Tor requires that you use the latest stable Rust version. At
-some point in the future, we will freeze on a given stable Rust version,
-to ensure backward compatibility with stable distributions that ship it.
-
-## Updating/Adding Dependencies
-
-To add/remove/update dependencies, first add your dependencies,
-exactly specifying their versions, into the appropriate *crate-level*
-`Cargo.toml` in `src/rust/` (i.e. *not* `/src/rust/Cargo.toml`, but
-instead the one for your crate). Also, investigate whether your
-dependency has any optional dependencies which are unnecessary but are
-enabled by default. If so, you'll likely be able to enable/disable
-them via some feature, e.g.:
-
-```toml
-[dependencies]
-foo = { version = "1.0.0", default-features = false }
-```
-
-Next, run `/scripts/maint/updateRustDependencies.sh`. Then, go into
-`src/ext/rust` and commit the changes to the `tor-rust-dependencies`
-repo.
-
-## Documentation
-
-You MUST include `#![deny(missing_docs)]` in your crate.
-
-For function/method comments, you SHOULD include a one-sentence, "first person"
-description of function behaviour (see requirements for documentation as
-described in `src/HACKING/CodingStandards.md`), then an `# Inputs` section
-for inputs or initialisation values, a `# Returns` section for return
-values/types, a `# Warning` section containing warnings for unsafe behaviours or
-panics that could happen. For publicly accessible
-types/constants/objects/functions/methods, you SHOULD also include an
-`# Examples` section with runnable doctests.
-
-You MUST document your module with _module docstring_ comments,
-i.e. `//!` at the beginning of each line.
-
-## Style
-
-You SHOULD consider breaking up large literal numbers with `_` when it makes it
-more human readable to do so, e.g. `let x: u64 = 100_000_000_000`.
-
-## Testing
-
-All code MUST be unittested and integration tested.
-
-Public functions/objects exported from a crate SHOULD include doctests
-describing how the function/object is expected to be used.
-
-Integration tests SHOULD go into a `tests/` directory inside your
-crate. Unittests SHOULD go into their own module inside the module
-they are testing, e.g. in `src/rust/tor_addition/addition.rs` you
-should put:
-
-```rust
-#[cfg(test)]
-mod test {
- use super::*;
-
-#[test]
- fn addition_with_zero() {
- let sum: i32 = get_sum(5i32, 0i32);
- assert_eq!(sum, 5);
- }
-}
-```
-
-## Benchmarking
-
-The external `test` crate can be used for most benchmarking. However, using
-this crate requires nightly Rust. Since we may want to switch to a more
-stable Rust compiler eventually, we shouldn't do things which will automatically
-break builds for stable compilers. Therefore, you MUST feature-gate your
-benchmarks in the following manner.
-
-If you wish to benchmark some of your Rust code, you MUST put the
-following in the `[features]` section of your crate's `Cargo.toml`:
-
-```toml
-[features]
-bench = []
-```
-
-Next, in your crate's `lib.rs` you MUST put:
-
-```rust
-#[cfg(all(test, feature = "bench"))]
-extern crate test;
-```
-
-This ensures that the external crate `test`, which contains utilities
-for basic benchmarks, is only used when running benchmarks via `cargo
-bench --features bench`.
-
-Finally, to write your benchmark code, in
-`src/rust/tor_addition/addition.rs` you SHOULD put:
-
-```rust
-#[cfg(all(test, features = "bench"))]
-mod bench {
- use test::Bencher;
- use super::*;
-
-#[bench]
- fn addition_small_integers(b: &mut Bencher) {
- b.iter(| | get_sum(5i32, 0i32));
- }
-}
-```
-
-## Fuzzing
-
-If you wish to fuzz parts of your code, please see the
-[cargo fuzz](https://github.com/rust-fuzz/cargo-fuzz) crate, which uses
-[libfuzzer-sys](https://github.com/rust-fuzz/libfuzzer-sys).
-
-## Whitespace & Formatting
-
-You MUST run `rustfmt` (https://github.com/rust-lang-nursery/rustfmt)
-on your code before your code will be merged. You can install rustfmt
-by doing `cargo install rustfmt-nightly` and then run it with `cargo
-fmt`.
-
-## Safety
-
-You SHOULD read [the nomicon](https://doc.rust-lang.org/nomicon/) before writing
-Rust FFI code. It is *highly advised* that you read and write normal Rust code
-before attempting to write FFI or any other unsafe code.
-
-Here are some additional bits of advice and rules:
-
-0. Any behaviours which Rust considers to be undefined are forbidden
-
- From https://doc.rust-lang.org/reference/behavior-considered-undefined.html:
-
- > Behavior considered undefined
- >
- > The following is a list of behavior which is forbidden in all Rust code,
- > including within unsafe blocks and unsafe functions. Type checking provides the
- > guarantee that these issues are never caused by safe code.
- >
- > * Data races
- > * Dereferencing a null/dangling raw pointer
- > * Reads of [undef](https://llvm.org/docs/LangRef.html#undefined-values)
- > (uninitialized) memory
- > * Breaking the
- > [pointer aliasing rules](https://llvm.org/docs/LangRef.html#pointer-aliasing-rules)
- > with raw pointers (a subset of the rules used by C)
- > * `&mut T` and `&T` follow LLVM’s scoped noalias model, except if the `&T`
- > contains an `UnsafeCell<U>`. Unsafe code must not violate these aliasing
- > guarantees.
- > * Mutating non-mutable data (that is, data reached through a shared
- > reference or data owned by a `let` binding), unless that data is
- > contained within an `UnsafeCell<U>`.
- > * Invoking undefined behavior via compiler intrinsics:
- > - Indexing outside of the bounds of an object with
- > `std::ptr::offset` (`offset` intrinsic), with the exception of
- > one byte past the end which is permitted.
- > - Using `std::ptr::copy_nonoverlapping_memory` (`memcpy32`/`memcpy64`
- > intrinsics) on overlapping buffers
- > * Invalid values in primitive types, even in private fields/locals:
- > - Dangling/null references or boxes
- > - A value other than `false` (0) or `true` (1) in a `bool`
- > - A discriminant in an `enum` not included in the type definition
- > - A value in a `char` which is a surrogate or above `char::MAX`
- > - Non-UTF-8 byte sequences in a `str`
- > * Unwinding into Rust from foreign code or unwinding from Rust into foreign
- > code. Rust's failure system is not compatible with exception handling in other
- > languages. Unwinding must be caught and handled at FFI boundaries.
-
-1. `unwrap()`
-
- If you call `unwrap()`, anywhere, even in a test, you MUST include
- an inline comment stating how the unwrap will either 1) never fail,
- or 2) should fail (i.e. in a unittest).
-
- You SHOULD NOT use `unwrap()` anywhere in which it is possible to handle the
- potential error with the eel operator, `?` or another non panicking way.
- For example, consider a function which parses a string into an integer:
-
- ```rust
- fn parse_port_number(config_string: &str) -> u16 {
- u16::from_str_radix(config_string, 10).unwrap()
- }
- ```
-
- There are numerous ways this can fail, and the `unwrap()` will cause the
- whole program to byte the dust! Instead, either you SHOULD use `ok()`
- (or another equivalent function which will return an `Option` or a `Result`)
- and change the return type to be compatible:
-
- ```rust
- fn parse_port_number(config_string: &str) -> Option<u16> {
- u16::from_str_radix(config_string, 10).ok()
- }
- ```
-
- or you SHOULD use `or()` (or another similar method):
-
- ```rust
- fn parse_port_number(config_string: &str) -> Option<u16> {
- u16::from_str_radix(config_string, 10).or(Err("Couldn't parse port into a u16")
- }
- ```
-
- Using methods like `or()` can be particularly handy when you must do
- something afterwards with the data, for example, if we wanted to guarantee
- that the port is high. Combining these methods with the eel operator (`?`)
- makes this even easier:
-
- ```rust
- fn parse_port_number(config_string: &str) -> Result<u16, Err> {
- let port = u16::from_str_radix(config_string, 10).or(Err("Couldn't parse port into a u16"))?;
-
- if port > 1024 {
- return Ok(port);
- } else {
- return Err("Low ports not allowed");
- }
- }
- ```
-
-2. `unsafe`
-
- If you use `unsafe`, you MUST describe a contract in your
- documentation which describes how and when the unsafe code may
- fail, and what expectations are made w.r.t. the interfaces to
- unsafe code. This is also REQUIRED for major pieces of FFI between
- C and Rust.
-
- When creating an FFI in Rust for C code to call, it is NOT REQUIRED
- to declare the entire function `unsafe`. For example, rather than doing:
-
- ```rust
- #[no_mangle]
- pub unsafe extern "C" fn increment_and_combine_numbers(mut numbers: [u8; 4]) -> u32 {
- for number in &mut numbers {
- *number += 1;
- }
- std::mem::transmute::<[u8; 4], u32>(numbers)
- }
- ```
-
- You SHOULD instead do:
-
- ```rust
- #[no_mangle]
- pub extern "C" fn increment_and_combine_numbers(mut numbers: [u8; 4]) -> u32 {
- for index in 0..numbers.len() {
- numbers[index] += 1;
- }
- unsafe {
- std::mem::transmute::<[u8; 4], u32>(numbers)
- }
- }
- ```
-
-3. Pass only C-compatible primitive types and bytes over the boundary
-
- Rust's C-compatible primitive types are integers and floats.
- These types are declared in the [libc crate](https://doc.rust-lang.org/libc/x86_64-unknown-linux-gnu/libc/index.html#types).
- Most Rust objects have different [representations](https://doc.rust-lang.org/libc/x86_64-unknown-linux-gnu/libc/index.html#types)
- in C and Rust, so they can't be passed using FFI.
-
- Tor currently uses the following Rust primitive types from libc for FFI:
- * defined-size integers: `uint32_t`
- * native-sized integers: `c_int`
- * native-sized floats: `c_double`
- * native-sized raw pointers: `* c_void`, `* c_char`, `** c_char`
-
- TODO: C smartlist to Stringlist conversion using FFI
-
- The only non-primitive type which may cross the FFI boundary is
- bytes, e.g. `&[u8]`. This SHOULD be done on the Rust side by
- passing a pointer (`*mut libc::c_char`). The length can be passed
- explicitly (`libc::size_t`), or the string can be NUL-byte terminated
- C string.
-
- One might be tempted to do this via doing
- `CString::new("blah").unwrap().into_raw()`. This has several problems:
-
- a) If you do `CString::new("bl\x00ah")` then the unwrap() will fail
- due to the additional NULL terminator, causing a dangling
- pointer to be returned (as well as a potential use-after-free).
-
- b) Returning the raw pointer will cause the CString to run its deallocator,
- which causes any C code which tries to access the contents to dereference a
- NULL pointer.
-
- c) If we were to do `as_raw()` this would result in a potential double-free
- since the Rust deallocator would run and possibly Tor's deallocator.
-
- d) Calling `into_raw()` without later using the same pointer in Rust to call
- `from_raw()` and then deallocate in Rust can result in a
- [memory leak](https://doc.rust-lang.org/std/ffi/struct.CString.html#method.into_raw).
-
- [It was determined](https://github.com/rust-lang/rust/pull/41074) that this
- is safe to do if you use the same allocator in C and Rust and also specify
- the memory alignment for CString (except that there is no way to specify
- the alignment for CString). It is believed that the alignment is always 1,
- which would mean it's safe to dealloc the resulting `*mut c_char` in Tor's
- C code. However, the Rust developers are not willing to guarantee the
- stability of, or a contract for, this behaviour, citing concerns that this
- is potentially extremely and subtly unsafe.
-
-4. Perform an allocation on the other side of the boundary
-
- After crossing the boundary, the other side MUST perform an
- allocation to copy the data and is therefore responsible for
- freeing that memory later.
-
-5. No touching other language's enums
-
- Rust enums should never be touched from C (nor can they be safely
- `#[repr(C)]`) nor vice versa:
-
- > "The chosen size is the default enum size for the target platform's C
- > ABI. Note that enum representation in C is implementation defined, so this is
- > really a "best guess". In particular, this may be incorrect when the C code
- > of interest is compiled with certain flags."
-
- (from https://gankro.github.io/nomicon/other-reprs.html)
-
-6. Type safety
-
- Wherever possible and sensical, you SHOULD create new types in a
- manner which prevents type confusion or misuse. For example,
- rather than using an untyped mapping between strings and integers
- like so:
-
- ```rust
- use std::collections::HashMap;
-
- pub fn get_elements_with_over_9000_points(map: &HashMap<String, usize>) -> Vec<String> {
- ...
- }
- ```
-
- It would be safer to define a new type, such that some other usage
- of `HashMap<String, usize>` cannot be confused for this type:
-
- ```rust
- pub struct DragonBallZPowers(pub HashMap<String, usize>);
-
- impl DragonBallZPowers {
- pub fn over_nine_thousand<'a>(&'a self) -> Vec<&'a String> {
- let mut powerful_enough: Vec<&'a String> = Vec::with_capacity(5);
-
- for (character, power) in &self.0 {
- if *power > 9000 {
- powerful_enough.push(character);
- }
- }
- powerful_enough
- }
- }
- ```
-
- Note the following code, which uses Rust's type aliasing, is valid
- but it does NOT meet the desired type safety goals:
-
- ```rust
- pub type Power = usize;
-
- pub fn over_nine_thousand(power: &Power) -> bool {
- if *power > 9000 {
- return true;
- }
- false
- }
-
- // We can still do the following:
- let his_power: usize = 9001;
- over_nine_thousand(&his_power);
- ```
-
-7. Unsafe mucking around with lifetimes
-
- Because lifetimes are technically, in type theory terms, a kind, i.e. a
- family of types, individual lifetimes can be treated as types. For example,
- one can arbitrarily extend and shorten lifetime using `std::mem::transmute`:
-
- ```rust
- struct R<'a>(&'a i32);
-
- unsafe fn extend_lifetime<'b>(r: R<'b>) -> R<'static> {
- std::mem::transmute::<R<'b>, R<'static>>(r)
- }
-
- unsafe fn shorten_invariant_lifetime<'b, 'c>(r: &'b mut R<'static>) -> &'b mut R<'c> {
- std::mem::transmute::<&'b mut R<'static>, &'b mut R<'c>>(r)
- }
- ```
-
- Calling `extend_lifetime()` would cause an `R` passed into it to live forever
- for the life of the program (the `'static` lifetime). Similarly,
- `shorten_invariant_lifetime()` could be used to take something meant to live
- forever, and cause it to disappear! This is incredibly unsafe. If you're
- going to be mucking around with lifetimes like this, first, you better have
- an extremely good reason, and second, you may as be honest and explicit about
- it, and for ferris' sake just use a raw pointer.
-
- In short, just because lifetimes can be treated like types doesn't mean you
- should do it.
-
-8. Doing excessively unsafe things when there's a safer alternative
-
- Similarly to #7, often there are excessively unsafe ways to do a task and a
- simpler, safer way. You MUST choose the safer option where possible.
-
- For example, `std::mem::transmute` can be abused in ways where casting with
- `as` would be both simpler and safer:
-
- ```rust
- // Don't do this
- let ptr = &0;
- let ptr_num_transmute = unsafe { std::mem::transmute::<&i32, usize>(ptr)};
-
- // Use an `as` cast instead
- let ptr_num_cast = ptr as *const i32 as usize;
- ```
-
- In fact, using `std::mem::transmute` for *any* reason is a code smell and as
- such SHOULD be avoided.
-
-9. Casting integers with `as`
-
- This is generally fine to do, but it has some behaviours which you should be
- aware of. Casting down chops off the high bits, e.g.:
-
- ```rust
- let x: u32 = 4294967295;
- println!("{}", x as u16); // prints 65535
- ```
-
- Some cases which you MUST NOT do include:
-
- * Casting an `u128` down to an `f32` or vice versa (e.g.
- `u128::MAX as f32` but this isn't only a problem with overflowing
- as it is also undefined behaviour for `42.0f32 as u128`),
-
- * Casting between integers and floats when the thing being cast
- cannot fit into the type it is being casted into, e.g.:
-
- ```rust
- println!("{}", 42949.0f32 as u8); // prints 197 in debug mode and 0 in release
- println!("{}", 1.04E+17 as u8); // prints 0 in both modes
- println!("{}", (0.0/0.0) as i64); // prints whatever the heck LLVM wants
- ```
-
- Because this behaviour is undefined, it can even produce segfaults in
- safe Rust code. For example, the following program built in release
- mode segfaults:
-
- ```rust
- #[inline(never)]
- pub fn trigger_ub(sl: &[u8; 666]) -> &[u8] {
- // Note that the float is out of the range of `usize`, invoking UB when casting.
- let idx = 1e99999f64 as usize;
- &sl[idx..] // The bound check is elided due to `idx` being of an undefined value.
- }
-
- fn main() {
- println!("{}", trigger_ub(&[1; 666])[999999]); // ~ out of bound
- }
- ```
-
- And in debug mode panics with:
-
- thread 'main' panicked at 'slice index starts at 140721821254240 but ends at 666', /checkout/src/libcore/slice/mod.rs:754:4
diff --git a/doc/HACKING/GettingStarted.md b/doc/HACKING/GettingStarted.md
index 6d61be9881..271e2d7517 100644
--- a/doc/HACKING/GettingStarted.md
+++ b/doc/HACKING/GettingStarted.md
@@ -41,7 +41,7 @@ Once you've reached this point, here's what you need to know.
$ git clone https://git.torproject.org/git/tor
```
- This will give you a checkout of the master branch. If you're
+ This will give you a checkout of the main branch. If you're
going to fix a bug that appears in a stable version, check out the
appropriate "maint" branch, as in:
diff --git a/doc/HACKING/GettingStartedRust.md b/doc/HACKING/GettingStartedRust.md
deleted file mode 100644
index beef825226..0000000000
--- a/doc/HACKING/GettingStartedRust.md
+++ /dev/null
@@ -1,187 +0,0 @@
-# Hacking on Rust in Tor
-
-## Getting Started
-
-Please read or review our documentation on Rust coding standards
-(`doc/HACKING/CodingStandardsRust.md`) before doing anything.
-
-Please also read
-[the Rust Code of Conduct](https://www.rust-lang.org/en-US/conduct.html). We
-aim to follow the good example set by the Rust community and be
-excellent to one another. Let's be careful with each other, so we can
-be memory-safe together!
-
-Next, please contact us before rewriting anything! Rust in Tor is still
-an experiment. It is an experiment that we very much want to see
-succeed, so we're going slowly and carefully. For the moment, it's also
-a completely volunteer-driven effort: while many, if not most, of us are
-paid to work on Tor, we are not yet funded to write Rust code for Tor.
-Please be patient with the other people who are working on getting more
-Rust code into Tor, because they are graciously donating their free time
-to contribute to this effort.
-
-## Resources for learning Rust
-
-**Beginning resources**
-
-The primary resource for learning Rust is
-[The Book](https://doc.rust-lang.org/book/). If you'd like to start writing
-Rust immediately, without waiting for anything to install, there is
-[an interactive browser-based playground](https://play.rust-lang.org/).
-
-**Advanced resources**
-
-If you're interested in playing with various Rust compilers and viewing
-a very nicely displayed output of the generated assembly, there is
-[the Godbolt compiler explorer](https://rust.godbolt.org/)
-
-For learning how to write unsafe Rust, read
-[The Rustonomicon](https://doc.rust-lang.org/nomicon/).
-
-For learning everything you ever wanted to know about Rust macros, there
-is
-[The Little Book of Rust Macros](https://danielkeep.github.io/tlborm/book/index.html).
-
-For learning more about FFI and Rust, see Jake Goulding's
-[Rust FFI Omnibus](https://jakegoulding.com/rust-ffi-omnibus/).
-
-## Compiling Tor with Rust enabled
-
-You will need to run the `configure` script with the `--enable-rust`
-flag to explicitly build with Rust. Additionally, you will need to
-specify where to fetch Rust dependencies, as we allow for either
-fetching dependencies from Cargo or specifying a local directory.
-
-**Fetch dependencies from Cargo**
-
-```console
-$ ./configure --enable-rust --enable-cargo-online-mode
-```
-
-**Using a local dependency cache**
-
-You'll need the following Rust dependencies (as of this writing):
-
- libc==0.2.39
-
-We vendor our Rust dependencies in a separate repo using
-[cargo-vendor](https://github.com/alexcrichton/cargo-vendor). To use
-them, do:
-
-```console
-$ git submodule init
-$ git submodule update
-```
-
-To specify the local directory containing the dependencies, (assuming
-you are in the top level of the repository) configure tor with:
-
-```console
-$ TOR_RUST_DEPENDENCIES='path_to_dependencies_directory' ./configure --enable-rust
-```
-
-(Note that `TOR_RUST_DEPENDENCIES` must be the full path to the directory; it
-cannot be relative.)
-
-Assuming you used the above `git submodule` commands and you're in the
-topmost directory of the repository, this would be:
-
-```console
-$ TOR_RUST_DEPENDENCIES=`pwd`/src/ext/rust/crates ./configure --enable-rust
-```
-
-## Identifying which modules to rewrite
-
-The places in the Tor codebase that are good candidates for porting to
-Rust are:
-
-1. loosely coupled to other Tor submodules,
-2. have high test coverage, and
-3. would benefit from being implemented in a memory safe language.
-
-Help in either identifying places such as this, or working to improve
-existing areas of the C codebase by adding regression tests and
-simplifying dependencies, would be really helpful.
-
-Furthermore, as submodules in C are implemented in Rust, this is a good
-opportunity to refactor, add more tests, and split modules into smaller
-areas of responsibility.
-
-A good first step is to build a module-level callgraph to understand how
-interconnected your target module is.
-
-```console
-$ git clone https://git.torproject.org/user/nickm/calltool.git
-$ cd tor
-$ CFLAGS=0 ./configure
-$ ../calltool/src/main.py module_callgraph
-```
-
-The output will tell you each module name, along with a set of every module that
-the module calls. Modules which call fewer other modules are better targets.
-
-## Writing your Rust module
-
-Strive to change the C API as little as possible.
-
-We are currently targeting Rust stable. (See `CodingStandardsRust.md` for more
-details.)
-
-It is on our TODO list to try to cultivate good
-standing with various distro maintainers of `rustc` and `cargo`, in
-order to ensure that whatever version we solidify on is readily
-available.
-
-If parts of your Rust code needs to stay in sync with C code (such as
-handling enums across the FFI boundary), annonotate these places in a
-comment structured as follows:
-
- `/// C_RUST_COUPLED: <path_to_file> <name_of_c_object>`
-
-Where `<name_of_c_object>` can be an enum, struct, constant, etc. Then,
-do the same in the C code, to note that rust will need to be changed
-when the C does.
-
-## Adding your Rust module to Tor's build system
-
-0. Your translation of the C module should live in its own crate(s)
- in the `src/rust/` directory.
-1. Add your crate to `src/rust/Cargo.toml`, in the
- `[workspace.members]` section.
-2. Add your crate's files to src/rust/include.am
-
-If your crate should be available to C (rather than just being included as a
-dependency of other Rust modules):
-0. Declare the crate as a dependency of tor_rust in
- `src/rust/tor_util/Cargo.toml` and include it in
- `src/rust/tor_rust/lib.rs`
-
-## How to test your Rust code
-
-Everything should be tested full stop. Even non-public functionality.
-
-Be sure to edit `src/test/test_rust.sh` to add the name of your
-crate to the `crates` variable! This will ensure that `cargo test` is
-run on your crate.
-
-Configure Tor's build system to build with Rust enabled:
-
-```console
-$ ./configure --enable-fatal-warnings --enable-rust --enable-cargo-online-mode
-```
-
-Tor's test should be run by doing:
-
-```console
-$ make check
-```
-
-Tor's integration tests should also pass:
-
-```console
-$ make test-stem
-```
-
-## Submitting a patch
-
-Please follow the instructions in `doc/HACKING/GettingStarted.md`.
diff --git a/doc/HACKING/HelpfulTools.md b/doc/HACKING/HelpfulTools.md
index 0ce59576f0..7849fc67c7 100644
--- a/doc/HACKING/HelpfulTools.md
+++ b/doc/HACKING/HelpfulTools.md
@@ -33,8 +33,8 @@ OFTC. If they don't, ask #tor-dev (also on OFTC).
It's CI/builders. Looks like this: https://jenkins.torproject.org
Runs automatically on commits merged to git.torproject.org. We CI the
-master branch and all supported tor versions. We also build nightly debian
-packages from master.
+main branch and all supported tor versions. We also build nightly debian
+packages from main.
Builds Linux and Windows cross-compilation. Runs Linux tests.
diff --git a/doc/HACKING/Maintaining.md b/doc/HACKING/Maintaining.md
index 4d5a7f6b76..267f6d0b58 100644
--- a/doc/HACKING/Maintaining.md
+++ b/doc/HACKING/Maintaining.md
@@ -7,7 +7,7 @@ The first section describes who is the current Tor maintainer and what are the
responsibilities. Tor has one main single maintainer but does have many
committers and subsystem maintainers.
-The second third section describes how the **alpha and master** branches are
+The second third section describes how the **alpha and main** branches are
maintained and by whom.
Finally, the last section describes how the **stable** branches are maintained
@@ -25,7 +25,7 @@ protocol design. Releasing Tor falls under their responsibility.
## Alpha and Master Branches
-The Tor repository always has at all times a **master** branch which contains
+The Tor repository always has at all times a **main** branch which contains
the upstream ongoing development.
It may also contain a branch for a released feature freezed version which is
@@ -37,7 +37,7 @@ Tor is separated into subsystems and some of those are maintained by other
developers than the main maintainer. Those people have commit access to the
code base but only commit (in most cases) into the subsystem they maintain.
-Upstream merges are restricted to the alpha and master branches. Subsystem
+Upstream merges are restricted to the alpha and main branches. Subsystem
maintainers should never push a patch into a stable branch which is the
responsibility of the [stable branch maintainer](#stable-branches).
@@ -69,7 +69,7 @@ maintain the following subsystems:
These are the tasks of a subsystem maintainer:
1. Regularly go over `merge_ready` tickets relevant to the related subsystem
- and for the current alpha or development (master branch) Milestone.
+ and for the current alpha or development (main branch) Milestone.
2. A subsystem maintainer is expected to contribute to any design changes
(including proposals) or large patch set about the subsystem.
@@ -102,7 +102,7 @@ These are few important items to follow when merging code upstream:
4. Tor uses the "merge forward" method, that is, if a patch applies to the
alpha branch, it has to be merged there first and then merged forward
- into master.
+ into main.
5. Maintainer should always consult with the network team about any doubts,
mis-understandings or unknowns of a patch. Final word will always go to the
diff --git a/doc/HACKING/README.1st.md b/doc/HACKING/README.1st.md
index 4bc3298c67..1c0decf9ce 100644
--- a/doc/HACKING/README.1st.md
+++ b/doc/HACKING/README.1st.md
@@ -5,12 +5,11 @@
This directory has helpful information about what you need to know to
hack on Tor!
-First, read `GettingStarted.md` and `GettingStartedRust.md`
-to learn how to get a start in Tor development.
+First, read `GettingStarted.md` to learn how to get a start in Tor
+development.
-If you've decided to write a patch, `CodingStandards.md` and
-`CodingStandardsRust.md` will give you a bunch of information
-about how we structure our code.
+If you've decided to write a patch, `CodingStandards.md` will give you a bunch
+of information about how we structure our code.
It's important to get the code right! Reading `WritingTests.md` will
tell you how to write and run tests in the Tor codebase.
@@ -36,6 +35,13 @@ For the latest version of the code, get a copy of git, and
$ git clone https://git.torproject.org/git/tor
```
+For a copy of Tor's original design paper, see
+[here](https://spec.torproject.org/tor-design). Note that Tor has changed in
+many ways since 2004.
+
+For a large collection of security papers, many of which are related to Tor,
+see [Anonbib's Selected Papers in Anonymity](https://www.freehaven.net/anonbib/).
+
## Stay in touch
We talk about Tor on the `tor-talk` mailing list. Design proposals and
diff --git a/doc/HACKING/ReleaseSeriesLifecycle.md b/doc/HACKING/ReleaseSeriesLifecycle.md
index 8536fbbd08..e47ac90fa5 100644
--- a/doc/HACKING/ReleaseSeriesLifecycle.md
+++ b/doc/HACKING/ReleaseSeriesLifecycle.md
@@ -87,17 +87,17 @@ they do not apply to security-related patch release versions.
(Ideally, do this immediately after a release.)
-1. Start a new maint-x.y.z branch based on master, and a new
- release-x.y.z branch based on master. They should have the same
+1. Start a new maint-x.y.z branch based on main, and a new
+ release-x.y.z branch based on main. They should have the same
starting point.
- Push both of these branches to the master git repository.
+ Push both of these branches to the canonical git repository.
-2. In master, change the version to "0.x.y.0-alpha-dev". Run the
+2. In the main branch, change the version to "0.x.y.0-alpha-dev". Run the
update_versions.py script, and commit this version bump.
3. Tag the version bump with "tor-0.x.y.0-alpha-dev". Push the tag
- and master.
+ and main branch.
4. Open tickets for connecting the new branches to various other
places. See section 2 above for a list of affected locations.
@@ -107,7 +107,7 @@ they do not apply to security-related patch release versions.
target in the maint-x.y.z branch only.
* Delete the file scripts/maint/practracker/.enable_practracker_in_hooks
in the maint-x.y.z branch only.
- * Merge to release-x.y.z, but do not forward-port to master.
+ * Merge to release-x.y.z, but do not forward-port to the main branch.
6. Finally, make sure this document is up to date with our latest
process.
diff --git a/doc/HACKING/ReleasingTor.md b/doc/HACKING/ReleasingTor.md
index 739ea38795..86feef754e 100644
--- a/doc/HACKING/ReleasingTor.md
+++ b/doc/HACKING/ReleasingTor.md
@@ -1,234 +1,147 @@
-# Putting out a new release
+# How to Release Tor
Here are the steps that the maintainer should take when putting out a
-new Tor release:
+new Tor release. It is split in 3 stages and coupled with our Tor CI Release
+pipeline.
-## 0. Preliminaries
+Before we begin, first rule is to make sure:
-1. Get at least two of weasel/arma/Sebastian to put the new
- version number in their approved versions list. Give them a few
- days to do this if you can.
+ - Our CIs (*nix and Windows) pass for each version to release
+ - Coverity has no new alerts
-2. If this is going to be an important security release, give these packagers
- some advance warning:
+## 0. Security Release
- - {weasel,sysrqb,mikeperry} at torproject dot org
- - {blueness} at gentoo dot org
- - {paul} at invizbox dot io
- - {vincent} at invizbox dot com
- - {lfleischer} at archlinux dot org
- - {Nathan} at freitas dot net
- - {mike} at tig dot as
- - {tails-rm} at boum dot org
- - {simon} at sdeziel.info
- - {yuri} at freebsd.org
- - {mh+tor} at scrit.ch
- - {security} at brave.com
-
-3. Given the release date for Tor, ask the TB team about the likely release
- date of a TB that contains it. See note below in "commit, upload,
- announce".
-
-## I. Make sure it works
-
-1. Make sure that CI passes: have a look at Travis
- (https://travis-ci.org/torproject/tor/branches), Appveyor
- (https://ci.appveyor.com/project/torproject/tor/history), and
- Jenkins (https://jenkins.torproject.org/view/tor/).
- Make sure you're looking at the right branches.
-
- If there are any unexplained failures, try to fix them or figure them
- out.
-
-2. Verify that there are no big outstanding issues. You might find such
- issues --
-
- * On Trac
-
- * On coverity scan
-
- * On OSS-Fuzz
-
-## II. Write a changelog
+To start with, if you are doing a security release, this must be done few days
+prior to the release:
-1a. (Alpha release variant)
+ 1. If this is going to be an important security release, give the packagers
+ advance warning, via `tor-packagers@lists.torproject.org`.
- Gather the `changes/*` files into a changelog entry, rewriting many
- of them and reordering to focus on what users and funders would find
- interesting and understandable.
- To do this, run `./scripts/maint/sortChanges.py changes/* > changelog.in`
- to combine headings and sort the entries. Copy the changelog.in file into
- the ChangeLog. Run `format_changelog.py --inplace` (see below) to clean up
- the line breaks.
+## 1. Preliminaries
- Remove the `changes/*` files that you just merged into the ChangeLog.
+The following must be done **2 days** at the very least prior to the release:
- After that, it's time to hand-edit and fix the issues that
- lintChanges can't find:
+ 1. Add the version(s) in the dirauth-conf git repository as the
+ RecommendedVersion and RequiredVersion so they can be approved by the
+ authorities and be in the consensus before the release.
- 1. Within each section, sort by "version it's a bugfix on", else by
- numerical ticket order.
+ 2. Send a pre-release announcement to `tor-project@lists.torproject.org` in
+ order to inform every teams in Tor of the upcoming release. This is so
+ we can avoid creating release surprises and sync with other teams.
- 2. Clean them up:
+ 3. Ask the network-team to review the `changes/` files in all versions we
+ are about to release. This step is encouraged but not mandatory.
- Make stuff very terse
- Describe the user-visible problem right away
+## 2. Tarballs
- Mention relevant config options by name. If they're rare or unusual,
- remind people what they're for
+To build the tarballs to release, we need to launch the CI release pipeline:
- Avoid starting lines with open-paren
+ https://gitlab.torproject.org/tpo/core/tor-ci-release
- Present and imperative tense: not past.
+The `versions.yml` needs to be modified with the Tor versions you want to
+release. Once done, git commit and push to trigger the release pipeline.
- "Relays", not "servers" or "nodes" or "Tor relays".
+The first two stages (Preliminary and Patches) will be run automatically. The
+Build stage needs to be triggered manually once all generated patches have
+been merged upstream.
- "Onion services", not "hidden services".
+ 1. Download the generated patches from the `Patches` stage.
- "Stop FOOing", not "Fix a bug where we would FOO".
+ 2. For the ChangeLog and ReleaseNotes, you need to write a blurb at the top
+ explaining a bit the release.
- Try not to let any given section be longer than about a page. Break up
- long sections into subsections by some sort of common subtopic. This
- guideline is especially important when organizing Release Notes for
- new stable releases.
+ 3. Review, modify if needed, and merged them upstream.
- If a given changes stanza showed up in a different release (e.g.
- maint-0.2.1), be sure to make the stanzas identical (so people can
- distinguish if these are the same change).
+ 4. Manually trigger the `maintained` job in the `Build` stage so the CI can
+ build the tarballs without errors.
- 3. Clean everything one last time.
+Once this is done, each selected developers need to build the tarballs in a
+reproducible way using:
- 4. Run `./scripts/maint/format_changelog.py --inplace` to make it prettier
+ https://gitlab.torproject.org/tpo/core/tor-ci-reproducible
-1b. (old-stable release variant)
+Steps are:
- For stable releases that backport things from later, we try to compose
- their releases, we try to make sure that we keep the changelog entries
- identical to their original versions, with a "backport from 0.x.y.z"
- note added to each section. So in this case, once you have the items
- from the changes files copied together, don't use them to build a new
- changelog: instead, look up the corrected versions that were merged
- into ChangeLog in the master branch, and use those.
+ 1. Run `./build.sh` which will download everything you need, including the
+ latest tarballs from the release CI, and auto-commit the signatures if
+ the checksum match. You will need to confim the commits.
- Add "backport from X.Y.Z" in the section header for these entries.
+ 2. If all is good, `git push origin main` your signatures.
-2. Compose a short release blurb to highlight the user-facing
- changes. Insert said release blurb into the ChangeLog stanza. If it's
- a stable release, add it to the ReleaseNotes file too. If we're adding
- to a release-* branch, manually commit the changelogs to the later
- git branches too.
+Once all signatures from all selected developers have been committed:
-3. If there are changes that require or suggest operator intervention
- before or during the update, mail operators (either dirauth or relays
- list) with a headline that indicates that an action is required or
- appreciated.
+ 1. Manually trigger the `signature` job in the `Post-process` stage of the
+ CI release pipeline.
-4. If you're doing the first stable release in a series, you need to
- create a ReleaseNotes for the series as a whole. To get started
- there, copy all of the Changelog entries from the series into a new
- file, and run `./scripts/maint/sortChanges.py` on it. That will
- group them by category. Then kill every bugfix entry for fixing
- bugs that were introduced within that release series; those aren't
- relevant changes since the last series. At that point, it's time
- to start sorting and condensing entries. (Generally, we don't edit the
- text of existing entries, though.)
+ 2. If it passes, the tarball(s) and signature(s) will be available as
+ artifacts and should be used for the release.
-## III. Making the source release.
+ 3. Put them on `dist.torproject.org`:
-1. In `maint-0.?.x`, bump the version number in `configure.ac` and run
- `make update-versions` to update version numbers in other
- places, and commit. Then merge `maint-0.?.x` into `release-0.?.x`.
+ Upload the tarball and its sig to the dist website, i.e.
+ `/srv/dist-master.torproject.org/htdocs/` on dist-master. Run
+ "static-update-component dist.torproject.org" on dist-master.
- When you merge the maint branch forward to the next maint branch, or into
- master, merge it with "-s ours" to avoid conflict with the version
- bump.
+ In the `project/web/tpo.git` repository, update `databags/versions.ini`
+ to note the new version. Push these changes to `master`.
-2. Make distcheck, put the tarball up in somewhere (how about your
- homedir on people.torproject.org?) , and tell `#tor-dev`
- about it.
+ (NOTE: Due to #17805, there can only be one stable version listed at once.
+ Nonetheless, do not call your version "alpha" if it is stable, or people
+ will get confused.)
- If you want, wait until at least one person has built it
- successfully. (We used to say "wait for others to test it", but our
- CI has successfully caught these kinds of errors for the last several
- years.)
+ (NOTE: It will take a while for the website update scripts to update the
+ website.)
-3. Make sure that the new version is recommended in the latest consensus.
- (Otherwise, users will get confused when it complains to them
- about its status.)
- If it is not, you'll need to poke Roger, Weasel, and Sebastian again: see
- item 0.1 at the start of this document.
+## 3. Post Process
-## IV. Commit, upload, announce
+Once the tarballs have been uploaded and are ready to be announced, we need to
+do the following:
-1. Sign the tarball, then sign and push the git tag:
+ 1. Tag versions (main and maint) using `git tag -s tor-0.x.y.z-<status>`
+ and then push the tags: `git push origin --tags`
-```console
-$ gpg -ba <the_tarball>
-$ git tag -s tor-0.4.x.y-<status>
-$ git push origin tag tor-0.4.x.y-<status>
-```
+ 2. Merge upstream the artifacts from the `patches` job in the
+ `Post-process` stage of the CI release pipeline.
- (You must do this before you update the website: the website scripts
- rely on finding the version by tag.)
+ 3. Write and post the release announcement for the `forum.torproject.net`
+ in the `News -> Tor Release Announcement` category.
- (If your default PGP key is not the one you want to sign with, then say
- "-u <keyid>" instead of "-s".)
+ If possible, mention in which Tor Browser version (with dates) the
+ release will be in. This usually only applies to the latest stable.
-2. scp the tarball and its sig to the dist website, i.e.
- `/srv/dist-master.torproject.org/htdocs/` on dist-master. Run
- "static-update-component dist.torproject.org" on dist-master.
+ 4. Inform `tor-talk@lists.torproject.org` with the releasing pointing to
+ the Forum. Append the ChangeLog there. We do this until we can automate
+ such post from the forum directly.
- In the project/web/tpo.git repository, update `databags/versions.ini`
- to note the new version. Push these changes to master.
+### New Stable
- (NOTE: Due to #17805, there can only be one stable version listed at
- once. Nonetheless, do not call your version "alpha" if it is stable,
- or people will get confused.)
+ 1. Create the `maint-x.y.z` and `release-x.y.z` branches and update the
+ `./scripts/git/git-list-tor-branches.sh` with the new version.
- (NOTE: It will take a while for the website update scripts to update
- the website.)
+ 2. Add the new version in `./scripts/ci/ci-driver.sh`.
-3. Email the tor-packagers@lists.torproject.org mailing list to tell them
- about the new release.
+ 3. Forward port the ChangeLog and ReleaseNotes into main branch. Remove any
+ change logs of stable releases in ReleaseNotes.
- Also, email tor-packagers@lists.torproject.org.
- Mention where to download the tarball (https://dist.torproject.org).
+## Appendix: An alternative means to notify packagers
- Include a link to the changelog.
+If for some reason you need to contact a bunch of packagers without
+using the publicly archived tor-packagers list, you can try these
+people:
-4. Wait for the download page to be updated. (If you don't do this before you
- announce, people will be confused.)
-
-5. Mail the release blurb and ChangeLog to tor-talk (development release) or
- tor-announce (stable).
-
- Post the changelog on the blog as well. You can generate a
- blog-formatted version of the changelog with
- `./scripts/maint/format_changelog.py -B`
-
- When you post, include an estimate of when the next TorBrowser
- releases will come out that include this Tor release. This will
- usually track https://wiki.mozilla.org/RapidRelease/Calendar , but it
- can vary.
-
- For templates to use when announcing, see:
- https://gitlab.torproject.org/tpo/core/team/-/wikis/NetworkTeam/AnnouncementTemplates
-
-## V. Aftermath and cleanup
-
-1. If it's a stable release, bump the version number in the
- `maint-x.y.z` branch to "newversion-dev", and do a `merge -s ours`
- merge to avoid taking that change into master.
-
-2. If there is a new `maint-x.y.z` branch, create a Travis CI cron job that
- builds the release every week. (It's ok to skip the weekly build if the
- branch was updated in the last 24 hours.)
-
-3. Forward-port the ChangeLog (and ReleaseNotes if appropriate) to the
- master branch.
-
-4. Keep an eye on the blog post, to moderate comments and answer questions.
+ - {weasel,sysrqb,mikeperry} at torproject dot org
+ - {blueness} at gentoo dot org
+ - {paul} at invizbox dot io
+ - {vincent} at invizbox dot com
+ - {lfleischer} at archlinux dot org
+ - {Nathan} at freitas dot net
+ - {mike} at tig dot as
+ - {tails-rm} at boum dot org
+ - {simon} at sdeziel.info
+ - {yuri} at freebsd.org
+ - {mh+tor} at scrit.ch
+ - {security} at brave.com
diff --git a/doc/HACKING/ReleasingTor.md.old b/doc/HACKING/ReleasingTor.md.old
new file mode 100644
index 0000000000..490c100fcb
--- /dev/null
+++ b/doc/HACKING/ReleasingTor.md.old
@@ -0,0 +1,255 @@
+# CHECKLIST
+
+Here's a summary checklist, with the things that Nick messes up most often.
+
+Did you:
+
+ * [ ] Copy the ChangeLog to the ReleaseNotes?
+ * [ ] Check that the new versions got approved?
+ * [ ] Check the release date in the ChangeLog?
+ * [ ] Update the GeoIP file?
+
+# Putting out a new release
+
+Here are the steps that the maintainer should take when putting out a
+new Tor release:
+
+## 0. Preliminaries
+
+1. Get at least three of weasel/arma/Sebastian/Sina to put the new
+ version number in their approved versions list. Give them a few
+ days to do this if you can.
+
+2. If this is going to be an important security release, give the packagers
+ advance warning, via `tor-packagers@lists.torproject.org`.
+
+
+3. Given the release date for Tor, ask the TB team about the likely release
+ date of a TB that contains it. See note below in "commit, upload,
+ announce".
+
+## I. Make sure it works
+
+1. Make sure that CI passes: have a look at the branches on gitlab.
+
+ _Optionally_, have a look at Travis
+ (https://travis-ci.org/torproject/tor/branches), Appveyor
+ (https://ci.appveyor.com/project/torproject/tor/history), and
+ Jenkins (https://jenkins.torproject.org/view/tor/).
+ Make sure you're looking at the right branches.
+
+ If there are any unexplained failures, try to fix them or figure them
+ out.
+
+2. Verify that there are no big outstanding issues. You might find such
+ issues --
+
+ * On Gitlab
+
+ * On coverity scan
+
+ * On OSS-Fuzz
+
+## II. Write a changelog
+
+
+1a. (Alpha release variant)
+
+ Gather the `changes/*` files into a changelog entry, rewriting many
+ of them and reordering to focus on what users and funders would find
+ interesting and understandable.
+
+ To do this, run `./scripts/maint/sortChanges.py changes/* > changelog.in`
+ to combine headings and sort the entries. Copy the changelog.in file into
+ the ChangeLog. Run `format_changelog.py --inplace` (see below) to clean up
+ the line breaks.
+
+ Remove the `changes/*` files that you just merged into the ChangeLog.
+
+ After that, it's time to hand-edit and fix the issues that
+ lintChanges can't find:
+
+ 1. Within each section, sort by "version it's a bugfix on", else by
+ numerical ticket order.
+
+ 2. Clean them up:
+
+ Make stuff very terse
+
+ Describe the user-visible problem right away
+
+ Mention relevant config options by name. If they're rare or unusual,
+ remind people what they're for
+
+ Avoid starting lines with open-paren
+
+ Present and imperative tense: not past.
+
+ "Relays", not "servers" or "nodes" or "Tor relays".
+
+ "Onion services", not "hidden services".
+
+ "Stop FOOing", not "Fix a bug where we would FOO".
+
+ Try not to let any given section be longer than about a page. Break up
+ long sections into subsections by some sort of common subtopic. This
+ guideline is especially important when organizing Release Notes for
+ new stable releases.
+
+ If a given changes stanza showed up in a different release (e.g.
+ maint-0.2.1), be sure to make the stanzas identical (so people can
+ distinguish if these are the same change).
+
+ 3. Clean everything one last time.
+
+ 4. Run `./scripts/maint/format_changelog.py --inplace` to make it prettier
+
+1b. (old-stable release variant)
+
+ For stable releases that backport things from later, we try to compose
+ their releases, we try to make sure that we keep the changelog entries
+ identical to their original versions, with a "backport from 0.x.y.z"
+ note added to each section. So in this case, once you have the items
+ from the changes files copied together, don't use them to build a new
+ changelog: instead, look up the corrected versions that were merged
+ into ChangeLog in the main branch, and use those.
+
+ Add "backport from X.Y.Z" in the section header for these entries.
+
+2. Compose a short release blurb to highlight the user-facing
+ changes. Insert said release blurb into the ChangeLog stanza. If it's
+ a stable release, add it to the ReleaseNotes file too. If we're adding
+ to a release-* branch, manually commit the changelogs to the later
+ git branches too.
+
+3. If there are changes that require or suggest operator intervention
+ before or during the update, mail operators (either dirauth or relays
+ list) with a headline that indicates that an action is required or
+ appreciated.
+
+4. If you're doing the first stable release in a series, you need to
+ create a ReleaseNotes for the series as a whole. To get started
+ there, copy all of the Changelog entries from the series into a new
+ file, and run `./scripts/maint/sortChanges.py` on it. That will
+ group them by category. Then kill every bugfix entry for fixing
+ bugs that were introduced within that release series; those aren't
+ relevant changes since the last series. At that point, it's time
+ to start sorting and condensing entries. (Generally, we don't edit the
+ text of existing entries, though.)
+
+## III. Making the source release.
+
+1. In `maint-0.?.x`, bump the version number in `configure.ac` and run
+ `./scripts/main/update_versions.py` to update version numbers in other
+ places, and commit. Then merge `maint-0.?.x` into `release-0.?.x`.
+
+ When you merge the maint branch forward to the next maint branch, or into
+ main, merge it with `-s ours` to avoid conflict with the version
+ bump.
+
+2. In `release-0.?.x`, run `make distcheck`, put the tarball up in somewhere
+ (how about your homedir on people.torproject.org?) , and tell `#tor-dev`
+ about it.
+
+ If you want, wait until at least one person has built it
+ successfully. (We used to say "wait for others to test it", but our
+ CI has successfully caught these kinds of errors for the last several
+ years.)
+
+3. Make sure that the new version is recommended in the latest consensus.
+ (Otherwise, users will get confused when it complains to them
+ about its status.)
+
+ If it is not, you'll need to poke Roger, Weasel, Sebastian, and Sina
+ again: see the note at the start of the document.
+
+## IV. Commit, upload, announce
+
+1. Sign the tarball, then sign and push the git tag:
+
+```console
+$ gpg -ba <the_tarball>
+$ git tag -s tor-0.4.x.y-<status>
+$ git push origin tag tor-0.4.x.y-<status>
+```
+
+ (You must do this before you update the website: the website scripts
+ rely on finding the version by tag.)
+
+ (If your default PGP key is not the one you want to sign with, then say
+ "-u <keyid>" instead of "-s".)
+
+2. scp the tarball and its sig to the dist website, i.e.
+ `/srv/dist-master.torproject.org/htdocs/` on dist-master. Run
+ "static-update-component dist.torproject.org" on dist-master.
+
+ In the `project/web/tpo.git` repository, update `databags/versions.ini`
+ to note the new version. Push these changes to `master`.
+
+ (NOTE: Due to #17805, there can only be one stable version listed at
+ once. Nonetheless, do not call your version "alpha" if it is stable,
+ or people will get confused.)
+
+ (NOTE: It will take a while for the website update scripts to update
+ the website.)
+
+3. Email the tor-packagers@lists.torproject.org mailing list to tell them
+ about the new release.
+
+ Also, email tor-packagers@lists.torproject.org.
+
+ Mention where to download the tarball (`https://dist.torproject.org/`).
+
+ Include a link to the changelog.
+
+4. Wait for the download page to be updated. (If you don't do this before you
+ announce, people will be confused.)
+
+5. Mail the release blurb and ChangeLog to tor-talk (development release) or
+ tor-announce (stable).
+
+ Post the changelog on the blog as well. You can generate a
+ blog-formatted version of the changelog with
+ `./scripts/maint/format_changelog.py -B`
+
+ When you post, include an estimate of when the next TorBrowser
+ releases will come out that include this Tor release. This will
+ usually track https://wiki.mozilla.org/RapidRelease/Calendar , but it
+ can vary.
+
+ For templates to use when announcing, see:
+ https://gitlab.torproject.org/tpo/core/team/-/wikis/NetworkTeam/AnnouncementTemplates
+
+## V. Aftermath and cleanup
+
+1. If it's a stable release, bump the version number in the
+ `maint-x.y.z` branch to "newversion-dev", and do a `merge -s ours`
+ merge to avoid taking that change into main.
+
+2. If there is a new `maint-x.y.z` branch, create a Travis CI cron job that
+ builds the release every week. (It's ok to skip the weekly build if the
+ branch was updated in the last 24 hours.)
+
+3. Forward-port the ChangeLog (and ReleaseNotes if appropriate) to the
+ main branch.
+
+4. Keep an eye on the blog post, to moderate comments and answer questions.
+
+## Appendix: An alternative means to notify packagers
+
+If for some reason you need to contact a bunch of packagers without
+using the publicly archived tor-packagers list, you can try these
+people:
+
+ - {weasel,sysrqb,mikeperry} at torproject dot org
+ - {blueness} at gentoo dot org
+ - {paul} at invizbox dot io
+ - {vincent} at invizbox dot com
+ - {lfleischer} at archlinux dot org
+ - {Nathan} at freitas dot net
+ - {mike} at tig dot as
+ - {tails-rm} at boum dot org
+ - {simon} at sdeziel.info
+ - {yuri} at freebsd.org
+ - {mh+tor} at scrit.ch
+ - {security} at brave.com
diff --git a/doc/asciidoc-helper.sh b/doc/asciidoc-helper.sh
index 3706ca2e14..98e216e68a 100755
--- a/doc/asciidoc-helper.sh
+++ b/doc/asciidoc-helper.sh
@@ -9,7 +9,7 @@
set -e
if [ $# != 3 ]; then
- exit 1;
+ exit 1
fi
SOURCE_DATE_EPOCH="$(git show --no-patch --format='%ct')"
@@ -22,50 +22,49 @@ if [ "$1" = "html" ]; then
base=${output%%.html.in}
if [ "$2" != none ]; then
- TZ=UTC "$2" -f "$(dirname "$0")/nofooter.conf" -d manpage -o "$output" "$input";
+ TZ=UTC "$2" -f "$(dirname "$0")/nofooter.conf" -d manpage -o "$output" "$input";
else
- echo "==================================";
- echo;
- echo "You need asciidoc installed to be able to build the manpage.";
- echo "To build without manpages, use the --disable-asciidoc argument";
- echo "when calling configure.";
- echo;
- echo "==================================";
- exit 1;
+ echo "=================================="
+ echo
+ echo "You need asciidoc installed to be able to build the manpage."
+ echo "To build without manpages, use the --disable-asciidoc argument"
+ echo "when calling configure."
+ echo
+ echo "=================================="
+ exit 1
fi
elif [ "$1" = "man" ]; then
input=${output%%.1.in}.1.txt
base=${output%%.1.in}
if test "$2" = none; then
- echo "==================================";
- echo;
- echo "You need asciidoc installed to be able to build the manpage.";
- echo "To build without manpages, use the --disable-asciidoc argument";
- echo "when calling configure.";
- echo;
- echo "==================================";
- exit 1;
+ echo "=================================="
+ echo
+ echo "You need asciidoc installed to be able to build the manpage."
+ echo "To build without manpages, use the --disable-asciidoc argument"
+ echo "when calling configure."
+ echo
+ echo "=================================="
+ exit 1
fi
if "$2" -f manpage "$input"; then
- mv "$base.1" "$output";
+ mv "$base.1" "$output"
else
- cat<<EOF
+ cat<<EOF
==================================
You need a working asciidoc installed to be able to build the manpage.
a2x is installed, but for some reason it isn't working. Sometimes
this happens because required docbook support files are missing.
Please install docbook-xsl, docbook-xml, and xmlto (Debian) or
-similar. If you use homebrew on Mac OS X, install the docbook formula
+similar. If you use homebrew on Mac OS X, install the docbook formula
and add "export XML_CATALOG_FILES=/usr/local/etc/xml/catalog" to your
-.bashrc
+.bashrc file.
Alternatively, to build without manpages, use the --disable-asciidoc
argument when calling configure.
==================================
EOF
- exit 1;
+ exit 1
fi
fi
-
diff --git a/doc/include.am b/doc/include.am
index 7a8a64ed16..d10f380e7f 100644
--- a/doc/include.am
+++ b/doc/include.am
@@ -51,10 +51,8 @@ EXTRA_DIST+= doc/asciidoc-helper.sh \
doc/TUNING \
doc/HACKING/README.1st.md \
doc/HACKING/CodingStandards.md \
- doc/HACKING/CodingStandardsRust.md \
doc/HACKING/Fuzzing.md \
doc/HACKING/GettingStarted.md \
- doc/HACKING/GettingStartedRust.md \
doc/HACKING/HelpfulTools.md \
doc/HACKING/HowToReview.md \
doc/HACKING/Module.md \
diff --git a/doc/man/tor.1.txt b/doc/man/tor.1.txt
index 0af9a9c03d..1814801b71 100644
--- a/doc/man/tor.1.txt
+++ b/doc/man/tor.1.txt
@@ -71,7 +71,7 @@ The following options in this section are only recognized on the
Specify a new configuration file to contain further Tor configuration
options, or pass *-* to make Tor read its configuration from standard
input. (Default: **`@CONFDIR@/torrc`**, or **`$HOME/.torrc`** if
- that file is not found)
+ that file is not found.)
[[opt-allow-missing-torrc]] **`--allow-missing-torrc`**::
Allow the configuration file specified by **`-f`** to be missing,
@@ -101,7 +101,7 @@ The following options in this section are only recognized on the
[[opt-dump-config]] **`--dump-config`** **`short`**|**`full`**::
Write a list of Tor's configured options to standard output.
When the `short` flag is selected, only write the options that
- are different from their default values
+ are different from their default values.
When `full` is selected, write every option.
[[opt-serviceinstall]] **`--service install`** [**`--options`** __command-line options__]::
@@ -988,20 +988,20 @@ forward slash (/) in the configuration file and on the command line.
running. (Default: none)
[[TCPProxy]] **TCPProxy** __protocol__ __host__:__port__::
- Tor will use the given protocol to make all its OR (SSL) connections through
- a TCP proxy on host:port, rather than connecting directly to servers. You may
- want to set **FascistFirewall** to restrict the set of ports you might try to
- connect to, if your proxy only allows connecting to certain ports. There is no
- equivalent option for directory connections, because all Tor client versions
- that support this option download directory documents via OR connections. +
+ Tor will use the given protocol to make all its OR (SSL) connections through
+ a TCP proxy on host:port, rather than connecting directly to servers. You may
+ want to set **FascistFirewall** to restrict the set of ports you might try to
+ connect to, if your proxy only allows connecting to certain ports. There is no
+ equivalent option for directory connections, because all Tor client versions
+ that support this option download directory documents via OR connections. +
+
- The only protocol supported right now 'haproxy'. This option is only for
- clients. (Default: none) +
+ The only protocol supported right now 'haproxy'. This option is only for
+ clients. (Default: none) +
+
- The HAProxy version 1 proxy protocol is described in detail at
- https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt +
+ The HAProxy version 1 proxy protocol is described in detail at
+ https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt +
+
- Both source IP address and source port will be set to zero.
+ Both source IP address and source port will be set to zero.
[[TruncateLogFile]] **TruncateLogFile** **0**|**1**::
If 1, Tor will overwrite logs at startup and in response to a HUP signal,
@@ -1749,6 +1749,13 @@ The following options are useful only for clients (that is, if
the guard-n-primary-guards consensus parameter, and default to 3 if the
consensus parameter isn't set. (Default: 0)
+[[VanguardsLiteEnabled]] **VanguardsLiteEnabled** **0**|**1**|**auto**::
+ This option specifies whether clients should use the vanguards-lite
+ subsystem to protect against guard discovery attacks. If it's set to
+ 'auto', clients will do what the vanguards-lite-enabled consensus parameter
+ tells them to do, and will default to enable the subsystem if the consensus
+ parameter isn't set. (Default: auto)
+
[[UseMicrodescriptors]] **UseMicrodescriptors** **0**|**1**|**auto**::
Microdescriptors are a smaller version of the information that Tor needs
in order to build its circuits. Using microdescriptors makes Tor clients
@@ -2847,11 +2854,15 @@ details.)
== DENIAL OF SERVICE MITIGATION OPTIONS
-Tor has three built-in mitigation options that can be individually
-enabled/disabled and fine-tuned, but by default Tor directory authorities will
-define reasonable values for relays and no explicit configuration is required
-to make use of these protections. The mitigations take place at relays,
-and are as follows:
+Tor has a series of built-in denial of service mitigation options that can be
+individually enabled/disabled and fine-tuned, but by default Tor directory
+authorities will define reasonable values for the network and no explicit
+configuration is required to make use of these protections.
+
+The following is a series of configuration options for relays and then options
+for onion services and how they work.
+
+The mitigations take place at relays, and are as follows:
1. If a single client address makes too many concurrent connections (this is
configurable via DoSConnectionMaxConcurrentCount), hang up on further
@@ -3002,6 +3013,68 @@ Denial of Service mitigation subsystem described above.
(Default: auto)
+As for onion services, only one possible mitigation exists. It was intended to
+protect the network first and thus do not help the service availability or
+reachability.
+
+The mitigation we put in place is a rate limit of the amount of introduction
+that happens at the introduction point for a service. In other words, it rates
+limit the number of clients that are attempting to reach the service at the
+introduction point instead of at the service itself.
+
+The following options are per onion service:
+
+[[HiddenServiceEnableIntroDoSDefense]] **HiddenServiceEnableIntroDoSDefense** **0**|**1**::
+ Enable DoS defense at the intropoint level. When this is enabled, the
+ rate and burst parameter (see below) will be sent to the intro point which
+ will then use them to apply rate limiting for introduction request to this
+ service.
+ +
+ The introduction point honors the consensus parameters except if this is
+ specifically set by the service operator using this option. The service
+ never looks at the consensus parameters in order to enable or disable this
+ defense. (Default: 0)
+
+//Out of order because it logically belongs after HiddenServiceEnableIntroDoSDefense.
+[[HiddenServiceEnableIntroDoSBurstPerSec]] **HiddenServiceEnableIntroDoSBurstPerSec** __NUM__::
+ The allowed client introduction burst per second at the introduction
+ point. If this option is 0, it is considered infinite and thus if
+ **HiddenServiceEnableIntroDoSDefense** is set, it then effectively
+ disables the defenses. (Default: 200)
+
+[[HiddenServiceEnableIntroDoSRatePerSec]] **HiddenServiceEnableIntroDoSRatePerSec** __NUM__::
+ The allowed client introduction rate per second at the introduction
+ point. If this option is 0, it is considered infinite and thus if
+ **HiddenServiceEnableIntroDoSDefense** is set, it then effectively
+ disables the defenses. (Default: 25)
+
+The rate is the maximum number of clients a service will ask its introduction
+points to allow every seconds. And the burst is a parameter that allows that
+many within one second.
+
+For example, the default values of 25 and 200 respectively means that for every
+introduction points a service has (default 3 but can be configured with
+**HiddenServiceNumIntroductionPoints**), 25 clients per seconds will be allowed
+to reach the service and 200 at most within 1 second as a burst. This means
+that if 200 clients are seen within 1 second, it will take 8 seconds (200/25)
+for another client to be able to be allowed to introduce due to the rate of 25
+per second.
+
+This might be too much for your use case or not, fine tuning these values is
+hard and are likely different for each service operator.
+
+Why is this not helping reachability of the service? Because the defenses are
+at the introduction point, an attacker can easily flood all introduction point
+rendering the service unavailable due to no client being able to pass through.
+But, the service itself is not overwhelmed with connetions allowing it to
+function properly for the few clients that were able to go through or other any
+services running on the same tor instance.
+
+The bottom line is that this protects the network by preventing an onion
+service to flood the network with new rendezvous circuits that is reducing load
+on the network.
+
+
== DIRECTORY AUTHORITY SERVER OPTIONS
The following options enable operation as a directory authority, and
@@ -3039,6 +3112,11 @@ on the public Tor network.
is the same as for exit policies, except that you don't need to say
"accept" or "reject", and ports are not needed.)
+[[AuthDirMiddleOnly]] **AuthMiddleOnly** __AddressPattern...__::
+ Authoritative directories only. A set of address patterns for servers that
+ will be listed as middle-only in any network status document this authority
+ publishes, if **AuthDirListMiddleOnly** is set. +
+
[[AuthDirFastGuarantee]] **AuthDirFastGuarantee** __N__ **bytes**|**KBytes**|**MBytes**|**GBytes**|**TBytes**|**KBits**|**MBits**|**GBits**|**TBits**::
Authoritative directories only. If non-zero, always vote the
Fast flag for any relay advertising this amount of capacity or
@@ -3086,6 +3164,13 @@ on the public Tor network.
1 unless you plan to list non-functioning exits as bad; otherwise, you are
effectively voting in favor of every declared exit as an exit.)
+[[AuthDirListMiddleOnly]] **AuthDirListMiddleOnly** **0**|**1**::
+ Authoritative directories only. If set to 1, this directory has some
+ opinion about which nodes should only be used in the middle position.
+ (Do not set this to 1 unless you plan to list questionable relays
+ as "middle only"; otherwise, you are effectively voting _against_
+ middle-only status for every relay.)
+
[[AuthDirMaxServersPerAddr]] **AuthDirMaxServersPerAddr** __NUM__::
Authoritative directories only. The maximum number of servers that we will
list as acceptable on a single IP address. Set this to "0" for "no limit".
@@ -3104,18 +3189,20 @@ on the public Tor network.
authority publishes, or accepted as an OR address in any descriptor
submitted for publication by this authority.
+[[AuthDirRejectRequestsUnderLoad]] **AuthDirRejectRequestsUnderLoad** **0**|**1**::
+ If set, the directory authority will start rejecting directory requests
+ from non relay connections by sending a 503 error code if it is under
+ bandwidth pressure (reaching the configured limit if any). Relays will
+ always tried to be answered even if this is on. (Default: 1)
+
//Out of order because it logically belongs with the other CCs options.
[[AuthDirBadExitCCs]] **AuthDirBadExitCCs** __CC__,... +
//Out of order because it logically belongs with the other CCs options.
[[AuthDirInvalidCCs]] **AuthDirInvalidCCs** __CC__,... +
-
-[[AuthDirRejectRequestsUnderLoad]] **AuthDirRejectRequestsUnderLoad** **0**|**1**::
- If set, the directory authority will start rejecting directory requests
- from non relay connections by sending a 503 error code if it is under
- bandwidth pressure (reaching the configured limit if any). Relays will
- always tried to be answered even if this is on. (Default: 1)
+//Out of order because it logically belongs with the other CCs options.
+[[AuthDirMiddleOnlytCCs]] **AuthDirMiddleOnlyCCs** __CC__,... +
[[AuthDirRejectCCs]] **AuthDirRejectCCs** __CC__,...::
Authoritative directories only. These options contain a comma-separated
@@ -3280,30 +3367,6 @@ The next section describes the per service options that can only be set
only owner is able to read the hidden service directory. (Default: 0)
Has no effect on Windows.
-[[HiddenServiceEnableIntroDoSDefense]] **HiddenServiceEnableIntroDoSDefense** **0**|**1**::
- Enable DoS defense at the intropoint level. When this is enabled, the
- rate and burst parameter (see below) will be sent to the intro point which
- will then use them to apply rate limiting for introduction request to this
- service.
- +
- The introduction point honors the consensus parameters except if this is
- specifically set by the service operator using this option. The service
- never looks at the consensus parameters in order to enable or disable this
- defense. (Default: 0)
-
-//Out of order because it logically belongs after HiddenServiceEnableIntroDoSDefense.
-[[HiddenServiceEnableIntroDoSBurstPerSec]] **HiddenServiceEnableIntroDoSBurstPerSec** __NUM__::
- The allowed client introduction burst per second at the introduction
- point. If this option is 0, it is considered infinite and thus if
- **HiddenServiceEnableIntroDoSDefense** is set, it then effectively
- disables the defenses. (Default: 200)
-
-[[HiddenServiceEnableIntroDoSRatePerSec]] **HiddenServiceEnableIntroDoSRatePerSec** __NUM__::
- The allowed client introduction rate per second at the introduction
- point. If this option is 0, it is considered infinite and thus if
- **HiddenServiceEnableIntroDoSDefense** is set, it then effectively
- disables the defenses. (Default: 25)
-
[[HiddenServiceExportCircuitID]] **HiddenServiceExportCircuitID** __protocol__::
The onion service will use the given protocol to expose the global circuit
identifier of each inbound client circuit. The only
@@ -3514,14 +3577,15 @@ The following options are used for running a testing Tor network.
[[TestingAuthKeySlop]] **TestingAuthKeySlop** __N__ **seconds**|**minutes**|**hours** +
[[TestingBridgeBootstrapDownloadInitialDelay]] **TestingBridgeBootstrapDownloadInitialDelay** __N__::
- Initial delay in seconds for when clients should download each bridge descriptor when they
- have just started, or when they can not contact any of their bridges.
+ Initial delay in seconds for how long clients should wait before
+ downloading a bridge descriptor for a new bridge.
Changing this requires that **TestingTorNetwork** is set. (Default: 0)
[[TestingBridgeDownloadInitialDelay]] **TestingBridgeDownloadInitialDelay** __N__::
- Initial delay in seconds for when clients should download each bridge descriptor when they
- know that one or more of their configured bridges are running. Changing
- this requires that **TestingTorNetwork** is set. (Default: 10800)
+ How long to wait (in seconds) once clients have successfully
+ downloaded a bridge descriptor, before trying another download for
+ that same bridge. Changing this requires that **TestingTorNetwork**
+ is set. (Default: 10800)
[[TestingClientConsensusDownloadInitialDelay]] **TestingClientConsensusDownloadInitialDelay** __N__::
Initial delay in seconds for when clients should download consensuses. Changing this
@@ -3840,7 +3904,12 @@ __KeyDirectory__/**`secret_onion_key_ntor`** and **`secret_onion_key_ntor.old`**
by clients that didn't have the new one.
__DataDirectory__/**`fingerprint`**::
- Only used by servers. Contains the fingerprint of the server's identity key.
+ Only used by servers. Contains the fingerprint of the server's RSA
+ identity key.
+
+__DataDirectory__/**`fingerprint-ed25519`**::
+ Only used by servers. Contains the fingerprint of the server's ed25519
+ identity key.
__DataDirectory__/**`hashed-fingerprint`**::
Only used by bridges. Contains the hashed fingerprint of the bridge's
@@ -3856,7 +3925,8 @@ __DataDirectory__/**`approved-routers`**::
descriptors are accepted, but marked in the vote as not valid.
If it is **!badexit**, then the authority will vote for it to receive a
BadExit flag, indicating that it shouldn't be used for traffic leaving
- the Tor network.
+ the Tor network. If it is **!middleonly**, then the authority will
+ vote for it to only be used in the middle of circuits.
(Neither rejected nor invalid relays are included in the consensus.)
__DataDirectory__/**`v3-status-votes`**::