Commit Graph

159 Commits

Author SHA1 Message Date
Nick Mathewson cac4ce759e Minor circuit predictor tweaks and comments.
Most notably, make min_exit_circs_for_port actually get used.

Also add a couple of comments.
2021-12-07 16:48:09 -05:00
Nick Mathewson 0f8d620757 Make preemptive circuits reconfigurable.
This required re-centralizing the configuration object for preemptive
circuits, since previously the settings from it were a bit spread out
over the crate.
2021-12-07 16:42:58 -05:00
Nick Mathewson a406e8e449 Make circuit_timing reconfigurable. 2021-12-07 16:08:52 -05:00
Nick Mathewson 99fb41218d Add new configuration objects to reconfigure.
(These weren't in the codebase when I started the first version of
this branch.)
2021-12-07 15:47:25 -05:00
Nick Mathewson 11210124da Allow on-the-fly changing of path_rules
And now the complexity begins: when the user changes the path_rules,
they not only want new circuits to obey those rules: they want
_all new requests_ to be put onto circuits that obey those rules.

That means that when the path rules become more restrictive, we need
to retire all the circuits, and make sure that currently pending
circuits aren't used for any requests.

If it's any comfort, doing this was even more complicated in C tor. ;)
2021-12-07 15:42:14 -05:00
Nick Mathewson 606d64eac5 Sketch API for reconfiguration.
This patch doesn't actually make anything reconfigurable, but it
does create an API that will tell you "you can't change the value of
that!"  If the API looks reasonable, I can start making it possible
to change the values of individual items.
2021-12-07 15:42:14 -05:00
Nick Mathewson 48f77a93c0 Clarify names and docs for predictive circuits.
Also, use humantime_serde, rather than a number of seconds, to indicate
configuration time.
2021-12-07 12:09:05 -05:00
Nick Mathewson c2e20a242a Rename circuits_preemptive to preemptive_circuits
This obeys a few conventions:
  * adjective before noun
  * config objects end with "config"
2021-12-07 12:06:53 -05:00
eta a3f2e32485 Merge branch 'bug183a_redux' into 'main'
Squash, refactor, and test !139 (Don't use same family as exit when picking a guard)

Closes #183

See merge request tpo/core/arti!173
2021-12-07 16:01:30 +00:00
eta 85bb40a002 Merge branch 'safe_mul_dur_f64' into 'main'
Use a panic-free function to multiply timeouts.

See merge request tpo/core/arti!175
2021-12-07 15:47:18 +00:00
eta 45b96579b8 Merge branch 'preemptive-config' into 'main'
Allow configurability on preemptive circuits

Closes #245

See merge request tpo/core/arti!164
2021-12-07 15:04:42 +00:00
Neel Chauhan 0e9c2d274e Allow configurability on preemptive circuits 2021-12-07 15:04:41 +00:00
Nick Mathewson d6f628c6b7 Use a panic-free function to multiply timeouts.
Previously we used Duration::mul_f64, which panics if its output is
out-of-range.  That shouldn't actually be possible for the values
we're giving it, but probably it's better to just multiply in a safe
way.

This resolves a couple of XXXXs and therefore relates to #231.
2021-12-06 16:00:17 -05:00
Nick Mathewson 31b385c5b2 Resolve roughly half of the XXXXs.
We want to only use TODO in the codebase for non-blockers, and open
tickets for anything that is a bigger blocker than a TODO.  These
XXXXs seem like definite non-blockers to me.

Part of arti#231.
2021-12-06 15:11:03 -05:00
Nick Mathewson 2c2f774bd1 Move the "real families" code into tor-netdir.
Just as `in_same_family` is a member of Relay, so the function for
getting all the real family members of a relay should belong in the
same crate.

This change also removes the `family()` accessor: it gives the _claimed_ family rather
 than the _acknlowedged_ family, and is therefore a bit dangerous.

 There's still a hole in this logic; I've noted it in the Limitations
section.  If we get a microdescriptor for a relay in between creating
and using  the guard restriction, it might be omitted from the family
list.
2021-12-06 10:48:27 -05:00
Nick Mathewson cfc31dadd4 Use hashset _inside_ GuardRestriction.
This approach saves us from a linear search when picking guards.
2021-12-06 09:44:56 -05:00
Nick Mathewson 54971e3c9a Change GuardUsage to have Vec of restrictions.
There's not much reason to use a HashSet here, since we're just
going over the whole list.

This reverts commit 16e8489abb and does a little more
refactoring.
2021-12-06 09:26:32 -05:00
Neel Chauhan b0016682c3 Implement guard family restriction code 2021-12-06 09:05:48 -05:00
Nick Mathewson d3aecd5192 Add a semicolon. 2021-11-30 15:43:21 -05:00
Nick Mathewson c733374693 Merge remote-tracking branch 'origin/mr/154' 2021-11-30 14:12:08 -05:00
eta 9a94f72e42 Add tests & address review commentary 2021-11-30 16:58:08 +00:00
Nick Mathewson eef81d9d57 Bump every crate by one patch version. 2021-11-29 15:21:58 -05:00
Nick Mathewson eb861b7edd Merge branch 'config-updates-and-tests' 2021-11-29 13:59:41 -05:00
eta ca42139944 Actually build preemptive circuits (and minor fixes)
The new CircMgr::build_circuits_preemptively function actually causes
preemptive circuits to be built; it gets called from arti-client, like
the other daemon tasks the CircMgr has.
2021-11-29 14:47:09 +00:00
Nick Mathewson b640bf75d5 Merge remote-tracking branch 'origin/mr/148' 2021-11-29 09:12:32 -05:00
Neel Chauhan 2461bd86b1 tor-circmgr: Write a test for BadExit support. 2021-11-29 09:08:32 -05:00
Neel Chauhan c98cc793a0 In struct PendingEntry, remove circ_spec 2021-11-28 17:19:58 -08:00
Nick Mathewson 17266305e2 Ensure that all config sections have deny_unknown_fields
When we deserialize a configuration, we should reject unknown variables
(except when we have an explicit reason to allow them).
2021-11-25 09:39:11 -05:00
Daniel Eades db16d13df4 add semicolons if nothing returned 2021-11-25 13:20:37 +00:00
Daniel Eades 052f51ff71 deglob some enums, use concise iteration syntax 2021-11-25 12:39:52 +00:00
Nick Mathewson f55950ab8d Fix a few typos.
Also fix some commonwealth spellings that had slipped in.
2021-11-24 18:12:44 -05:00
eta 8a5a9575c6 Introduce PreemptiveCircuitPredictor and TargetCircUsage::Preemptive
In preparation for making Arti build circuits preemptively, this commit
introduces `TargetCircUsage::Preemptive`, a circuit usage that works
somewhat differently from other ones: it requires at least 2 circuits to
exist that can exit the port it contains in order for an existing
circuit to match against it (path-spec.txt § 2.1.1); if that's not the
case, that usage will require building new circuits (in order that we
build enough to have 2 available).

This required refactoring how circuit reuse worked; now,
`CircList::find_open` uses the new `AbstractSpec::find_supported` trait
method, which we customize to implement the above check in the case of
`Preemptive` circuit usages. To make that work, `OpenEntry` now takes
two type parameters (the spec and circuit types), instead of taking a
builder type parameter and using its associated types. (We also got rid
of type constraints on that struct, yay!)

A WIP implementation of a preemptive circuit predictor that implements
path-spec.txt § 2.1.1 is also included, but this will require additional
effort to wire it up with the `CircMgr` properly.
2021-11-23 16:37:52 +00:00
Nick Mathewson 307ca9b4d0 Implement meta-builder pattern for TorClientConfig
This should be ergonomic than having to construct every section of the
configuration separately.
2021-11-22 14:53:52 +00:00
Nick Mathewson 40ff7113d4 Make every Config type implement Eq.
Doing this is necessary for reconfiguration support, and will help a lot
with testing, too.
2021-11-21 12:06:15 -05:00
Nick Mathewson e7fdf05f50 For every* config type, make defaults consistent.
This patch makes sure that for every* config type we have, the defaults
you get from a Builder match those you get from Serde, and that both
match the value that you get from arti_defaults.toml. Later down the
line I'll be adding some tests to keep these in sync.

* StorageConfig still has no defaults of its own, since we aren't so
sure we want other applications to use Arti's directories by default.
2021-11-21 11:52:43 -05:00
Nick Mathewson 97f5a7a357 Give every ConfigBuilder a From<Config> implementation.
This will make it more convenient to reconfigure things.
2021-11-21 10:54:34 -05:00
Nick Mathewson aa83a5e38a Ensure that every section-level config type has a builder() function. 2021-11-21 10:54:34 -05:00
Nick Mathewson eba35e789c Flatten enforce_distance into path_rules.
Also use the path_rules name consistently throughout the code.
2021-11-18 11:37:48 -05:00
Nick Mathewson d592e86f9c Fold "circuit_timing" and "request_timing" into a single section. 2021-11-18 11:37:48 -05:00
Nick Mathewson 5184f5ba84 Move top-level configuration downwards from `arti` to `arti-config`.
To do this at all neatly, I had to split out `tor-config` from
`arti-config` again, and putting the lower level stuff (paths,
builder errors) into tor-config.  I also changed our use of
derive_builder to always use a common error type, to avoid
error type proliferation.
2021-11-18 11:37:48 -05:00
eta 197816d14c Completely overhaul the tor-proto circuit reactor
Rather like e8e9699c3c ("Get rid of
tor-proto's ChannelImpl, and use the reactor more instead"), this
admittedly rather large commit refactors the way circuits in `tor-proto`
work, centralising all of the logic in one large nonblocking reactor
which other things send messages into and out of, instead of having a
bunch of `-Impl` types that are protected by mutexes.

Congestion control becomes a lot simpler with this refactor, since the
reactor can manage both stream- and circuit-level congestion control
unilaterally without having to share this information with consumers,
meaning we can get rid of some locks.

The way streams work also changes, in order to facilitate better
handling of backpressure / fairness between streams: each stream now has
a set of channels to send and receive messages over, instead of sending
relay cells directly onto the channel (now, the reactor pulls messages
off each stream in each map, and tries to avoid doing so if it won't be
able to forward them yet).

Additionally, a lot of "close this circuit / stream" messages aren't
required any more, since that state is simply indicated by one end of a
channel going away. This should make cleanup a lot less brittle.

Getting all of this to work involved writing a fair deal of intricate
nonblocking code in Reactor::run_once that tries very hard to be mindful
of making backpressure work correctly (and congestion control); the old
code could get away with having tasks .await on things, but the new
reactor can't really do this (as it'd lock the reactor up), so has to do
everything in a nonblocking manner.
2021-11-12 15:04:24 +00:00
Dimitris Apostolou ad3c18a456
Fix typos 2021-11-12 13:54:50 +02:00
Nick Mathewson 24b6a2455d Document that the "experimental-api" feature is not semver-covered. 2021-11-11 10:44:24 -05:00
Nick Mathewson ee030260fb Add a couple of pieces of missing documentation. 2021-11-08 16:06:08 -05:00
Nick Mathewson 83d9f2299e Replace all println/eprintln calls outside of arti CLI with trace. 2021-11-04 11:04:59 -04:00
Nick Mathewson dae8cdb463 Remove all remaining dbg! instances. 2021-11-04 10:54:47 -04:00
Nick Mathewson cb63449aeb Basic tests for readonly estimators, and estimator migration.
Also add a comment about a possible problem behavior in read-only
estimators.
2021-11-03 13:58:51 -04:00
eta e8e9699c3c Get rid of tor-proto's ChannelImpl, and use the reactor more instead
Instead of awkwardly sharing the internals of a `tor-proto` `Channel`
between the reactor task and any other tasks, move most of the internals
into the reactor and have other tasks communicate with the reactor via
message-passing to allocate circuits and send cells.

This makes a lot of things simple, and has convenient properties like
not needing to wrap the `Channel` in an `Arc` (though some places in the
code still do this for now).

A lot of test code required tweaking in order to deal with the refactor;
in fact, fixing the tests probably took longer than writing the mainline
code (!). Importantly, we now use `tokio`'s `tokio::test` annotation
instead of `async_test`, so that we can run things in the background
(which is required to have reactors running for the circuit tests).

This is an instance of #205, and also kind of #217.
2021-11-03 13:19:45 +00:00
Nick Mathewson 03cf83b2cc Disable a check in exitpath
This check relies on families being enforced correctly, which is not
the case when specifying a fixed exit and using guards.  (See #183)
2021-11-02 16:43:58 -04:00
Nick Mathewson b9849788cd Allow clone-on-copy in tor-circmgr tests to fix a nightly-only clippy warning. 2021-11-02 16:17:51 -04:00
Nick Mathewson 78fbb141be tor-circmgr: test ExitPathBuilder with guards. 2021-11-02 14:17:18 -04:00
Nick Mathewson 3b41933b67 tor-circmgr: test DirPathBuilder with GuardMgr. 2021-11-02 13:50:08 -04:00
Nick Mathewson ad132602ae tor-circmgr: testing for NoUsage and TimeoutTesting usage
This doesn't add much to coverage, but it's important.
2021-11-02 13:30:04 -04:00
Nick Mathewson 5b1b87c896 tor-circmgr: tests for netwoks with no exits 2021-11-02 10:58:28 -04:00
Nick Mathewson b547cdb7ff tor-circmgr::usage: Add a few more tests. 2021-11-02 09:42:56 -04:00
Nick Mathewson e6e740646a Bump all crate versions to 0.0.1 2021-10-29 11:05:51 -04:00
Nick Mathewson 19a61249f8 Merge remote-tracking branch 'origin/mr/112' 2021-10-29 09:16:44 -04:00
eta a12fffc66a Improve docs of more (potentially re-exported) arti-client types
Most of the structs in `arti-client` have example code now, to give a
clearer idea of how they're used.

Annoyingly, a lot of the types exposed in `arti-client` are actually
re-exports, which makes documentation a bit harder: example code that
references other parts of `arti-client` can't actually be run as a
doctest, since the crate it's in is a dependency of `arti-client`.

We might be able to fix this in future by doing the documentation in
`arti-client` itself, but rustdoc seems to have some weird behaviours
there that need to be investigated first (for example, it seems to merge
the re-export and original documentation, and also put the re-export
documentation on the `impl` block for some reason).

For now, though, this commit just writes the docs from the point of view
of an `arti-client` consumer, removing notes specific to the crate in
which they're defined. It's not ideal, but at least the end user
experience is decent.
2021-10-29 14:06:06 +01:00
Nick Mathewson 1ee24ce653 Improve some documentation links
Instead of putting a fully qualified name in the text, in most cases
we should just use the short name of the type or function we're
referring to.

In other words, instead of saying [`crate::module::Foo`], we should
typically say [`Foo`](crate::module::Foo).
2021-10-29 08:39:04 -04:00
Nick Mathewson c11fe200d1 Try writing a bit more documentation for configuration types. 2021-10-28 20:49:17 -04:00
Nick Mathewson a730478fd0 Fix clippy warnings in tests. 2021-10-28 11:44:09 -04:00
Nick Mathewson 6dde31f328 Merge remote-tracking branch 'origin/mr/110' 2021-10-28 11:40:18 -04:00
Nick Mathewson 0979e60293 Mark request_retried test as ignored 2021-10-28 11:30:16 -04:00
Nick Mathewson b7c7c8ba13 tor_circmgr: Refactor and re-enable build_timeout() test
The previous version of this test used the old, racy version of
wait_for (see #149).  The new version is refactored so that
simulated time is only allowed to advance after each step is done,
so that we can actually be sure that each step in the process will
happen as it should.

In order to get the time-advances to proceed properly, and avoid
polluting state between tests, I've had to introduce some machinery
to encode the proper amount for time to advance.  It isn't something
I'd want to use for a whole bunch of tests, but for just one set,
it's fine.

These tests now pass reliably for me.

I wonder if a discrete-event-simulation approach (hello, Shadow)
would let us write tests like these to our hearts' content?
2021-10-27 16:31:31 -04:00
Nick Mathewson 134c04a67a Update our disclaimers and limitations sections. 2021-10-27 11:13:46 -04:00
eta 7a931b4de3 Add #[serde(flatten)] HashMap fields to serializable objects
As per arti#175, we'd like to be able to handle newer Arti versions
storing additional state in the persisted state files, without dropping
this data on the floor when we write out changes to these files.

Use the #[serde(flatten)] mechanism to achieve this, by adding catch-all
HashMap<String, JsonValue> fields to all structs that are at risk of
this happening to them.
2021-10-27 13:31:52 +01:00
Nick Mathewson e64177d97e Fix some clippy-nightly warnings.
These are my fault; I merged the wrong version of !102. :p
2021-10-26 13:13:46 -04:00
Nick Mathewson c6a1bcaa69 circmgr: Split request_timeout test into two.
There seems to be some issue here with the new WaitFor code,
where using the same MockSleepProvider with both of these wait_for()
calls gives questionable behavior under some circumstances (like
when running under Tarpaulin with the wrong set of flags).
2021-10-26 13:01:13 -04:00
Nick Mathewson b0fd7cff8e Merge remote-tracking branch 'origin/mr/102' 2021-10-26 13:01:01 -04:00
Nick Mathewson da45008644 Merge branch 'pb_lite_squashed' 2021-10-26 12:03:51 -04:00
Nick Mathewson 72ebaed16b Do not blame a guard for failures on non-random circuits.
We must not apply our new path-bias behavior (where we blame a guard
if it gives us too many indeterminate circuit failures) if the path
was not chosen at random.  If too many random paths fail, we know
that's suspicious, since the other relays are a random sample.  But
if a bunch of user-provided paths fail, that could simply be because
the user's chosen exit is down.
2021-10-26 12:03:23 -04:00
eta e8419abd25 Overhaul the way WaitFor and the MockSleepProvider work
Instead of racily advancing time forward, this commit attempts to rework
how WaitFor works, such that it makes advances when all sleeper futures
that have been created have been polled (by handing the MockSleepRuntime
a Waker with which to wake up the WaitFor).

The above described mechanics work well enough for the double timeout
test, but fail in the presence of code that spawns asynchronous /
background tasks that must make progress before time is advanced for the
test to work properly. In order to deal with these cases, a set of APIs
are introduced in order to block time from being advanced until some
code has run, and a carveout added in order to permit small advances in
time where required.

(In some cases, code needed to be hacked up a bit in order to be made
properly testable using these APIs; the `MockablePlan` trait included in
here is somewhat unfortunate.)

This should fix arti#149.
2021-10-26 16:33:23 +01:00
Nick Mathewson 47234655ce Turn StreamIsolation into a separate type.
Now that we have two kinds of isolation tokens (those set on a
stream, and those set by the stream's associated TorClient), we
need a more sophisticated kind of isolation.

This fixes the bug introduced with the previous commit, where
per-stream tokens would override per-TorClient tokens.
2021-10-25 12:32:18 -04:00
Nick Mathewson b477f12d83 s/arti-arti-client/arti-client/ and regenerate readme files 2021-10-25 08:40:00 -04:00
Nick Mathewson 529d5d5efb Fix a typo in a comment. 2021-10-25 08:25:59 -04:00
Nick Mathewson e00a1c59ae Run "cargo fix --edition-idioms=2018". 2021-10-22 09:05:45 -04:00
Nick Mathewson 730be38867 Replace references to arti-client in the documentation. 2021-10-21 14:22:21 -04:00
Nick Mathewson 7159941ae1 Remove #![allow(dead_code)] in timeouts.rs 2021-10-21 13:42:53 -04:00
Nick Mathewson f3dc66d964 Merge branch 'share_state' 2021-10-21 13:34:38 -04:00
Nick Mathewson 8a99833777 Implement the guard side of shared state directories. 2021-10-21 13:31:38 -04:00
Nick Mathewson c8cfbda339 Finish the timeout-inference side of shared state. 2021-10-20 13:13:15 -04:00
Nick Mathewson db0921fd7e Add a timeout estimator to take estimates from another process. 2021-10-20 12:41:59 -04:00
Nick Mathewson 16ec1d21f2 Allow type of timeout estimator to change at runtime.
This is a big change, but it does simplify the type of Builder a
little, and isolates locking across different (potential) timeout
estimator types.
2021-10-20 12:06:58 -04:00
Nick Mathewson 7b6ed9dab6 Replace the return type of StorageMgr::try_lock with a tristate
It's useful to know now only if we now have the lock, but also if we
just got it for the first time.
2021-10-20 09:37:53 -04:00
Nick Mathewson b53abdb67e Implement the "request_loyalty" configuration option 2021-10-19 16:25:52 -04:00
Nick Mathewson 445ec6d220 Fix most warnings from nightly.
(One represents code that I forgot to write.)
2021-10-19 16:21:12 -04:00
eta b42a6712c9 tor-client: refactor TorClient::bootstrap's args into a config object
The three arguments TorClient::bootstrap requires by way of configuration
have been factored into a new TorClientConfig object.

This object gains two associated functions: one which uses `tor_config`'s
`CfgPath` machinery to generate sane defaults for the state and cache
directories, and one that accepts said directories in order to create a
config object with those inserted.

(this commit was inspired by trying to use arti as a library and being somewhat
overwhelmed by the amount of config stuff there was to do :p)
2021-10-19 19:59:25 +01:00
Nick Mathewson 89d1fb1767 Initial work on periodically reloading state.
We can use this in the case where we don't get the lock on the
state file, because another process is running.
2021-10-19 11:26:22 -04:00
Nick Mathewson f15cde80de Use better reporting for guard status.
The previous code would report all failures to build a circuit as
failures of the guard.  But of course that's not right:  If we
fail to extend to the second or third hop, that might or might not
be the guard's fault.

Now we use the "pending status" feature of the GuardMonitor type so
that an early failure is attributed to the guard, but a later
failure is attributed as "Indeterminate".  Only a complete circuit
is called a success.  We use a new "GuardStatusHandle" type here so
that we can report the status early if there is a timeout.
2021-10-13 11:24:37 -04:00
Nick Mathewson 733aa3a4e2 Implement guards for multihop paths.
There are some limitations here, as noted in the comments.
2021-10-13 10:27:46 -04:00
Nick Mathewson fd893f750c Actually select guards for directory circuits. 2021-10-13 09:30:50 -04:00
Nick Mathewson 5b06b3c64a Pass the guard manager down to the path selection functions. 2021-10-11 15:59:45 -04:00
Nick Mathewson ad851c43c6 WIP 2021-10-11 15:37:59 -04:00
Nick Mathewson 34b576a815 Integrate GuardUsability and GuardMonitor into CircuitBuilder.
(When we're building a path with a guard, we need to tell the guard
manager whether the path succeeded, and we need to wait to hear
whether the guard is usable.)
2021-10-10 13:48:58 -04:00
Nick Mathewson 33ba697b5d Notify guard manager on network change and state flush. 2021-10-10 12:38:50 -04:00
Nick Mathewson c41dd01a14 Add a GuardMgr member to CircuitBuilder 2021-10-10 12:24:48 -04:00
Nick Mathewson 58355d7d54 Re-export configuration types from tor-client. 2021-10-09 17:30:06 -04:00
Nick Mathewson af7c9d5a0b enable checked_conversions lint. 2021-10-09 16:53:13 -04:00
Nick Mathewson 0779923d64 Initial backend implementation for guard node manager.
There are some missing parts here (like persistence and tests)
and some incorrect parts (I am 90% sure that the "exploratory
circuit" flag is bogus).  Also it is not integrated with the circuit
manager code.
2021-10-07 10:45:42 -04:00
Nick Mathewson f1d6779218 Use StorageHandle in tor_circmgr. 2021-09-30 15:36:11 -04:00