test_circuitbuild.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /* Copyright (c) 2001-2004, Roger Dingledine.
  2. * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
  3. * Copyright (c) 2007-2019, The Tor Project, Inc. */
  4. /* See LICENSE for licensing information */
  5. #define CIRCUITBUILD_PRIVATE
  6. #define CIRCUITLIST_PRIVATE
  7. #define ENTRYNODES_PRIVATE
  8. #include "core/or/or.h"
  9. #include "test/test.h"
  10. #include "test/test_helpers.h"
  11. #include "test/log_test_helpers.h"
  12. #include "app/config/config.h"
  13. #include "core/or/circuitbuild.h"
  14. #include "core/or/circuitlist.h"
  15. #include "core/or/cpath_build_state_st.h"
  16. #include "core/or/extend_info_st.h"
  17. #include "core/or/origin_circuit_st.h"
  18. #include "feature/client/entrynodes.h"
  19. /* Dummy nodes smartlist for testing */
  20. static smartlist_t dummy_nodes;
  21. /* Dummy exit extend_info for testing */
  22. static extend_info_t dummy_ei;
  23. static int
  24. mock_count_acceptable_nodes(const smartlist_t *nodes, int direct)
  25. {
  26. (void)nodes;
  27. return direct ? 1 : DEFAULT_ROUTE_LEN + 1;
  28. }
  29. /* Test route lengths when the caller of new_route_len() doesn't
  30. * specify exit_ei. */
  31. static void
  32. test_new_route_len_noexit(void *arg)
  33. {
  34. int r;
  35. (void)arg;
  36. MOCK(count_acceptable_nodes, mock_count_acceptable_nodes);
  37. r = new_route_len(CIRCUIT_PURPOSE_C_GENERAL, NULL, &dummy_nodes);
  38. tt_int_op(DEFAULT_ROUTE_LEN, OP_EQ, r);
  39. r = new_route_len(CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT, NULL, &dummy_nodes);
  40. tt_int_op(DEFAULT_ROUTE_LEN, OP_EQ, r);
  41. r = new_route_len(CIRCUIT_PURPOSE_S_CONNECT_REND, NULL, &dummy_nodes);
  42. tt_int_op(DEFAULT_ROUTE_LEN, OP_EQ, r);
  43. done:
  44. UNMOCK(count_acceptable_nodes);
  45. }
  46. /* Test route lengths where someone else chose the "exit" node, which
  47. * require an extra hop for safety. */
  48. static void
  49. test_new_route_len_unsafe_exit(void *arg)
  50. {
  51. int r;
  52. (void)arg;
  53. MOCK(count_acceptable_nodes, mock_count_acceptable_nodes);
  54. /* connecting to hidden service directory */
  55. r = new_route_len(CIRCUIT_PURPOSE_C_GENERAL, &dummy_ei, &dummy_nodes);
  56. tt_int_op(DEFAULT_ROUTE_LEN + 1, OP_EQ, r);
  57. /* client connecting to introduction point */
  58. r = new_route_len(CIRCUIT_PURPOSE_C_INTRODUCING, &dummy_ei, &dummy_nodes);
  59. tt_int_op(DEFAULT_ROUTE_LEN + 1, OP_EQ, r);
  60. /* hidden service connecting to rendezvous point */
  61. r = new_route_len(CIRCUIT_PURPOSE_S_CONNECT_REND, &dummy_ei, &dummy_nodes);
  62. tt_int_op(DEFAULT_ROUTE_LEN + 1, OP_EQ, r);
  63. done:
  64. UNMOCK(count_acceptable_nodes);
  65. }
  66. /* Test route lengths where we chose the "exit" node, which don't
  67. * require an extra hop for safety. */
  68. static void
  69. test_new_route_len_safe_exit(void *arg)
  70. {
  71. int r;
  72. (void)arg;
  73. MOCK(count_acceptable_nodes, mock_count_acceptable_nodes);
  74. /* hidden service connecting to introduction point */
  75. r = new_route_len(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO, &dummy_ei,
  76. &dummy_nodes);
  77. tt_int_op(DEFAULT_ROUTE_LEN, OP_EQ, r);
  78. /* router testing its own reachability */
  79. r = new_route_len(CIRCUIT_PURPOSE_TESTING, &dummy_ei, &dummy_nodes);
  80. tt_int_op(DEFAULT_ROUTE_LEN, OP_EQ, r);
  81. done:
  82. UNMOCK(count_acceptable_nodes);
  83. }
  84. /* Make sure a non-fatal assertion fails when new_route_len() gets an
  85. * unexpected circuit purpose. */
  86. static void
  87. test_new_route_len_unhandled_exit(void *arg)
  88. {
  89. int r;
  90. (void)arg;
  91. MOCK(count_acceptable_nodes, mock_count_acceptable_nodes);
  92. tor_capture_bugs_(1);
  93. setup_full_capture_of_logs(LOG_WARN);
  94. r = new_route_len(CIRCUIT_PURPOSE_CONTROLLER, &dummy_ei, &dummy_nodes);
  95. tt_int_op(DEFAULT_ROUTE_LEN + 1, OP_EQ, r);
  96. tt_int_op(smartlist_len(tor_get_captured_bug_log_()), OP_EQ, 1);
  97. tt_str_op(smartlist_get(tor_get_captured_bug_log_(), 0), OP_EQ,
  98. "!(exit_ei && !known_purpose)");
  99. expect_single_log_msg_containing("Unhandled purpose");
  100. expect_single_log_msg_containing("with a chosen exit; assuming routelen");
  101. teardown_capture_of_logs();
  102. tor_end_capture_bugs_();
  103. done:
  104. UNMOCK(count_acceptable_nodes);
  105. }
  106. static void
  107. test_upgrade_from_guard_wait(void *arg)
  108. {
  109. circuit_t *circ = NULL;
  110. origin_circuit_t *orig_circ = NULL;
  111. entry_guard_t *guard = NULL;
  112. smartlist_t *list = NULL;
  113. (void) arg;
  114. circ = dummy_origin_circuit_new(0);
  115. orig_circ = TO_ORIGIN_CIRCUIT(circ);
  116. tt_assert(orig_circ);
  117. orig_circ->build_state = tor_malloc_zero(sizeof(cpath_build_state_t));
  118. circuit_set_state(circ, CIRCUIT_STATE_GUARD_WAIT);
  119. /* Put it in guard wait state. */
  120. guard = tor_malloc_zero(sizeof(*guard));
  121. guard->in_selection = get_guard_selection_info();
  122. orig_circ->guard_state =
  123. circuit_guard_state_new(guard, GUARD_CIRC_STATE_WAITING_FOR_BETTER_GUARD,
  124. NULL);
  125. /* Mark the circuit for close. */
  126. circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL);
  127. tt_int_op(circ->marked_for_close, OP_NE, 0);
  128. /* We shouldn't pick the mark for close circuit. */
  129. list = circuit_find_circuits_to_upgrade_from_guard_wait();
  130. tt_assert(!list);
  131. done:
  132. smartlist_free(list);
  133. circuit_free(circ);
  134. entry_guard_free_(guard);
  135. }
  136. struct testcase_t circuitbuild_tests[] = {
  137. { "noexit", test_new_route_len_noexit, 0, NULL, NULL },
  138. { "safe_exit", test_new_route_len_safe_exit, 0, NULL, NULL },
  139. { "unsafe_exit", test_new_route_len_unsafe_exit, 0, NULL, NULL },
  140. { "unhandled_exit", test_new_route_len_unhandled_exit, 0, NULL, NULL },
  141. { "upgrade_from_guard_wait", test_upgrade_from_guard_wait, TT_FORK,
  142. &helper_pubsub_setup, NULL },
  143. END_OF_TESTCASES
  144. };