test_relay.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /* Copyright (c) 2014-2016, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. #include "or.h"
  4. #define CIRCUITBUILD_PRIVATE
  5. #include "circuitbuild.h"
  6. #include "circuitlist.h"
  7. #include "rephist.h"
  8. #include "channeltls.h"
  9. #define RELAY_PRIVATE
  10. #include "relay.h"
  11. /* For init/free stuff */
  12. #include "scheduler.h"
  13. /* Test suite stuff */
  14. #include "test.h"
  15. #include "fakechans.h"
  16. static or_circuit_t * new_fake_orcirc(channel_t *nchan, channel_t *pchan);
  17. static void test_relay_append_cell_to_circuit_queue(void *arg);
  18. uint64_t find_largest_max(bw_array_t *b);
  19. void commit_max(bw_array_t *b);
  20. void advance_obs(bw_array_t *b);
  21. static or_circuit_t *
  22. new_fake_orcirc(channel_t *nchan, channel_t *pchan)
  23. {
  24. or_circuit_t *orcirc = NULL;
  25. circuit_t *circ = NULL;
  26. orcirc = tor_malloc_zero(sizeof(*orcirc));
  27. circ = &(orcirc->base_);
  28. circ->magic = OR_CIRCUIT_MAGIC;
  29. circuit_set_n_circid_chan(circ, get_unique_circ_id_by_chan(nchan), nchan);
  30. cell_queue_init(&(circ->n_chan_cells));
  31. circ->n_hop = NULL;
  32. circ->streams_blocked_on_n_chan = 0;
  33. circ->streams_blocked_on_p_chan = 0;
  34. circ->n_delete_pending = 0;
  35. circ->p_delete_pending = 0;
  36. circ->received_destroy = 0;
  37. circ->state = CIRCUIT_STATE_OPEN;
  38. circ->purpose = CIRCUIT_PURPOSE_OR;
  39. circ->package_window = CIRCWINDOW_START_MAX;
  40. circ->deliver_window = CIRCWINDOW_START_MAX;
  41. circ->n_chan_create_cell = NULL;
  42. /* for assert_circ_ok */
  43. orcirc->p_crypto = (void*)1;
  44. orcirc->n_crypto = (void*)1;
  45. orcirc->n_digest = (void*)1;
  46. orcirc->p_digest = (void*)1;
  47. circuit_set_p_circid_chan(orcirc, get_unique_circ_id_by_chan(pchan), pchan);
  48. cell_queue_init(&(orcirc->p_chan_cells));
  49. return orcirc;
  50. }
  51. static void
  52. test_relay_close_circuit(void *arg)
  53. {
  54. channel_t *nchan = NULL, *pchan = NULL;
  55. or_circuit_t *orcirc = NULL;
  56. cell_t *cell = NULL;
  57. int old_count, new_count;
  58. (void)arg;
  59. /* Make fake channels to be nchan and pchan for the circuit */
  60. nchan = new_fake_channel();
  61. tt_assert(nchan);
  62. pchan = new_fake_channel();
  63. tt_assert(pchan);
  64. /* We'll need chans with working cmuxes */
  65. nchan->cmux = circuitmux_alloc();
  66. pchan->cmux = circuitmux_alloc();
  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. /* Append it */
  80. old_count = get_mock_scheduler_has_waiting_cells_count();
  81. append_cell_to_circuit_queue(TO_CIRCUIT(orcirc), nchan, cell,
  82. CELL_DIRECTION_OUT, 0);
  83. new_count = get_mock_scheduler_has_waiting_cells_count();
  84. tt_int_op(new_count, OP_EQ, old_count + 1);
  85. /* Now try the reverse direction */
  86. old_count = get_mock_scheduler_has_waiting_cells_count();
  87. append_cell_to_circuit_queue(TO_CIRCUIT(orcirc), pchan, cell,
  88. CELL_DIRECTION_IN, 0);
  89. new_count = get_mock_scheduler_has_waiting_cells_count();
  90. tt_int_op(new_count, OP_EQ, old_count + 1);
  91. /* Ensure our write totals are 0 */
  92. tt_u64_op(find_largest_max(write_array), OP_EQ, 0);
  93. /* Mark the circuit for close */
  94. circuit_mark_for_close(TO_CIRCUIT(orcirc), 0);
  95. /* Check our write totals. */
  96. advance_obs(write_array);
  97. commit_max(write_array);
  98. /* Check for two cells plus overhead */
  99. tt_u64_op(find_largest_max(write_array), OP_EQ,
  100. 2*(get_cell_network_size(nchan->wide_circ_ids)
  101. +TLS_PER_CELL_OVERHEAD));
  102. UNMOCK(scheduler_channel_has_waiting_cells);
  103. /* Get rid of the fake channels */
  104. MOCK(scheduler_release_channel, scheduler_release_channel_mock);
  105. channel_mark_for_close(nchan);
  106. channel_mark_for_close(pchan);
  107. UNMOCK(scheduler_release_channel);
  108. /* Shut down channels */
  109. channel_free_all();
  110. done:
  111. tor_free(cell);
  112. if (orcirc) {
  113. circuitmux_detach_circuit(nchan->cmux, TO_CIRCUIT(orcirc));
  114. circuitmux_detach_circuit(pchan->cmux, TO_CIRCUIT(orcirc));
  115. cell_queue_clear(&orcirc->base_.n_chan_cells);
  116. cell_queue_clear(&orcirc->p_chan_cells);
  117. }
  118. tor_free(orcirc);
  119. free_fake_channel(nchan);
  120. free_fake_channel(pchan);
  121. return;
  122. }
  123. static void
  124. test_relay_append_cell_to_circuit_queue(void *arg)
  125. {
  126. channel_t *nchan = NULL, *pchan = NULL;
  127. or_circuit_t *orcirc = NULL;
  128. cell_t *cell = NULL;
  129. int old_count, new_count;
  130. (void)arg;
  131. /* Make fake channels to be nchan and pchan for the circuit */
  132. nchan = new_fake_channel();
  133. tt_assert(nchan);
  134. pchan = new_fake_channel();
  135. tt_assert(pchan);
  136. /* We'll need chans with working cmuxes */
  137. nchan->cmux = circuitmux_alloc();
  138. pchan->cmux = circuitmux_alloc();
  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, ==, 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, ==, 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. };