Opened 4 years ago

Closed 16 months ago

#12595 closed task (fixed)

Finalize design for improved guard-node behavior

Reported by: asn Owned by: asn
Priority: High Milestone: Tor: 0.3.0.x-final
Component: Core Tor/Tor Version: Tor: 0.2.7
Severity: Normal Keywords: tor-guard, TorCoreTeam201608, 028-triaged, mike-can, prop259, tor-guards-revamp, TorCoreTeam201612
Cc: starlight.2015q2@…, isis, *@…, andrea, yawning, asn Actual Points:
Parent ID: Points: 3
Reviewer: Sponsor: SponsorU-must

Description

Bugs like #12466 and #12450 have made it clear that the data structures and methods of the guard nodes code are not very robust. To fix those tickets with the current data structures, we would need even more kludges that would lower the code quality.

This is a ticket about finding a more elegant approach to keeping entry guards and directory guards.

I'm putting this in 0.2.6 milestone because it's important, but it might get deferred if it's too much work.

Child Tickets

TicketStatusOwnerSummaryComponent
#19468closednickmRevise prop259 to fit the Tor networking APICore Tor/Tor

Attachments (1)

entry_guard_list.jpg (272.5 KB) - added by asn 4 years ago.

Download all attachments as: .zip

Change History (50)

comment:1 Changed 4 years ago by asn

One of the possible designs discussed during the dev meeting, is to have two guard lists. One list is the entry_guards list, and the other is the directory_guards list.

The idea is that if your primary entry guard is not a directory cache, then you use the directory_guards list to get a directory guard. Or maybe you just use the directory_guards list for all your directory needs anyway. Also, in the future when #12597 becomes totally deployed, we will be able to move to a single list, where all nodes will be both directory guards and entry guards.

Some more ideas that were thrown around during the dev meeting, and would make guard selection smoother:

  • All guards should be directory caches which will happen as part of #12597.
  • All guards should be considered fast/stable, or Relays can be guards iff they are fast/stable. This will make it more likely that guards on the top of our list can be used for our purposes, since we will not have to skip guards till we find a stable guard for stable circuits. However, because of the analysis in #12204, this is not very likely to happen anyway.

Also, it's worth noting that designing data structures with the assumption that we are only going to have 1 primary guard is probably easier than designing data structures that can accommodate N primary guards.

comment:2 in reply to:  1 Changed 4 years ago by nickm

Replying to asn:

One of the possible designs discussed during the dev meeting, is to have two guard lists. One list is the entry_guards list, and the other is the directory_guards list.

Seems plausible to me.

Some more ideas that were thrown around during the dev meeting, and would make guard selection smoother:

  • All guards should be directory caches which will happen as part of #12597.

Remember that we can't rely on "All guards are directory caches" until all server versions before 0.2.6 are obsolete.

  • All guards should be considered fast/stable, or Relays can be guards iff they are fast/stable. This will make it more likely that guards on the top of our list can be used for our purposes, since we will not have to skip guards till we find a stable guard for stable circuits. However, because of the analysis in #12204, this is not very likely to happen anyway.

"All guards should be considered fast/stable" seems okay to me, unless I'm missing something.

Also, it's worth noting that designing data structures with the assumption that we are only going to have 1 primary guard is probably easier than designing data structures that can accommodate N primary guards.

Hmmm. No, I don't agree with that one. We need to have some notion of what we're going to do when we move back and forth between versions of Tor that use the old state file and the new one. We should also know what to do when our main guard is down for a while, then comes back up. I think that the data structure we need to handle both of those problems will be not too far from the one that we would need to keep support for N guards.

Changed 4 years ago by asn

Attachment: entry_guard_list.jpg added

comment:3 Changed 4 years ago by asn

Some more thoughts on the new data structures:

I wonder if this behavior is any different from the corresponding
behavior of circuit guards: "If our circuit guard fails our circuit,
we have to go ahead and ask the next circuit guard"

If not, maybe we could just switch NumDirectoryGuards to 1 too, and
just make sure that if a microdescriptor gets denied we move to the
next directory guard, till we have enough microdescriptor to be happy?
(logic similar to compute_frac_paths_available()).

With the current code, and if NumDirectoryGuards was 3, from the
first entry guard list we would select a directory guard between
(entry2, entry4, entry6). On the second list, we would select
between (entry1, entry4, entry6). On the third list, the worst case
scenario, we would select between (entry4, entry5, ...).

I'd argue that we should strongly prefer the *top* directory guard
every time, and only move to the lower ones if the top one doesn't
give us what we want.


comment:4 in reply to:  3 Changed 4 years ago by asn

Replying to asn:

With the current code, and if NumDirectoryGuards was 3, from the
first entry guard list we would select a directory guard between
(entry2, entry4, entry6). On the second list, we would select
between (entry1, entry4, entry6). On the third list, the worst case
scenario, we would select between (entry4, entry5, ...).

I'd argue that we should strongly prefer the *top* directory guard
every time, and only move to the lower ones if the top one doesn't
give us what we want.

My point here was that NumEntryGuards and NumDirectoryGuards probably does not work the way people expect it to work.

In the current code, NumDirectoryGuards (and NumEntryGuards) being 3 means that Tor needs to have 3 choices when picking a entry/directory guard. This means, that Tor will go as deep as needed in the guard list till it gets 3 nodes that satisfy the circuit requirements. This means that Tor might pick between the first, the second and the 25th entry guard, if the circuit requirements are such. This is what causes #12466.

OTOH, when I think of "Tor has 3 entry guards", I'm thinking that Tor will try its best to push traffic through one of three static nodes; but this is not what the current behavior does. To do that, we would need to have a concept of "primary guards" (maybe the top 3 guards in the guard list), and Tor would have to make sure that all traffic (including directory traffic) can be pushed through one of those 3 guards.

All these concepts are hairy and weird. Moving to a single entry/directory guard will simplify the logic here.

comment:5 Changed 4 years ago by asn

Another thing that the new data structures should fix is the #12450 behavior. That is, the part of Tor that figures out that the net was disabled and just came back up, and hence we need to retry our previous guards.

Currently, the logic is as follows:

https://gitweb.torproject.org/tor.git/blob/d064773595f1d0bf1b76dd6f7439bff653a3c8ce:/src/or/entrynodes.c#l776

If we just added a new entry guard to our list and we managed to connect to it, then we assume that the network just came back up: we enable the can_retry field of all previous guards and kill the current connection to the new guard. Then we retry guards from the beginning.

The assumption here is that since we had to add a new entry guard to the list we have already exhausted all the already existing entry guards, and hence we had a network down scenario.

This assumption is OK but not complete since it does not consider some edge cases

As an example, it causes the #12450 bug, where the network comes back up before we exhaust all the already existing entry guards. Since we didn't have to add a new entry guard to the list, the network up event is not detected and we keep on using that entry guard we ended up with.

The new data structures and methods should take this into account.


There are various kludg^Wways to fix this issue. Some ideas:

a) Everytime we manage to connect to a guard, if it's not the first guard in our list, we mark all previous guards as retriable, and try from the top.
b) Everytime we manage to connect to a guard, if we have previously failed to connect to other guards in this session, we mark all other guards as retriable and try from the top.
c) Everytime we manage to connect to a guard, if we have previously failed to connect to a guard in this session, we mark those previously attempted guards as retriable and try from the top.

All the above ideas will also need some way to stop them from infinite looping.


From the above ideas, I can see some problems with (b) and (c) because its memory is restricted to a single session. Example: Network goes down, Tor tries some guards and marks them as unreachable. Tor gets shut down. Tor starts up again when the network is back up, manages to connect to a guard and stays with that guard (which is not the top one).

(a) is a bit more bulletproof since it will always try to use the top guards, but it also has its problems. First of all, there needs to be a system to stop it from infinite looping, since if your first guard is actually down, we shouldn't keep on retrying it.

Assuming that there is some sort of infinite loop protection, you can imagine the following (unlikely) race condition problem. Tor starts up, network down, Tor tries various guards. Network goes up and we connect to a guard. We notice that network goes up, and we mark all previous guards as retriable. Before starting from the top, network goes down again, Tor finds the first few guards unreachable, and then network goes up again and we connect to the entry guard we were examining at that point (which is not the top one).

Furthermore, it's worth having in mind that such probing behaviors can also act as a guard fingerprint (similar to #10969). For example, let's assume the (a) behavior and assume that the first two guards of your entry guard list are actually down (quite common). Everytime you mark your guards as retriable and go from the top, you will also probe those two entry guards that are down. Your ISP will be able to see both of those probes plus the connection to the third guard that actually succeeds. These three connections should be enough to form a fingerprint.

Guess what, more research is needed.

comment:6 in reply to:  5 Changed 4 years ago by asn

Replying to asn:

There are various kludg^Wways to fix this issue. Some ideas:

a) Everytime we manage to connect to a guard, if it's not the first guard in our list, we mark all previous guards as retriable, and try from the top.
b) Everytime we manage to connect to a guard, if we have previously failed to connect to other guards in this session, we mark all other guards as retriable and try from the top.
c) Everytime we manage to connect to a guard, if we have previously failed to connect to a guard in this session, we mark those previously attempted guards as retriable and try from the top.

All the above ideas will also need some way to stop them from infinite looping.

FWIW, the kludges above are needed because we don't have a "Is my network down?" primitive.
And since we don't have such a primitive, we can't distinguish between "Guard is marked unreachable because it was down" and "Guard is marked unrecahble because the network was down". If we could distinguish between those two cases, then this task would be much easier.

Is there a way to build such a primitive in a secure and scaleable fashion? For example, we could imagine that clients ping the authorities to check if their network is up. But this puts more load to the authorities and it doesn't scale well.

comment:7 in reply to:  3 ; Changed 4 years ago by nickm

Replying to asn:

Some more thoughts on the new data structures:

Seems plausible to me.

I wonder if this behavior is any different from the corresponding
behavior of circuit guards: "If our circuit guard fails our circuit,
we have to go ahead and ask the next circuit guard"

If not, maybe we could just switch NumDirectoryGuards to 1 too, and
just make sure that if a microdescriptor gets denied we move to the
next directory guard, till we have enough microdescriptor to be happy?
(logic similar to compute_frac_paths_available()).

Watch out there. "compute_frac_paths_available()" still allows some epistemic bias. It only insists that we have a large proportion of possible microdescriptors before we're happy enough to build circuits, not that we have all of them. That's not such a big deal with multiple noncolluding directory guards, but with only one guard, it's possibly trouble.

With the current code, and if NumDirectoryGuards was 3, from the
first entry guard list we would select a directory guard between
(entry2, entry4, entry6). On the second list, we would select
between (entry1, entry4, entry6). On the third list, the worst case
scenario, we would select between (entry4, entry5, ...).

I'd argue that we should strongly prefer the *top* directory guard
every time, and only move to the lower ones if the top one doesn't
give us what we want.

"Strongly prefer" seems good; can we turn this into an algorithm?

Reading through all of the above stuff, in fact, I think that the right way to approach design here might be to step back from the "what is the right data structure" question and ask ourselves, "what interface must these algorithms expose, and how should they implement it?" IOW, can we enumerate their inputs and outputs, the events that affect them, and the operations they need to perform? If we figure that out, we should be able to examine some ideas in pseudocode and converge on something clever.

comment:8 in reply to:  7 Changed 4 years ago by asn

Replying to nickm:

Replying to asn:

Some more thoughts on the new data structures:

Seems plausible to me.

I wonder if this behavior is any different from the corresponding
behavior of circuit guards: "If our circuit guard fails our circuit,
we have to go ahead and ask the next circuit guard"

If not, maybe we could just switch NumDirectoryGuards to 1 too, and
just make sure that if a microdescriptor gets denied we move to the
next directory guard, till we have enough microdescriptor to be happy?
(logic similar to compute_frac_paths_available()).

Watch out there. "compute_frac_paths_available()" still allows some epistemic bias. It only insists that we have a large proportion of possible microdescriptors before we're happy enough to build circuits, not that we have all of them. That's not such a big deal with multiple noncolluding directory guards, but with only one guard, it's possibly trouble.

Yep, we should be careful.

I was thinking of an algorithm like this:

Fetch all mds from first dirguard
If all mds got fetched successfully:
   Done!

else:
   # If any mds got denied try next dirguard (even if we have enough dir info )
   while True: # Keep on asking other dirguards till we have enough dir info
     Get missing mds from the next dirguard
     if have_minimum_dir_info():
        Done

Which would basically ensure that we have tried at least two dirguards if the first one didn't serve us all the microdescriptors we were looking for. After we have asked two dirguards, we exit when we get enough directory info.

I guess the idea is that the first dirguard might lie, but the probability of both dirguards lying is less. The algorithm can also be adapted to ask the first three dirguards (if we prefer the number 'three' instead of 'two').

I think this kind of algorithm ("Try guards sequentially till you get what you want") is a better approach than "Choose between the 3 top currently active guards in your list." since it avoids bugs like #12466.

A big engineering problem with this idea, is that the networking logic of Tor is probably not ready to support this feature and will require non-trivial changes. For example, we will need some kind of logic that marks dirguards as skippable if they failed to deliver a microdescriptor, and then the next dirguard query would use the next guard. I can imagine implementation of this feature to get quite complicated.

To better understand whether such an algorithm would work (and how often it would need to ask more dirguards), we need to check how frequent microdescriptor fetch failures are in the wild right now.

Also, maybe it makes sense to write a proposal with the ideas from:
https://lists.torproject.org/pipermail/tor-dev/2014-June/006944.html
https://lists.torproject.org/pipermail/tor-dev/2014-June/006945.html
and then try to implement it along with #12538, so that we eventually get rid of this issue:

...
If the above is the only case, we can fix it by making sure that
directory servers start serving a consensus _only after_ they have
downloaded the descriptors of all the routers mentioned in that
consensus.
...

comment:9 in reply to:  7 Changed 4 years ago by asn

Replying to nickm:

Replying to asn:

With the current code, and if NumDirectoryGuards was 3, from the
first entry guard list we would select a directory guard between
(entry2, entry4, entry6). On the second list, we would select
between (entry1, entry4, entry6). On the third list, the worst case
scenario, we would select between (entry4, entry5, ...).

I'd argue that we should strongly prefer the *top* directory guard
every time, and only move to the lower ones if the top one doesn't
give us what we want.

"Strongly prefer" seems good; can we turn this into an algorithm?

My idea was the following "simple" algorithm:

node_t choose_live_circuit_guard(restrictions) {
  foreach guard in guard_list:
    if guard.should_be_used_as_circuit_guard():
      return guard

  # No guard was found
  return find_and_add_new_guard()
}

and

node_t choose_live_directory_guard(restrictions) {
  foreach guard in guard_list:
    if guard.should_be_used_as_dir_guard():
      return guard

  # No guard was found
  return find_and_add_new_guard()
}

where should_be_used_as_circuit_guard() is basically the requirements in:
https://gitweb.torproject.org/tor.git/blob/HEAD:/src/or/entrynodes.c#l1077

should_be_used_as_directory_guard() is the same requirements as above plus any restrictions from my previous comment (comment:8) if we decide it's a good idea.

and find_and_add_new_guard() would basically be like tor's add_an_entry_guard() with chosen set to NULL.

The idea is to basically use the guard list as a conveyor belt, and if no items in the conveyor belt can satisfy us append a new one.

Last edited 4 years ago by asn (previous) (diff)

comment:10 in reply to:  7 Changed 4 years ago by asn

Replying to nickm:

Reading through all of the above stuff, in fact, I think that the right way to approach design here might be to step back from the "what is the right data structure" question and ask ourselves, "what interface must these algorithms expose, and how should they implement it?" IOW, can we enumerate their inputs and outputs, the events that affect them, and the operations they need to perform? If we figure that out, we should be able to examine some ideas in pseudocode and converge on something clever.

I agree that this will be helpful.

When I started thinking about this problem, I wanted to formalize it
but I quickly found myself unsure of how much formalization is
actually productive here.

I found it helpful to think of this as an OOP system. I thought of a
class called Guard and a class called GuardList:

A Guard is basically a Tor node plus some metadata about it. Using
the metadata you can answer questions like "is it fast?", "is it
dir?", "was it unreachable?", "should we retry?", "is it too old?".

A GuardList contains many Guard objects and knows how to select
between them. It basically acts as a conveyor belt for them.

The main interface to the guard subsystem that Tor needs to use are
the functions that return entry guards and directory guards. In the
current codebase, this is choose_random_entry_impl().

We can imagine this function as a method of the GuardList that does
something similar to what was described in comment:9: it takes as
input some restrictions (the type of the circuit, the exit node
family, whether bridges are used etc.) and outputs a node that can be
used (or NULL if nothing could be found). The method has side-effects,
since the guard list might need to be extended to find a suitable
node.

Some more methods of the guard list could be:

  • load_guards(), which loads guards from the torrc and state file.
  • save_guards(), which saves guards to the state file.
  • refresh(), which kills old/bad guards based on a newly arrived

consensus (see entry_guards_compute_status())

  • network_is_back_up(), which is the "network up" trigger (see comment:5)
  • stuff like add_guard(), remove_guard(), get_num_guards(), etc.

Continuing with comment:9, the main methods of the Guard class would
be:
bool should_be_used_as_dir_guard(restrictions) and
bool should_be_used_as_circuit_guard(restrictions)

These methods take a look at the latest consensus, the metadata of
each guard and the restrictions imposed, to figure out whether a Guard
can be used as a guard *right now*. These methods will be used by the
GuardList when choosing a guard node.

Now, here are various events that need to be taken into account:

  • The network is down! (comment:5)
  • Directory guard does not have descriptor X (comment:8)
  • Top circuit guard is not a directory.
  • Guard used to be OK, but now: is not a guard anymore

is not a directory
is path bias disabled
is in the same family as exit
is too old
is an excluded node

Any suggestions on how I should be looking at this better?

Last edited 4 years ago by asn (previous) (diff)

comment:11 Changed 4 years ago by nickm

Keywords: 026-triaged-1 added

comment:12 Changed 3 years ago by nickm

Priority: normalmajor

comment:13 Changed 3 years ago by nickm

Milestone: Tor: 0.2.6.x-finalTor: 0.2.7.x-final

comment:14 Changed 3 years ago by nickm

Status: newassigned

comment:15 Changed 3 years ago by nickm

Keywords: 027-triaged-1-in added

Marking more tickets as triaged-in for 0.2.7

comment:16 Changed 3 years ago by isabela

Keywords: SponsorU added
Points: medium
Version: Tor: 0.2.7

comment:17 Changed 3 years ago by nickm

opening https://etherpad.mozilla.org/HsR7ubjcUC for brainstorming here. We should copy it down if it comes up with anything good.

comment:18 Changed 3 years ago by asn

Another thing that needs more work here, is to improve our detection of failing guards. That is, should we consider a guard to be down when a single CREATE cell fails through it, or should we be more flexible here?

comment:19 Changed 3 years ago by nickm

Keywords: TorCoreTeam201507 added

comment:20 Changed 3 years ago by starlight

Cc: starlight.2015q2@… added

comment:21 Changed 3 years ago by nickm

Keywords: TorCoreTeam201508 added; TorCoreTeam201507 removed
Owner: set to asn
Summary: Think of better data structures for guard nodesThink of better data structures and algorithms for guard nodes

comment:22 Changed 3 years ago by nickm

Keywords: TorCoreTeam201509 added; 026-triaged-1 027-triaged-1-in TorCoreTeam201508 removed
Summary: Think of better data structures and algorithms for guard nodesFinalize design for improved guard-node behavior

comment:23 Changed 3 years ago by nickm

Milestone: Tor: 0.2.7.x-finalTor: 0.2.8.x-final

comment:24 Changed 3 years ago by asn

An attempt for a better guard selection algorithm:

https://lists.torproject.org/pipermail/tor-dev/2015-August/009297.html

comment:25 Changed 3 years ago by nickm

Keywords: 028-triaged added

comment:26 Changed 3 years ago by nickm

Keywords: SponsorU removed
Sponsor: SponsorU

Bulk-replace SponsorU keyword with SponsorU field.

comment:27 Changed 3 years ago by mikeperry

Keywords: mike-can added

comment:28 Changed 3 years ago by isis

Cc: isis added
Severity: Normal

Related: #17261 #17262

comment:29 Changed 2 years ago by asn

Milestone: Tor: 0.2.8.x-finalTor: 0.2.9.x-final

Progress is being done here but no way we can fit it in 0.2.8.

Moving to next release.

comment:30 Changed 2 years ago by isabela

Sponsor: SponsorUSponsorU-must

comment:31 Changed 2 years ago by nickm

Keywords: TorCoreTeam201604 added; TorCoreTeam201509 removed

comment:32 Changed 2 years ago by nickm

Keywords: prop259 added

These are all prop259-related.

comment:33 Changed 2 years ago by nickm

Keywords: tor-guards-revamp added

comment:34 Changed 2 years ago by asn

Keywords: TorCoreTeam201605 added; TorCoreTeam201604 removed

comment:35 Changed 2 years ago by isabela

Points: medium3

comment:36 Changed 2 years ago by asn

Keywords: TorCoreTeam201606 added; TorCoreTeam201605 removed

comment:37 Changed 2 years ago by asn

Hello. Here is a small status report on this project.

Let me first mention the main problems of the current Tor guard algorithm that proposal 259 tries to address:

ISSUE1: The current Tor guard algorithm will attempt to connect to an infinite number of guards given enough time. This is a security issue, since a LAN adversary can firewall a Tor user until Tor eventually connects to an adversary-controlled entry guard. In prop259, we enforce an upper bound on the number of guards that Tor will ever attempt to connect to (a la prop241).

ISSUE2: There are various edge cases and race conditions where Tor will think that some guards are down, and connect to lower priority guards, even though the ones on the top are still up (e.g. bug #12450). While it's very hard to fix all these edge cases, proposal 259 aims to minimize the time Tor will spend connected to lower priority guards.

ISSUE3: The current Tor guard algorithm is completely unspecified and undocumented, making it very hard to fix issues and design improvements. With prop259 we aim to provide a proper algorithm specification (i.e. a documented state machine) that in the future could be modded to include various improvements (firewall heuristics, etc.). See [0] for a brief algorithm description.

The idea was also to produce clean, isolated and tested code that can be reused and extended with ease in the future (e.g. to do multiple layers of guards a la prop247). The current entry guard code is spaggheti and spewed all over the codebase.


State of prop259

You can find the latest version of proposal 259 here, and the thoughtworks crew has already implemented a PoC of it in the Tor codebase.

There is also a Python simulation of prop259, but I'm not sure what's its current state relative to the prop259 spec and the little-t-tor implementation. Ola and Reinaldo showed me some graphs of it in Valencia, that looked about what you would expect.

That said, IMO, both the design and the implementation need heavy improvements before we consider them for inclusion in our codebase:

The main problem with the prop259 design right now, is that the algorithm was not designed to support multiple parallel invocations of it, which is exactly what Tor does (multiple circuits can pick guards at the same time). This causes problems like "Prop259 algorithm invocation #2 does not learn the guard reachability information that invocation #1 knows, and has to try the same dead guards again".

It is my understanding that when the thoughtworks crew realized the above issue, they slightly changed the design such that one invocation of the algorithm can support multiple circuit creations. However, I feel this was done in a kludgy way on the implementation side. I feel that instead, the right way forward would be to refactor the state machine to support this usage model.

IMO, this is the main actual design change that needs to be done to the
algorithm. Also, the spec needs to be cleaned and simplified a bit (because it got edited multiple times by multiple people and there are ugly artifacts around), and some constants/states should be renamed to better names. I feel that fixing these issues properly should take about 2-4 days of thinking time.

I have not looked too deep at the implementation, but it seems like it's indeed implementing some version of proposal 259. The code is workable, but it's also undocumented in parts, and it also uses some non-standard coding idioms that we would need to fix. Fortunately, the state machine is well tested, and it seems to work without crashing on my system. I feel that if we revise the design in a way we are happy, then we can use the thoughtworks implementation as a good basis for our branch.


Ways forward

The righteous way:

  • I feel that the proper way to proceed here (if we could ignore deliverables, lack of engineers and funding issues) would be to finish up prop259, and implement it in Tor. Ideally, for the first months we would be able to run both algorithms in parallel and get statistics about them, so that we can actually test it in real life and evaluate its security.

The honest way:

  • If we don't have time to do the above, but we are still concerned about the security of our current guard selection (i.e. ISSUE1), we could make a quick hotfix for ISSUE1 in our current codebase. For example, we could modify choose_random_entry_impl() or pick_entry_guards() so that instead of sampling guards from the whole consensus, we use a restricted set of guards to sample from.

I imagine this is going to be easier to do than the righteous way, but also it will not help us at all with ISSUE2 and ISSUE3 which are also quite important (e.g. since we hope to implement prop247 as well).

The cheap way:

  • We already have a PoC of the current (incomplete) prop259: We have a branch for little-t-tor and a simulation in Python. I think this work could be enough to satisfy sponsor deliverables if we have no manpower to work on this. I don't actually want to take this approach, but we are all under fire from all sides... so dropping things shouldn't be forgotten as an option.

I'm currently unsure which approach should be taken here. I feel that more
people need to skim over prop259 before we decided that it's a good way forward, because me and the thoughtworks team are the only people who are actually familiar with it right now (and I'm already starting to forget it).


Footnotes

[0]:

With prop259, when Tor builds a circuit and needs a guard, Tor calls START() to initialize the prop259 algo for that particular circuit, and then it starts calling NEXT() to receive a candidate guard. Tor connects to the candidate guard, and updates the guard reachability state accordingly. If the candidate guard did not work, we go back to calling NEXT(). Otherwise, we call END() and the algorithm finishes successfuly.

Prop259 also specifies the behavior of Tor when it receives a new consensus.

Prop259 also specifies the already existing "network-up" heuristic of Tor when it manages to connect to a guard after long times of inactivity (see prop259 SHOULD_CONTINUE()). This heuristic is already implemented in Tor: see first_contact at entry_guard_register_connect_status().

comment:38 Changed 2 years ago by asn

[Please see ticket #19364 about implementing the outcome of this ticket in little-t-tor]

comment:39 Changed 2 years ago by U+039b

Cc: *@… added

comment:40 Changed 22 months ago by nickm

Proposal 271 now exists. I think we can start breaking it down to implement.

comment:41 in reply to:  40 Changed 22 months ago by asn

Replying to nickm:

Proposal 271 now exists. I think we can start breaking it down to implement.

And here is an initial implementation plan for prop271:
https://lists.torproject.org/pipermail/tor-dev/2016-July/011234.html

If someone does a basic sanity check on the implementation plan, I can try splitting it in tickets or sth.

comment:42 Changed 22 months ago by asn

Cc: andrea yawning added

comment:43 Changed 22 months ago by asn

Keywords: TorCoreTeam201608 added; TorCoreTeam201606 removed

comment:44 Changed 21 months ago by asn

Cc: asn added

comment:45 Changed 20 months ago by nickm

Keywords: TorCoreTeam201610 added
Milestone: Tor: 0.2.9.x-finalTor: 0.3.0.x-final

Defer target for these doc fixes to 0.3.0 (though of course they can go into 0.2.9 if they're done on time.)

comment:46 Changed 19 months ago by dgoulet

Keywords: TorCoreTeam201611 added; TorCoreTeam201610 removed

comment:47 Changed 17 months ago by dgoulet

Keywords: TorCoreTeam201612 added; TorCoreTeam201611 removed

Going to December!

comment:48 Changed 16 months ago by nickm

Type: defecttask

comment:49 Changed 16 months ago by nickm

Resolution: fixed
Status: assignedclosed
Note: See TracTickets for help on using tickets.