The RetryDelays are being triggered for the 2nd time here, so their
timeouts can be longer. We must bump the sleep to make sure we don't
have a flaky test.
Prior to the previous commit, set_bridges would malfunction if there
were bridges which where (i) in current (ii) in queued or running
(iii) in the new bridge set.
This test failed then and passes now.
This was fundamentally confused and irregular. Now it is more
regular: it does the same things to all the elements of Tracked,
and a simple filtering on current.
This fixes a bug, for which I'm about to add a test case.
0.99.[012] have a bug https://github.com/JelteF/derive_more/issues/114
which makes the Deref derive for bridgedesc::StateGuard not work
and therefore breaks minimal-versions CI.
It seems simpler to require the newer version everywhere.
Previously we always set `dir_info_missing` to `false` for new
guards, since new guards could only be taken from ones that were
present in the NetDir. But for bridges, we don't download their
info until _after_ we have chosen them as guards.
In this and the upcoming commits I'll be changing how guards related
to `NetDir` and to `Relay`. Previously, a guard could only come
from (or be updated from) a `Relay` in a `NetDir`. Soon it will be
able to be built from a bridge as well.
To do this, I'm defining a `Universe` trait (name negotiable) that
represents a set of things that may be guards. I'm going to
continue extending its functionality until there are no more
methods in guard.rs or sample.rs that take `NetDir`.
This commit removes most of the usage of `NetDir` and `Relay` in
`guard.rs`.
The new `ipc` module inside `tor-ptmgr` implements the Pluggable
Transport Specification version 1 (`pt-spec.txt`,
https://gitlab.torproject.org/tpo/core/torspec/-/blob/main/pt-spec.txt).
This enables module users to spawn pluggable transport binaries inside a
child process asynchronously, and receive structured information about
how to connect to the transports provided by said binaries.
Internally, this is structured as a pure set of serialisers and
deserialisers for the protocol in the specification (in the form of
environment variables, and the PT's stdout), a wrapper to run the PT
binary and enable accessing its output asynchronously, and a user-facing
wrapper that handles ensuring all the requested transports launched
properly.
The included `run-pt` example is an exceedingly minimal wrapper program
that was useful in testing. More tests can and should be added in a
further MR.
closes arti#394; part of arti#69
This is necessary for the (somewhat undesirable) lookup_ids function
to return an ID that the dirmgr can actually use to report successes
and failures.
As noted, lookup_ids will create problems down the road when we
implement relays. We should refactor it out before then.
This required a number of changes, which I've tried to document.
I've taken a conservative approach to modification, and I'm not
using any of the by_*_mut() functions (yet). For cases which
potentially modify the whole set, I'm using into_values() and
collect() to ensure that it's re-indexed correctly, even though the
identities don't change.
I introduce some "TODO pt-client" comments here which I will resolve
in the next commit(s).
The explicit list of variant names, that needs to be kept in sync, and
is a test failure semver break hazard, is now gone.
All the necessary code is now generated automatically, and cannot be
wrong.
I want this because I find myself wanting to add a second
implementation of FlagEvent, for another type.
1. Import it, as we do elsewhere, and use that import.
2. Use thiserror to generate the Display impl, rather than
derive_more, as we do for errors elsewhere.
(tor_error still needs derive_more::Display for ErrorKind.)
Previously we could only use Relay for this case, which won't work
any more: a Bridge is not a `tor_netdir::Relay`. Instead we allow
the GuardMgr to give us something that knows how to convert itself
into an OwnedCircTarget.
This change required a far amount of follow-on revisions and
refactoring, but it should all be internal to the path-building
logic.
Now it contains either an `OwnedChanTarget` or an `OwnedCircTarget`,
which will let `GuardMgr` return bridges that can be used to make
circuits.
As part of this change, it was necessary to revise some
address-modification functions that applied to filters and
`OwnedChanTarget`. Now they do the smart thing, and remove only the
address that are in the `ChanMethod`. This means that the addresses
from HasAddrs are still accurate about which addresses the relay
"has".
This commit improves the overflow protection of one call to
Vec::write_u16(), by replacing the cast conversion from self.sig.len()
with a call to u16::try_from(), like it is already done in the rest of
the accompanying function.
This commit adds a `debug_assert!` macro into the `new_unchecked()`
function of the Data cell. Beside this, it also fixes a misleading
comment regarding that limit.
We could in the future provide a version of abs_retry_time which took
an &dyn closure if that turns out to be wanted.
I think this isn't a semver break because trait implementors are
allowed to relax bounds.
The most important part of this commit is to make sure that each
`FirstHopId` includes the `GuardSetSelector` from which the guard
was selected. Doing this lets us be certain that when we report
that a guard has succeeded or failed, we're reporting it in the
right context.
Additionally, this commit uses strum to make an iterator over the
samples, so that we can make sure that our "for each sample" code is
robust against future changes, and we don't miss the bridge sample.
This commit changes the way how a vector with a known sized gets
allocated, by using Vec::with_capacity() instead of Vec::new().
It will eventually avoid an allocation of more memory than required.
This commit renames the for_client and for_relay functions to
from_client and from_relay respectively, in order to indicate their
origin, as the term "for" is more likely to indicate a destination,
which is not true in that situation.
This commit renames the fixed_len! macro to fixed_len_handshake!, in
order to indicate, that this macro is only suited for cells with
commands related to handshaking.
The `PtTarget` type and its contents (`TransportName`,
`PtTargetAddr`, `PtSettings`) are now unconditionally compiled and
exposed. This will allow us to serialize and deserialize them in
our guard-state files even when we have been built without explicit
PT support.
The `pt-client` feature controls whether `TransportName` is a
variant of `TransportId`, and whether `PtTarget` is a variant of
`ChanMethod`: this in turn means that we'll still have simpler
binary code and smaller structures when we're building without PT
support (which is what we wanted when we initially made these types
conditional).
This lets us write functions which can either take an existing
owned OwnedChanTarget, or copy out of some other kind of ChanTarget
passed by reference.
Now keyed by Arc<BridgeConfig>, and the values can be errors.
Currently there is no implementation so there can't be any errors,
but the error enum will become nonempty.
This is a compromise between C tor (never escapes = signs) and the
spec (calls for escaping all = signs). In C tor there is no way to
actually construct a key with an = sign in it, so this difference
should be undetectable.
This code is _not_ conditional, since we want to support running
with a proxy even if we don't support pluggable transports.
We may eventually want to refactor this into a new create.
Now, instead of duplicate checks in various cases, we simply go
through the loop one last time.
This allows us to simplify some of our other logic around here.
This is necessary so that we can look up channels (open and pending)
by all of the Ids that we know about them.
The operations needed here are pretty complex: to get them right,
I've replaced most of the accessors on the inner `ChannelMap` with a
function that holds the lock while another `FnOnce` is called. This
still gets us the invariant that we can't accidentally await while
holding the lock on the `ChannelMap`.
I've removed the tests for the accessors that are no longer there.
There are some subtleties here. Now that we have more than one kind
of Id, it's possible to have a partial match. I've tried to explain
all these cases in the comments.
}
Even though channels are practically changeable, they use locks
internally so that you don't need a `&mut Channel` to send or
receive traffic. It makes sense for reparameterizing the channel to
also use a &self reference.
I'll need this so that I can store channels in an `ByRelayIds<>`
set, and still invoke their reparameterize methods.
This is mostly a testing only change for now too, but soon I'll use
it to deal with the fact that we need to know the IDs to actually
build a channel at all.
The `ByRelayIds` type doesn't have a type equivalent to
`hash_map::Entry`, since it's a set type rather than a map
type. Therefore, the only plausible way to do entry mutation will
be to remove the old entry and insert a new one. And so, we no
longer need a "poisoned" state.
Also, add a few tests for this and the other accessors.
We'll need this accessor to find whether we have any channels to
_any_ of the identities that we're trying to connect to.
We need to handle String, not just str, since some deserializers
have to handle escapes and generate new strings.
Found while writing tests; fixes#605.
In addition to the usual "You named that method wrong!" errors, we
have a new rustdoc error that complains about bogus "HTML tags" that
are actually unquoted usage of types like `Result<Foo>`.
This lets us build channels using different TransportHelpers,
including the (new) default TransportHelper, which just uses the old
connect_to_one() code.
The feature we want is `#[doc = include_str!("README.md")]`, which is
stable since 1.54 and our MSRV is now 1.56.
This commit is precisely the result of the following Perl rune:
perl -i~ -0777 -pe 's{(^//!(?!.*\@\@).*\n)+}{#![doc = include_str!("../README.md")]\n}m' crates/*/src/lib.rs
The traits that launch connections need to be async; the traits that
don't, shouldn't be async.
Additionally, we need a few more "Sync" annotations here for the
futures to work.
This is an internal type (distinct from factory::ChannelFactory)
that we use to make the code in `tor_chanmgr::mgr` agnostic about
what a channel actually is, and how it is actually launched.
Therefore, I'm renaming it and giving better documentation in a
couple of places, to prevent confusion.
Add ,ignore to ignore three examples that don't actually compile.
cargo readme would add these annotations to lib.rs, but the doc
include doesn't do stuff like that. pandoc seems to still render the
result just fine.
This demonstrates that:
* !bridge-client: uncommenting nondefault bridge config generates
urecognized config key warnings (but the config is still accepted)(
* bridge-client, !pt-client: uncommenting nondefault bridges generates
error due to attempting to use a PT. If that's filtered out,
everything is fine.
* pt-client: Everything is good (as before).
* Introduce filter_examples and resolve_examples helpers,
which will become more complex in a moment.
* Move the API test into a { } block to minimise subsequent diff.
It's going to become conditional.
* In subsequent comparisons, use the parsed version, since
the API built one might not exist.
No overall functional change.
We're going to want something that has the standard list builder
methods at the Rust API, but which has different serialisation.
Sadly the implementation is annoying, because macro_rules makes it
hard to parse a nice input syntax.
This is precisely the text from the original version of !744.
There is no implementation yet, so we must add a entry to the
exception list in the tests.
Section headings appear uncommented in the file, so if we have a
whole section which is completely unrecognized (ie, an entry with no
`.`, it will be spotted when we parse the not-uncommented file too.
Right now there aren't any but there will be in a moment.
This test depends on `Duration` having a granularity of 1
nanosecond, which is not the case on OSX, and is probably not the
case on other places too.
We can re-enable this once we have a set of test vectors that use
more realistic RTTs, and a set of testing code that tolerates some
divergence.
Temporary solution for #574.
I think this is quite an inconvenient way to be carrying on.
Maybe we should disable all dead code warnings unless all features are
also enabled, and just let the compiler get rid of unused stuff later.
`${PROGRAM_DIR}` expands to the equivalent of
`std::env::current_exe().parent()`, with appropriate unwrapping and
conversions.
It is expected to be useful for finding the locations of pluggable
transports in some kinds of bundles.
Closes#586.