test_relay.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /* Copyright (c) 2014-2018, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. #define CIRCUITBUILD_PRIVATE
  4. #define RELAY_PRIVATE
  5. #define REPHIST_PRIVATE
  6. #include "core/or/or.h"
  7. #include "core/or/circuitbuild.h"
  8. #include "core/or/circuitlist.h"
  9. #include "core/or/channeltls.h"
  10. #include "feature/stats/rephist.h"
  11. #include "core/or/relay.h"
  12. #include "feature/stats/rephist.h"
  13. #include "lib/container/order.h"
  14. /* For init/free stuff */
  15. #include "core/or/scheduler.h"
  16. #include "core/or/cell_st.h"
  17. #include "core/or/or_circuit_st.h"
  18. /* Test suite stuff */
  19. #include "test/test.h"
  20. #include "test/fakechans.h"
  21. static or_circuit_t * new_fake_orcirc(channel_t *nchan, channel_t *pchan);
  22. static void test_relay_append_cell_to_circuit_queue(void *arg);
  23. static or_circuit_t *
  24. new_fake_orcirc(channel_t *nchan, channel_t *pchan)
  25. {
  26. or_circuit_t *orcirc = NULL;
  27. circuit_t *circ = NULL;
  28. orcirc = tor_malloc_zero(sizeof(*orcirc));
  29. circ = &(orcirc->base_);
  30. circ->magic = OR_CIRCUIT_MAGIC;
  31. circuit_set_n_circid_chan(circ, get_unique_circ_id_by_chan(nchan), nchan);
  32. cell_queue_init(&(circ->n_chan_cells));
  33. circ->n_hop = NULL;
  34. circ->streams_blocked_on_n_chan = 0;
  35. circ->streams_blocked_on_p_chan = 0;
  36. circ->n_delete_pending = 0;
  37. circ->p_delete_pending = 0;
  38. circ->received_destroy = 0;
  39. circ->state = CIRCUIT_STATE_OPEN;
  40. circ->purpose = CIRCUIT_PURPOSE_OR;
  41. circ->package_window = CIRCWINDOW_START_MAX;
  42. circ->deliver_window = CIRCWINDOW_START_MAX;
  43. circ->n_chan_create_cell = NULL;
  44. circuit_set_p_circid_chan(orcirc, get_unique_circ_id_by_chan(pchan), pchan);
  45. cell_queue_init(&(orcirc->p_chan_cells));
  46. return orcirc;
  47. }
  48. static void
  49. assert_circuit_ok_mock(const circuit_t *c)
  50. {
  51. (void) c;
  52. return;
  53. }
  54. static void
  55. test_relay_close_circuit(void *arg)
  56. {
  57. channel_t *nchan = NULL, *pchan = NULL;
  58. or_circuit_t *orcirc = NULL;
  59. cell_t *cell = NULL;
  60. int old_count, new_count;
  61. (void)arg;
  62. /* Make fake channels to be nchan and pchan for the circuit */
  63. nchan = new_fake_channel();
  64. tt_assert(nchan);
  65. pchan = new_fake_channel();
  66. tt_assert(pchan);
  67. /* Make a fake orcirc */
  68. orcirc = new_fake_orcirc(nchan, pchan);
  69. tt_assert(orcirc);
  70. circuitmux_attach_circuit(nchan->cmux, TO_CIRCUIT(orcirc),
  71. CELL_DIRECTION_OUT);
  72. circuitmux_attach_circuit(pchan->cmux, TO_CIRCUIT(orcirc),
  73. CELL_DIRECTION_IN);
  74. /* Make a cell */
  75. cell = tor_malloc_zero(sizeof(cell_t));
  76. make_fake_cell(cell);
  77. MOCK(scheduler_channel_has_waiting_cells,
  78. scheduler_channel_has_waiting_cells_mock);
  79. MOCK(assert_circuit_ok,
  80. assert_circuit_ok_mock);
  81. /* Append it */
  82. old_count = get_mock_scheduler_has_waiting_cells_count();
  83. append_cell_to_circuit_queue(TO_CIRCUIT(orcirc), nchan, cell,
  84. CELL_DIRECTION_OUT, 0);
  85. new_count = get_mock_scheduler_has_waiting_cells_count();
  86. tt_int_op(new_count, OP_EQ, old_count + 1);
  87. /* Now try the reverse direction */
  88. old_count = get_mock_scheduler_has_waiting_cells_count();
  89. append_cell_to_circuit_queue(TO_CIRCUIT(orcirc), pchan, cell,
  90. CELL_DIRECTION_IN, 0);
  91. new_count = get_mock_scheduler_has_waiting_cells_count();
  92. tt_int_op(new_count, OP_EQ, old_count + 1);
  93. /* Ensure our write totals are 0 */
  94. tt_u64_op(find_largest_max(write_array), OP_EQ, 0);
  95. /* Mark the circuit for close */
  96. circuit_mark_for_close(TO_CIRCUIT(orcirc), 0);
  97. /* Check our write totals. */
  98. advance_obs(write_array);
  99. commit_max(write_array);
  100. /* Check for two cells plus overhead */
  101. tt_u64_op(find_largest_max(write_array), OP_EQ,
  102. 2*(get_cell_network_size(nchan->wide_circ_ids)
  103. +TLS_PER_CELL_OVERHEAD));
  104. UNMOCK(scheduler_channel_has_waiting_cells);
  105. /* Get rid of the fake channels */
  106. MOCK(scheduler_release_channel, scheduler_release_channel_mock);
  107. channel_mark_for_close(nchan);
  108. channel_mark_for_close(pchan);
  109. UNMOCK(scheduler_release_channel);
  110. /* Shut down channels */
  111. channel_free_all();
  112. done:
  113. tor_free(cell);
  114. if (orcirc) {
  115. circuitmux_detach_circuit(nchan->cmux, TO_CIRCUIT(orcirc));
  116. circuitmux_detach_circuit(pchan->cmux, TO_CIRCUIT(orcirc));
  117. cell_queue_clear(&orcirc->base_.n_chan_cells);
  118. cell_queue_clear(&orcirc->p_chan_cells);
  119. }
  120. tor_free(orcirc);
  121. free_fake_channel(nchan);
  122. free_fake_channel(pchan);
  123. UNMOCK(assert_circuit_ok);
  124. return;
  125. }
  126. static void
  127. test_relay_append_cell_to_circuit_queue(void *arg)
  128. {
  129. channel_t *nchan = NULL, *pchan = NULL;
  130. or_circuit_t *orcirc = NULL;
  131. cell_t *cell = NULL;
  132. int old_count, new_count;
  133. (void)arg;
  134. /* Make fake channels to be nchan and pchan for the circuit */
  135. nchan = new_fake_channel();
  136. tt_assert(nchan);
  137. pchan = new_fake_channel();
  138. tt_assert(pchan);
  139. /* Make a fake orcirc */
  140. orcirc = new_fake_orcirc(nchan, pchan);
  141. tt_assert(orcirc);
  142. circuitmux_attach_circuit(nchan->cmux, TO_CIRCUIT(orcirc),
  143. CELL_DIRECTION_OUT);
  144. circuitmux_attach_circuit(pchan->cmux, TO_CIRCUIT(orcirc),
  145. CELL_DIRECTION_IN);
  146. /* Make a cell */
  147. cell = tor_malloc_zero(sizeof(cell_t));
  148. make_fake_cell(cell);
  149. MOCK(scheduler_channel_has_waiting_cells,
  150. scheduler_channel_has_waiting_cells_mock);
  151. /* Append it */
  152. old_count = get_mock_scheduler_has_waiting_cells_count();
  153. append_cell_to_circuit_queue(TO_CIRCUIT(orcirc), nchan, cell,
  154. CELL_DIRECTION_OUT, 0);
  155. new_count = get_mock_scheduler_has_waiting_cells_count();
  156. tt_int_op(new_count, OP_EQ, old_count + 1);
  157. /* Now try the reverse direction */
  158. old_count = get_mock_scheduler_has_waiting_cells_count();
  159. append_cell_to_circuit_queue(TO_CIRCUIT(orcirc), pchan, cell,
  160. CELL_DIRECTION_IN, 0);
  161. new_count = get_mock_scheduler_has_waiting_cells_count();
  162. tt_int_op(new_count, OP_EQ, old_count + 1);
  163. UNMOCK(scheduler_channel_has_waiting_cells);
  164. /* Get rid of the fake channels */
  165. MOCK(scheduler_release_channel, scheduler_release_channel_mock);
  166. channel_mark_for_close(nchan);
  167. channel_mark_for_close(pchan);
  168. UNMOCK(scheduler_release_channel);
  169. /* Shut down channels */
  170. channel_free_all();
  171. done:
  172. tor_free(cell);
  173. if (orcirc) {
  174. circuitmux_detach_circuit(nchan->cmux, TO_CIRCUIT(orcirc));
  175. circuitmux_detach_circuit(pchan->cmux, TO_CIRCUIT(orcirc));
  176. cell_queue_clear(&orcirc->base_.n_chan_cells);
  177. cell_queue_clear(&orcirc->p_chan_cells);
  178. }
  179. tor_free(orcirc);
  180. free_fake_channel(nchan);
  181. free_fake_channel(pchan);
  182. return;
  183. }
  184. struct testcase_t relay_tests[] = {
  185. { "append_cell_to_circuit_queue", test_relay_append_cell_to_circuit_queue,
  186. TT_FORK, NULL, NULL },
  187. { "close_circ_rephist", test_relay_close_circuit,
  188. TT_FORK, NULL, NULL },
  189. END_OF_TESTCASES
  190. };