|
@@ -1430,9 +1430,7 @@ compute_frac_paths_available(const networkstatus_t *consensus,
|
|
|
smartlist_t *guards = smartlist_new();
|
|
|
smartlist_t *mid = smartlist_new();
|
|
|
smartlist_t *exits = smartlist_new();
|
|
|
- smartlist_t *myexits= smartlist_new();
|
|
|
- smartlist_t *myexits_unflagged = smartlist_new();
|
|
|
- double f_guard, f_mid, f_exit, f_myexit, f_myexit_unflagged;
|
|
|
+ double f_guard, f_mid, f_exit;
|
|
|
double f_path = 0.0;
|
|
|
/* Used to determine whether there are any exits in the consensus */
|
|
|
int np = 0;
|
|
@@ -1494,75 +1492,89 @@ compute_frac_paths_available(const networkstatus_t *consensus,
|
|
|
* browsing (as distinct from hidden service web browsing). */
|
|
|
}
|
|
|
|
|
|
- /* All nodes with exit flag in ExitNodes option */
|
|
|
- count_usable_descriptors(&np, &nu, myexits, consensus, options, now,
|
|
|
- options->ExitNodes, USABLE_DESCRIPTOR_EXIT_ONLY);
|
|
|
- log_debug(LD_NET,
|
|
|
- "%s: %d present, %d usable",
|
|
|
- "myexits",
|
|
|
- np,
|
|
|
- nu);
|
|
|
-
|
|
|
- /* Now compute the nodes in the ExitNodes option where which we don't know
|
|
|
- * what their exit policy is, or we know it permits something. */
|
|
|
- count_usable_descriptors(&np, &nu, myexits_unflagged,
|
|
|
- consensus, options, now,
|
|
|
- options->ExitNodes, USABLE_DESCRIPTOR_ALL);
|
|
|
- log_debug(LD_NET,
|
|
|
- "%s: %d present, %d usable",
|
|
|
- "myexits_unflagged (initial)",
|
|
|
- np,
|
|
|
- nu);
|
|
|
-
|
|
|
- SMARTLIST_FOREACH_BEGIN(myexits_unflagged, const node_t *, node) {
|
|
|
- if (node_has_descriptor(node) && node_exit_policy_rejects_all(node)) {
|
|
|
- SMARTLIST_DEL_CURRENT(myexits_unflagged, node);
|
|
|
- /* this node is not actually an exit */
|
|
|
- np--;
|
|
|
- /* this node is unusable as an exit */
|
|
|
- nu--;
|
|
|
- }
|
|
|
- } SMARTLIST_FOREACH_END(node);
|
|
|
-
|
|
|
- log_debug(LD_NET,
|
|
|
- "%s: %d present, %d usable",
|
|
|
- "myexits_unflagged (final)",
|
|
|
- np,
|
|
|
- nu);
|
|
|
-
|
|
|
f_guard = frac_nodes_with_descriptors(guards, WEIGHT_FOR_GUARD);
|
|
|
f_mid = frac_nodes_with_descriptors(mid, WEIGHT_FOR_MID);
|
|
|
f_exit = frac_nodes_with_descriptors(exits, WEIGHT_FOR_EXIT);
|
|
|
- f_myexit= frac_nodes_with_descriptors(myexits,WEIGHT_FOR_EXIT);
|
|
|
- f_myexit_unflagged=
|
|
|
- frac_nodes_with_descriptors(myexits_unflagged,WEIGHT_FOR_EXIT);
|
|
|
|
|
|
log_debug(LD_NET,
|
|
|
- "f_exit: %.2f, f_myexit: %.2f, f_myexit_unflagged: %.2f",
|
|
|
- f_exit,
|
|
|
- f_myexit,
|
|
|
- f_myexit_unflagged);
|
|
|
-
|
|
|
- /* If our ExitNodes list has eliminated every possible Exit node, and there
|
|
|
- * were some possible Exit nodes, then instead consider nodes that permit
|
|
|
- * exiting to some ports. */
|
|
|
- if (smartlist_len(myexits) == 0 &&
|
|
|
- smartlist_len(myexits_unflagged)) {
|
|
|
- f_myexit = f_myexit_unflagged;
|
|
|
- }
|
|
|
+ "f_guard: %.2f, f_mid: %.2f, f_exit: %.2f",
|
|
|
+ f_guard,
|
|
|
+ f_mid,
|
|
|
+ f_exit);
|
|
|
|
|
|
smartlist_free(guards);
|
|
|
smartlist_free(mid);
|
|
|
smartlist_free(exits);
|
|
|
- smartlist_free(myexits);
|
|
|
- smartlist_free(myexits_unflagged);
|
|
|
-
|
|
|
- /* This is a tricky point here: we don't want to make it easy for a
|
|
|
- * directory to trickle exits to us until it learns which exits we have
|
|
|
- * configured, so require that we have a threshold both of total exits
|
|
|
- * and usable exits. */
|
|
|
- if (f_myexit < f_exit)
|
|
|
- f_exit = f_myexit;
|
|
|
+
|
|
|
+ if (options->ExitNodes) {
|
|
|
+ double f_myexit, f_myexit_unflagged;
|
|
|
+ smartlist_t *myexits= smartlist_new();
|
|
|
+ smartlist_t *myexits_unflagged = smartlist_new();
|
|
|
+
|
|
|
+ /* All nodes with exit flag in ExitNodes option */
|
|
|
+ count_usable_descriptors(&np, &nu, myexits, consensus, options, now,
|
|
|
+ options->ExitNodes, USABLE_DESCRIPTOR_EXIT_ONLY);
|
|
|
+ log_debug(LD_NET,
|
|
|
+ "%s: %d present, %d usable",
|
|
|
+ "myexits",
|
|
|
+ np,
|
|
|
+ nu);
|
|
|
+
|
|
|
+ /* Now compute the nodes in the ExitNodes option where which we don't know
|
|
|
+ * what their exit policy is, or we know it permits something. */
|
|
|
+ count_usable_descriptors(&np, &nu, myexits_unflagged,
|
|
|
+ consensus, options, now,
|
|
|
+ options->ExitNodes, USABLE_DESCRIPTOR_ALL);
|
|
|
+ log_debug(LD_NET,
|
|
|
+ "%s: %d present, %d usable",
|
|
|
+ "myexits_unflagged (initial)",
|
|
|
+ np,
|
|
|
+ nu);
|
|
|
+
|
|
|
+ SMARTLIST_FOREACH_BEGIN(myexits_unflagged, const node_t *, node) {
|
|
|
+ if (node_has_descriptor(node) && node_exit_policy_rejects_all(node)) {
|
|
|
+ SMARTLIST_DEL_CURRENT(myexits_unflagged, node);
|
|
|
+ /* this node is not actually an exit */
|
|
|
+ np--;
|
|
|
+ /* this node is unusable as an exit */
|
|
|
+ nu--;
|
|
|
+ }
|
|
|
+ } SMARTLIST_FOREACH_END(node);
|
|
|
+
|
|
|
+ log_debug(LD_NET,
|
|
|
+ "%s: %d present, %d usable",
|
|
|
+ "myexits_unflagged (final)",
|
|
|
+ np,
|
|
|
+ nu);
|
|
|
+
|
|
|
+ f_myexit= frac_nodes_with_descriptors(myexits,WEIGHT_FOR_EXIT);
|
|
|
+ f_myexit_unflagged=
|
|
|
+ frac_nodes_with_descriptors(myexits_unflagged,WEIGHT_FOR_EXIT);
|
|
|
+
|
|
|
+ log_debug(LD_NET,
|
|
|
+ "f_exit: %.2f, f_myexit: %.2f, f_myexit_unflagged: %.2f",
|
|
|
+ f_exit,
|
|
|
+ f_myexit,
|
|
|
+ f_myexit_unflagged);
|
|
|
+
|
|
|
+ /* If our ExitNodes list has eliminated every possible Exit node, and there
|
|
|
+ * were some possible Exit nodes, then instead consider nodes that permit
|
|
|
+ * exiting to some ports. */
|
|
|
+ if (smartlist_len(myexits) == 0 &&
|
|
|
+ smartlist_len(myexits_unflagged)) {
|
|
|
+ f_myexit = f_myexit_unflagged;
|
|
|
+ }
|
|
|
+
|
|
|
+ smartlist_free(myexits);
|
|
|
+ smartlist_free(myexits_unflagged);
|
|
|
+
|
|
|
+ /* This is a tricky point here: we don't want to make it easy for a
|
|
|
+ * directory to trickle exits to us until it learns which exits we have
|
|
|
+ * configured, so require that we have a threshold both of total exits
|
|
|
+ * and usable exits. */
|
|
|
+ if (f_myexit < f_exit)
|
|
|
+ f_exit = f_myexit;
|
|
|
+ }
|
|
|
|
|
|
/* if the consensus has no exits, treat the exit fraction as 100% */
|
|
|
if (router_have_consensus_path() != CONSENSUS_PATH_EXIT) {
|