aboutsummaryrefslogtreecommitdiff
path: root/src/test/test_circuitbuild.c
diff options
context:
space:
mode:
authorDavid Goulet <dgoulet@torproject.org>2019-06-18 13:32:45 -0400
committerDavid Goulet <dgoulet@torproject.org>2019-06-19 07:42:30 -0400
commit16a0b7ed6779bf72a8a471c558a5e09084921d8b (patch)
tree16c7bf8cf75a30809d7a7319bb8cccc8f972af6c /src/test/test_circuitbuild.c
parent125a6300da5412ce5fb2c0506f699e653a7ea6dc (diff)
downloadtor-16a0b7ed6779bf72a8a471c558a5e09084921d8b.tar.gz
tor-16a0b7ed6779bf72a8a471c558a5e09084921d8b.zip
guard: Ignore marked for close circuit when changing state to open
When we consider all circuits in "waiting for guard" state to be promoted to an "open" state, we were considering all circuits, even the one marked for close. This ultiamtely triggers a "circuit_has_opened()" called on the circuit that is marked for close which then leads to possible undesirable behaviors within a subsystem. For instance, the HS subsystem would be unable to find the authentication key of the introduction point circuit leading to a BUG() warning and a duplicate mark for close on the circuit. This commit also adds a unit test to make sure we never select marked for close circuits when upgrading its guard state from waiting for guard to open. Fixes #30871 Signed-off-by: David Goulet <dgoulet@torproject.org>
Diffstat (limited to 'src/test/test_circuitbuild.c')
-rw-r--r--src/test/test_circuitbuild.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/src/test/test_circuitbuild.c b/src/test/test_circuitbuild.c
index 47218a559a..196d8cd355 100644
--- a/src/test/test_circuitbuild.c
+++ b/src/test/test_circuitbuild.c
@@ -4,6 +4,8 @@
/* See LICENSE for licensing information */
#define CIRCUITBUILD_PRIVATE
+#define CIRCUITLIST_PRIVATE
+#define ENTRYNODES_PRIVATE
#include "core/or/or.h"
#include "test/test.h"
@@ -13,7 +15,11 @@
#include "core/or/circuitbuild.h"
#include "core/or/circuitlist.h"
+#include "core/or/cpath_build_state_st.h"
#include "core/or/extend_info_st.h"
+#include "core/or/origin_circuit_st.h"
+
+#include "feature/client/entrynodes.h"
/* Dummy nodes smartlist for testing */
static smartlist_t dummy_nodes;
@@ -126,10 +132,51 @@ test_new_route_len_unhandled_exit(void *arg)
UNMOCK(count_acceptable_nodes);
}
+static void
+test_upgrade_from_guard_wait(void *arg)
+{
+ circuit_t *circ = NULL;
+ origin_circuit_t *orig_circ = NULL;
+ entry_guard_t *guard = NULL;
+ smartlist_t *list = NULL;
+
+ (void) arg;
+
+ circ = dummy_origin_circuit_new(0);
+ orig_circ = TO_ORIGIN_CIRCUIT(circ);
+ tt_assert(orig_circ);
+
+ orig_circ->build_state = tor_malloc_zero(sizeof(cpath_build_state_t));
+
+ circuit_set_state(circ, CIRCUIT_STATE_GUARD_WAIT);
+
+ /* Put it in guard wait state. */
+ guard = tor_malloc_zero(sizeof(*guard));
+ guard->in_selection = get_guard_selection_info();
+
+ orig_circ->guard_state =
+ circuit_guard_state_new(guard, GUARD_CIRC_STATE_WAITING_FOR_BETTER_GUARD,
+ NULL);
+
+ /* Mark the circuit for close. */
+ circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL);
+ tt_int_op(circ->marked_for_close, OP_NE, 0);
+
+ /* We shouldn't pick the mark for close circuit. */
+ list = circuit_find_circuits_to_upgrade_from_guard_wait();
+ tt_assert(!list);
+
+ done:
+ circuit_free(circ);
+ entry_guard_free_(guard);
+}
+
struct testcase_t circuitbuild_tests[] = {
{ "noexit", test_new_route_len_noexit, 0, NULL, NULL },
{ "safe_exit", test_new_route_len_safe_exit, 0, NULL, NULL },
{ "unsafe_exit", test_new_route_len_unsafe_exit, 0, NULL, NULL },
{ "unhandled_exit", test_new_route_len_unhandled_exit, 0, NULL, NULL },
+ { "upgrade_from_guard_wait", test_upgrade_from_guard_wait, TT_FORK,
+ &helper_pubsub_setup, NULL },
END_OF_TESTCASES
};