This includes a partial solution for #769, but also turned up
another bug (#774) while I was working on it. I'll close them both
once I have a real solution.
We'll use this to router relay messages on a circuit to the
appropriate stream, and hand them to that stream, without parsing
the message until the stream has been determined.
We now manipulate raw relay cell bodies as (an alias for)
`Box<[u8;509]>` rather than as (an alias for) `[u8;509]`. This
enables us to do much less copying. It will become more important
soon, as we defer parsing relay cell bodies even longer.
Related to #7.
We also use SliceWriter to avoid allocating a Vec<> for every relay
message we want to encode, and instead encode directly into the
cell.
Because the API assumes that many writes are infallible, this writer
takes ownership of the backing object, and will only return it to
you if you didn't run over the end.
I'm going to use this to save some allocations in relay cell bodies
Several HS message types have an extension list type. They all use
the same framing for extensions, but each of them has separate
extension types and separate extension namespaces.
This commit simplifies establish_intro a little, and adds support
for maintaining unrecognized extension types--at the expense of some
new internal code.
Some of the HS message types have a lot of dependent types, like
extensions and options for those extensions, and so on. Except when
those extensions are portable across cell types, it makes sense
to put them in their own modules.
We want to fuzz these parsers, but there's no currently way to get
at the parsers for inner documents without going through a lot of
encryption. (Coverage-guided fuzzers are powerful, but they
can't find SHA3 preimages.)
There will be two call sites to demonstrate it.
Eventually maybe this will want to be in tor-basic-utils, since it
doesn't depend on any of the tor-netdoc types. But it would be
sensible to wait until the situation with PeekableIterator and
Itertools is improved.
For now we make this #[doc(hidden)] to avoid it becoming part of our
stable API.
This one was generated (by dgoulet) using `ClientDescEncKey`
encryption. Its information is:
```
Address: paozpdhgz2okvc6kgbxvh2bnfsmt4xergrtcl4obkhopyvwxkpjzvoad.onion
Time period: 19397
Client:
paozpdhgz2okvc6kgbxvh2bnfsmt4xergrtcl4obkhopyvwxkpjzvoad:descriptor:x25519:SDZNMD4RP4SCH4EYTTUZPFRZINNFWAOPPKZ6BINZAC7LREV24RBQ
Service:
descriptor:x25519:SACGOAEODFGCYY22NYZV45ZESFPFLDGLMBWFACKEO34XGHASSAMQ
```
Fixes an instance of #768.
The problem with the test vectors is that I used a random time
period number (1234) and the default-in-tor period length (1440)
without checking whether 1440 _meant_ minutes or seconds. I'll add
another test to Tor to make sure that the time period matches now.
With this change, I can test Tor-generated hsdescs with encryption,
so I'm fairly confident that the new behavior is correct.
Unlike C tor, we treat unrecognized commands as reason to kill off
the connection entirely. That's fine; if we need to add an
unrecognized command in the future, we can use VERSIONS to negotiate
it.
Also, if someday we want this code to support relay channels as
well, we can use some type trickery to have that work too.
Actually, to avoid making a breaking change, I'm deprecating
BadMessage and creating a new InvalidMessage variant that takes a
Cow. This way I don't need to track every crate that re-exposes
tor_bytes::Error and call this a breaking change in those.
Making this change will allow tor_bytes errors to be much more
helpful.
Every FooMsg type now implements Into<AnyFooMsg>, and
TryFrom<FooMsg>.
Additionally, it now implements From<X> for every distinct type that
it supports. This last part lets us discard a bunch of code.
Unfortunately, I needed some downright hackish trickery in order to
get these macros to avoid generating `From<AnyFooMsg> for AnyFooMsg`
and conflicting with the blanket implementation.
The trickery to deal with RelayEarly and Relay being the same type
was not necessarily worth it; I will be separating them and removing
said trickery in the next commit.
This change lets us use ChannelCodec to encode and decode any
restricted channel message type we want. (Later on, we'll turn the
related Codec class in tor-proto into a more type-restricted version
of this.)
* Provide an accessor for the HSDIR flag
* Provide a function for testing a relay for hsdir inclusion
* Provide an iterator on NetDir that returns the hsdirs
* Implement Netdir::compute_rings in terms of a new
HsDirRing::compute, that currently does nothing.
* Actually call Netdir::compute_rings (since now it doesn't panic).
* Make Netdir::compute_rings not be pub. We do this unconditionally,
rather than exposing the distinction between a netdir-without-hsdir
and a netdir-with-hsdir.
The file which contains this type is called hsdir_params.rs. We have
a general problem with slight confusion about when to includen "dir"
and when to include "ring".
Resolve this in favour of the rule now added to the module-level doc
comment.
These variables are going to be struct fields, which will sort of
enforce consistent naming. The struct fields are going to appear in a
moment. We'll call the fields "current" and "secondary" after the
naming in the test cases.
And import hsdir_params::HsRingParams, which we're going to make more
references to.
* Remove the return value, which was not used anywhere.
Also remove the code to calculate the return value.
* Take an Arc<NetDir> rather than a reference. We are going to want
this for HS support. This has no overall effect on the lifetime of
the4 Arc, which was owned at the one call site and then imediately
dropped.
* Change the documentation to explain what the function's role is in
the netdir API, rather than the fiddly details of what it actually
does internally. Relegate the latter to a code comment.
(When we have HS, this will do more, or, at least, make further
arrangements.)
Locally, the only functional effect is that now we refuse to handle
non-whole-number-of-minutes lengths - but since the consensus
parameter can't represent those, there's no overall functional change.
We need to make sure any `#[cfg(feature=...)]` attributes are
applied not only to our variant declarations, but also to the
branches in the match statements that deal with them.