If a complete circuit C2 doesn't obey the restrictions of C1, then
C2 cannot block C1.
The patch here is a little big-ish, since we can no longer look
through all the complete circuits and all the waiting circuits on a
single pass: we have to find the best waiting circuit first.
This is an important thing I hadn't considered when writing prop271:
sometimes you have to restrict what guard you use for a particular
circuit. Most frequently, that would be because you plan to use a
certain node as your exit, and so you can't choose that for your
guard.
This change means that the upgrade-waiting-circuits algorithm needs
a slight tweak too: circuit A cannot block circuit B from upgrading
if circuit B needs to follow a restriction that circuit A does not
follow.
I had been asking myself, "hey, doesn't the new code need to look at
this "info" parameter? The old code did!" But it turns out that the
old code hasn't, since 05f7336624.
So instead of "support this!" the comment now says "we can remove
this!"
George pointed out that (-1,0,1) for (never usable, maybe usable
later, usable right now) was a pretty rotten convention that made
the code harder to read.
Here we handle most (all?) of the remaining tasks, and fix some
bugs, in the prop271 bridge implementation.
* We record bridge identities as we learn them.
* We only call deprecated functions from bridges.c when the
deprecated guard algorithm is in use.
* We update any_bridge_descriptors_known() and
num_bridges_usable() to work correctly with the new backend
code. (Previously, they called into the guard selection logic.
* We update bridge directory fetches to work with the new
guard code.
* We remove some erroneous assertions where we assumed that we'd
never load a guard that wasn't for the current selection.
Also, we fix a couple of typos.
Still missing is functionality for picking bridges when we don't
know a descriptor for them yet, and functionality for learning a
bridge ID.
Everything else remains (basically) the same. Neat!
This includes:
* making bridge_info_t exposed but opaque
* allowing guards where we don't know an identity
* making it possible to learn the identity of a guard
* creating a guard that lacks a node_t
* remembering a guard's address and port.
* Looking up a guard by address and port.
* Only enforcing the rule that we need a live consensus to update
the "listed" status for guards when we are not using bridges.
This is safe, because no entry_guard_t ever outlives its
guard_selection_t.
I want this because now that multiple guard selections can be active
during one tor session, we should make sure that any information we
register about guards is with respect to the selection that they came
from.
Currently, this code doesn't actually have the contexts behave
differently, (except for the legacy context), but it does switch
back and forth between them nicely.
If a guard becomes primary as a result of confirming it, consider
the circuit through that guard as a primary circuit.
Also, note open questions on behavior when confirming nonprimary guards
Some of these will get torrc options to override them too; this
is just the mechanical conversion.
Also, add documentation for a couple of undocumented (but now used)
parameters.
To do this, it makes sense to treat legacy guards as a separate
guard_selection_t *, and handle them separately. This also means we
add support here for having multiple guard selections.
Note that we don't persist pathbias information yet; that will take
some refactoring.
This patch doesn't cover every case; omitted cases are marked with
"XXXX prop271", as usual. It leaves both the old interface and the
new interface for guard status notification, since they don't
actually work in the same way: the new API wants to be told when a
circuit has failed or succeeded, whereas the old API wants to know
when a channel has failed or succeeded.
I ran into some trouble with directory guard stuff, since when we
pick the directory guard, we don't actually have a circuit to
associate it with. I solved that by allowing guard states to be
associated with directory connections, not just circuits.
I expect we'll be ripping this out somewhere in 0.3.0, but let's
keep it around for a little while in case it turns out to be the
only way to avert disaster?
This state corresponds to the WAITING_FOR_BETTER_GUARD state; it's
for circuits that are 100% constructed, but which we won't use until
we are sure that we wouldn't use circuits with a better guard.
When a nonprimary guard's circuit is complete, we don't call it
actually usable until we are pretty sure that every better guard
is indeed not going to give us a working circuit.
Here we add a little bit of state to origin circuits, and set up
the necessary functions for the circuit code to call in order to
find guards, use guards, and decide when circuits can be used.
There's also an incomplete function for the hard part of the
circuit-maintenance code, where we figure out whether any waiting
guards are ready to become usable.
(This patch finally uses the handle.c code to make safe handles to
entry_guard_t objects, so that we are allowed to free an
entry_guard_t without checking whether any origin_circuit_t is
holding a reference to it.)
This code handles:
* Maintaining the sampled set, the filtered set, and the
usable_filtered set.
* Maintaining the confirmed and primary guard lists.
* Picking guards for circuits, and updating guard state when
circuit state changes.
Additionally, I've done code structure movement: even more constants
and structures from entrynodes.c have become ENTRYNODES_PRIVATE
fields of entrynodes.h.
I've also included a bunch of documentation and a bunch of unit
tests. Coverage on the new code is pretty high.
I've noted important things to resolve before this branch is done
with the /XXXX.*prop271/ regex.
These are taken from the proposal, and defined there. Some of them
should turn into consensus parameters.
Also, remove some dead code that was there to make compilation work,
and use ATTR_UNUSED like a normal person.
The previous commit, in moving a bunch of functions to bridges.c,
broke compilation because bridges.c required two entry points to
entrynodes.c it didn't have.
This patch is just:
* Code movement
* Adding headers here and there as needed
* Adding a bridges_free_all() with a call to it.
It breaks compilation, since the bridge code needed to make exactly
2 calls into entrynodes.c internals. I'll fix those in the next
commit.
The encoding code is very straightforward. The decoding code is a
bit tricky, but clean-ish. The sampling code is untested and
probably needs more work.