This code deviates from current tor in that it allows missing
sendme authentications only when we know we're talking to an old
relay, or when we don't know the version of the relay we're talking
to.
There's a problem, though: this code assumes that tags are 20 bytes
long whereas actually the tag type is part of the crypto layer info.
So maybe in the long term we need to move the queue of tags from the
send window into being part of the crypto layers.
This is incomplete because the cell crypto code doesn't actually
expose tags yet, and because it demands tags unconditionally,
without caring about the linkspec protocol version.
This was a hard one. I need to make sure that we send an END cell
when the stream is dropped. But we can't call an .await from inside
the drop() function, since drop() isn't async, and we don't have an
executor.
Fortunately, you can call send() on a oneshot::Sender without having
to await on it, so that's the obvious thing to put in drop(). But
we need some way to make sure that the oneshot::Receiver is given to
the reactor, and is .awaited. For that, we needed a control
channel. And the reactor needs to treat the control channel and the
close messages as equally important.
So that's how I wound up with a
Fuse<Select<mpsc::Receiver<Result<Foo>>,
SelectAll<Once<oneshot::Receiver<Foo>>>>>.
I doubt that this is actually the best way to handle any of this!
By putting the cell-sink in a box, we can get rid of the need for
having everything that uses a channel or a circuit know what kind
of underlying TLS implementation it has.
Found by fuzzing! The issue was that we were relying on the
arguments slice being within the input string, but we were sometimes
using a different _empty_ slice when there were no arguments.
I've noted a better solution in a comment.