We'll probably need the hsdir list to be shuffled deterministically for
testing purposes (this might be desirable, for example, when we write a
test for HS descriptor download retries).
Signed-off-by: Gabriela Moldovan <gabi@torproject.org>
Now there can be one of each, since we want references and handles
to be conceptually separate.
(The alternative would be to say that an operation either "returns a
handle" or "returns a reference (which may become a handle) unless a
handle already exists.")
To me, "Session" suggests that we're authenticated, when we are
not necessarily authenticated. Also, we may eventually want to have
some kind of persistent session object; if we do, then we'll want
Connections to be separate.
(This is the correct capabilities-based behavior. For now it will only
work if the TorClient uses a PreferredRuntime, but with luck we will
find a solution for #837 soon.)
Now there's a module in `arti` that runs the loop for an RPC
listener. The part of the old `listener` module that made
the framed connections is now part of the `Session` object.
There is now yet another a temporary location for the pipe; we
should pick something better. At least now it's configurable.
In the future, this will probably hold more data as well, like a
TorClient and some configuration info.
The TorClient will present an issue; I've made comments about that.
Closes#820
The `HsClientSecretKeys` stored in the HS client connection context only
have the secret keys. Certain APIs (such as `HsDesc::parse`) expect a
keypair (both `HsClientDescEncKey` and `HsClientDescEncSecretKey`). This
`From` impl makes it possible to get a `HsClientDescEncKey` out of
`HsClientDescEncSecretKey`.
Signed-off-by: Gabriela Moldovan <gabi@torproject.org>
My goal here is to make sure that we can't confuse
one download operation and another, and that we actually know
what's going on. Previously, not all state transitions or
attempts to fetch information actually corresponded to a log.
One of the tests run as part of `cargo test -p arti-client` fails
because the `pt-client` feature is not enabled by default:
```
failures:
---- src/config.rs - config::BridgesConfig (line 221) stdout ----
error[E0432]: unresolved import `arti_client::config::pt`
--> src/config.rs:225:26
|
7 | use arti_client::config::pt::ManagedTransportConfigBuilder;
| ^^ could not find `pt` in `config`
error[E0599]: no method named `bridges` found for mutable reference `&mut BridgesConfigBuilder` in the current scope
--> src/config.rs:233:19
|
15 | builder.bridges().bridges().push(bridge_1);
| ^^^^^^^ private field, not a method
error[E0599]: no function or associated item named `default` found for struct `BridgeConfigBuilder` in the current scope
--> src/config.rs:236:48
|
18 | let mut bridge2_builder = BridgeConfigBuilder::default();
| ^^^^^^^ function or associated item not found in `BridgeConfigBuilder`
error[E0599]: no method named `bridges` found for mutable reference `&mut BridgesConfigBuilder` in the current scope
--> src/config.rs:247:19
|
29 | builder.bridges().bridges().push(bridge2_builder);
| ^^^^^^^ private field, not a method
error[E0599]: no method named `transports` found for mutable reference `&mut BridgesConfigBuilder` in the current scope
--> src/config.rs:255:19
|
37 | builder.bridges().transports().push(transport);
| ^^^^^^^^^^ method not found in `&mut BridgesConfigBuilder`
error: aborting due to 5 previous errors
Some errors have detailed explanations: E0432, E0599.
For more information about an error, try `rustc --explain E0432`.
Couldn't compile the test.
failures:
src/config.rs - config::BridgesConfig (line 221)
test result: FAILED. 5 passed; 1 failed; 3 ignored; 0 measured; 0 filtered out; finished in 2.10s
```
This disables the `BridgesConfig` doc test if the `pt-client` feature is not enabled.
Closes#843
Signed-off-by: Gabriela Moldovan <gabi@torproject.org>
This adds an example to the `HsDesc::parse` docs. The constants from the
example are lifted from the `parse_desc_good` test.
Signed-off-by: Gabriela Moldovan <gabi@torproject.org>
This adds the `HsDesc::parse_decrypt_validate` method, which parses,
decrypts, and validates HS descriptors.
Closes#809
Signed-off-by: Gabriela Moldovan <gabi@torproject.org>
Right now, this lets us say whether the method was unrecognized or
whether the parameter type was incorrect.
We'll use this to enforce correct method names later on.
(I have to add another `inventory` here, since the `typetag`
maintainer does not want to expose this functionality: see
https://github.com/dtolnay/typetag/issues/57#issuecomment-1506106290
)
Otherwise there is too much risk of accidentally adding in another
1<<12 when we meant to add a 1<<13.
(It would be neat to have an alternative to bitflags here that would
auto-number our bitflags for us.)
Previously the main loop received updates via a `mpsc::channel`, and
final responses via a `futures::unordered`. This could lead to
final responses being transmitted to the user before the updates
were all flushed.
Now all of the responses are sent to the main loop via the same channel,
and they can't get out-of-sequence.
Closes#817 and (IMO) simplifies the code a bit.
Now that the sink is not part of the context, RPC functions that are
able to send an update have to declare an `impl Sink` as their
fourth argument. This syntax is not final.
Part of #824.
Now instead of hoping that buggy clients will detect a magic `id`,
we can simply tell them that they will get no `id` at all. If they
can't handle that case, no major harm is done: the connection will
get closed anyway.
Since we're serializing everything in this format, let's enforce it.
With this change, we can no longer cram arbitrary junk into an
RPC error, so we have to clean up our handling of cancelled requests.
This is a bit big, but it's not that _complicated_.
The idea here is that we use serde's "untagged" enum facility
when parsing our `Request`s, such that if parsing as a `Request`
fails, we parse as an `InvalidRequest` and try to report
what the problem was exactly.
This lets us determine the ID of a request (if it had one),
so we can report that ID in our error message. We can also
recover from a much broader variety of errors.
We now also conform with the spec reporting errors about
completely wrong json, requests without IDs, and so on.
Well, mostly correct. Our current serde implementation doesn't
tell us much about what went wrong with the object, so we can't
tell why we couldn't convert it into a Request.
Also, our output for the data field is not as the spec says:
we should bring them into conformance.
Part of #825.
Even though json-rpc uses "result" to mean "a successful return value
from a method", we can't: Rust's `Result` type is so pervasive
that confusion would be inevitable.
In one case, we use WeightRole::Exit on circuits that can't
actually be used to exit. This commit adds a comment to explain
why, so that we don't wonder about it in the future, and we have
some indication of whether it's still appropriate.
Closes#785
We now _use_ the function pointers rather than comparing them; this
lets us drop our Eq/PartialEq/Hash implementations for
`ConstTypeId_` and instead just use `TypeId`s once we're in run-time
code.
It's experimental, and tokio-only. To enable it, build with
the "rpc" feature turned on, and connect to
`~/.arti-rpc-TESTING/PIPE`. (`nc -U` worked for me)
I'll add some instructions.
Per our design, every connection starts out unauthenticated, and
needs one authenticate command to become authenticated.
Right now the only authentication type is "This is a unix named
socket where everybody who can connect has permission."
This lets us avoid async_trait in tor-rpccmd, and makes us use a
Box<>. I think we might actually get an even smarter type later on,
but we will need to play with this for a while too.
I'm not sure about these APIs at all! They force us to use
`async_trait` for `tor_rpccmd::Context`, which bothers me. Should we
just have a function that returns
`Option<Box<dyn Sink<Item=X, Error=Y>>` or something? If so,
what's the correct Y?
This code uses some kludges (discussed with Ian previously and
hopefully well documented here) to get a type-identifier for each
type in a const context. It then defines a macro to declare a
type-erased versions of a concrete implementation functions, and
register those implementations to be called later.
We will probably want to tweak a bunch of this code as we move ahead.
Ordinarily you can cancel a future just by dropping it, but we'll
want the ability to cancel futures that we no longer own (because we
gave them to a `FuturesUnordered`).
This is a workaround for an issue that I'm about to encounter
somewhere in our pile of dependencies as I add arti-rpcserver, and
somehow make serde_json visible in this test code thereby, making
the PartialEq method resolution ambiguous.
!1121 renamed *ProtocolFailed to *ProtocolViolation.
!1118 introduced a new reference to a *ProtocolFailed
I rebased !1118 onto main and enabled automerge. That tested the tip
of !1118. I assume a similar thing happened to !1121.
The possibility of such regressions is a property of our workflow.
It's rather surprising it doesn't happen more often.
1. Abbreviate the link text, and don't have it contain `crate`
which is not really great in docs.
2. Use `super::` for the link target, to find the right thing.
(`crate` doesn't seem to work in rustdoc, perhaps deliberately,
although the error messages are ridiculous and claim the
nonexistence of intermediate modules.)
3. Wrap the lines a bit more.
We have a local alias of `HsDesc = String` which needs to be got rid
of.
But, right now the alternative would be to implement all the code for
signature checking and decryption of an `HsDesc`, before we can make a
test case for the downloader part.