In an effort to publish early and often, my bug7144branch contains an implementation of this which is not quite finished yet. There are some unittests in there for the added code (but only ~60% coverage of the new code so far).
Note that we'll need to remember to revise consider_testing_reachability() and dirserv_single_reachability_test() to not use random middle nodes to connect to bridges when testing their reachability. (Otherwise all this work for bridge guards is still a bit wasted.)
Also, I've diverged slightly from prop!#188 (closed): rather than sending a CREATE_FAST cell to the bridge guard, we use circuit_should_use_create_fast_for_circuit() (which has been slightly modified) to attempt to do use the same CREATE* cell type as a normal client.
My latest code is in my bug7144_r1branch. I know it's a lot of code, and I apologise for that… but if you review it, I'll buy you a beverage of your choice at the next dev meeting. :)
Review is happening on this experimental Phabricator instance that doesn't belong to us and is probably going to eat all the data: https://phablab.krautspace.de/D1
Because the data is going to get eaten, I just wanted to archive this:
I hope it was okay to for me to merge that! I felt like I shouldn't merge my own commits… then I thought it'd be okay because it's only documentation and it's now sort of "my" proposal. In the end, I decided that it was probably okay, since it seems easier for others to audit my code and follow my specification side-by-side — with the spec already updated — than needing to review both separately. If this was not okay, please let me know, and I'll revert my commit and never do that again.
The changes include:
ADD a new section detailing loose-source routed circuits, including:
How the circuit should appear to the OP, the bridge, and the
bridge guard,
How the hop(s) in the path is/are chosen,
How the first hop is handled and how circuit extension is
handled, in a generalised sense (i.e. not specific to a bridge
using bridge guards),
Which cell types are used and how they are chosen,
When the original create cell is answered (in relation to when
cells are sent to the other additional hops),
What should be done when relay cells are received when the
additional hops in the loose-source routed circuit are not
fully constructed,
How the circuit crypto and cell digests for incoming/outgoing
relay cells works (again, in a generalised sense, i.e. not
specific to bridges using bridge guards),
How and whether a given relay cell is treated as "recognized",
Under what circumstances (based on whether a stream is attached
and which relay command was sent) should cause a node which
uses loose-source routed circuits to drop a relay cell or mark
a circuit for close, and,
When and what statistics should be gathered for loose-source
routed circuits.
UPDATE and clarify the example loose-source routed circuit
construction (the original one from the proposal which was specific
to a client using a bridge that uses bridge guards).
CHANGE the "Make it harder to tell clients from bridges" section
which described the tradeoffs between using CREATE versus
CREATE_FAST cells for the first additional hop (i.e. the bridge
guard). Those concerns is no longer entirely relevant, since, in
the meantime, we've introduced the NTor handshake and it's
extremely likely that both the client and the bridge will use
CREATE2 for all their hops.
ADD a new section on enumerating bridges via the behaviours
inherent to bridge reachability testing.
REMOVE open question (from the very end of the proposal) regarding
whether the standard guard selection algorithms are adequate. They
are. (Even if they are convoluted and overly-complicated.)