test_sendme.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. /* Copyright (c) 2014-2019, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. /* Unit tests for handling different kinds of relay cell */
  4. #define CIRCUITLIST_PRIVATE
  5. #define NETWORKSTATUS_PRIVATE
  6. #define SENDME_PRIVATE
  7. #define RELAY_PRIVATE
  8. #include "core/or/circuit_st.h"
  9. #include "core/or/or_circuit_st.h"
  10. #include "core/or/origin_circuit_st.h"
  11. #include "core/or/circuitlist.h"
  12. #include "core/or/relay.h"
  13. #include "core/or/sendme.h"
  14. #include "feature/nodelist/networkstatus.h"
  15. #include "feature/nodelist/networkstatus_st.h"
  16. #include "lib/crypt_ops/crypto_digest.h"
  17. #include "test/test.h"
  18. #include "test/log_test_helpers.h"
  19. static void
  20. setup_mock_consensus(void)
  21. {
  22. current_md_consensus = current_ns_consensus =
  23. tor_malloc_zero(sizeof(networkstatus_t));
  24. current_md_consensus->net_params = smartlist_new();
  25. current_md_consensus->routerstatus_list = smartlist_new();
  26. }
  27. static void
  28. free_mock_consensus(void)
  29. {
  30. SMARTLIST_FOREACH(current_md_consensus->routerstatus_list, void *, r,
  31. tor_free(r));
  32. smartlist_free(current_md_consensus->routerstatus_list);
  33. smartlist_free(current_ns_consensus->net_params);
  34. tor_free(current_ns_consensus);
  35. }
  36. static void
  37. test_v1_record_digest(void *arg)
  38. {
  39. or_circuit_t *or_circ = NULL;
  40. circuit_t *circ = NULL;
  41. (void) arg;
  42. /* Create our dummy circuit. */
  43. or_circ = or_circuit_new(1, NULL);
  44. /* Points it to the OR circuit now. */
  45. circ = TO_CIRCUIT(or_circ);
  46. /* The package window has to be a multiple of CIRCWINDOW_INCREMENT minus 1
  47. * in order to catched the CIRCWINDOW_INCREMENT-nth cell. Try something that
  48. * shouldn't be noted. */
  49. circ->package_window = CIRCWINDOW_INCREMENT;
  50. sendme_record_cell_digest_on_circ(circ, NULL);
  51. tt_assert(!circ->sendme_last_digests);
  52. /* This should work now. Package window at CIRCWINDOW_INCREMENT + 1. */
  53. circ->package_window++;
  54. sendme_record_cell_digest_on_circ(circ, NULL);
  55. tt_assert(circ->sendme_last_digests);
  56. tt_int_op(smartlist_len(circ->sendme_last_digests), OP_EQ, 1);
  57. /* Next cell in the package window shouldn't do anything. */
  58. circ->package_window++;
  59. sendme_record_cell_digest_on_circ(circ, NULL);
  60. tt_int_op(smartlist_len(circ->sendme_last_digests), OP_EQ, 1);
  61. /* The next CIRCWINDOW_INCREMENT should add one more digest. */
  62. circ->package_window = (CIRCWINDOW_INCREMENT * 2) + 1;
  63. sendme_record_cell_digest_on_circ(circ, NULL);
  64. tt_int_op(smartlist_len(circ->sendme_last_digests), OP_EQ, 2);
  65. done:
  66. circuit_free_(circ);
  67. }
  68. static void
  69. test_v1_consensus_params(void *arg)
  70. {
  71. (void) arg;
  72. setup_mock_consensus();
  73. tt_assert(current_md_consensus);
  74. /* Both zeroes. */
  75. smartlist_add(current_md_consensus->net_params,
  76. (void *) "sendme_emit_min_version=0");
  77. smartlist_add(current_md_consensus->net_params,
  78. (void *) "sendme_accept_min_version=0");
  79. tt_int_op(get_emit_min_version(), OP_EQ, 0);
  80. tt_int_op(get_accept_min_version(), OP_EQ, 0);
  81. smartlist_clear(current_md_consensus->net_params);
  82. /* Both ones. */
  83. smartlist_add(current_md_consensus->net_params,
  84. (void *) "sendme_emit_min_version=1");
  85. smartlist_add(current_md_consensus->net_params,
  86. (void *) "sendme_accept_min_version=1");
  87. tt_int_op(get_emit_min_version(), OP_EQ, 1);
  88. tt_int_op(get_accept_min_version(), OP_EQ, 1);
  89. smartlist_clear(current_md_consensus->net_params);
  90. /* Different values from each other. */
  91. smartlist_add(current_md_consensus->net_params,
  92. (void *) "sendme_emit_min_version=1");
  93. smartlist_add(current_md_consensus->net_params,
  94. (void *) "sendme_accept_min_version=0");
  95. tt_int_op(get_emit_min_version(), OP_EQ, 1);
  96. tt_int_op(get_accept_min_version(), OP_EQ, 0);
  97. smartlist_clear(current_md_consensus->net_params);
  98. /* Validate is the cell version is coherent with our internal default value
  99. * and the one in the consensus. */
  100. smartlist_add(current_md_consensus->net_params,
  101. (void *) "sendme_accept_min_version=1");
  102. /* Minimum acceptable value is 1. */
  103. tt_int_op(cell_version_can_be_handled(1), OP_EQ, true);
  104. /* Minimum acceptable value is 1 so a cell version of 0 is refused. */
  105. tt_int_op(cell_version_can_be_handled(0), OP_EQ, false);
  106. done:
  107. free_mock_consensus();
  108. }
  109. static void
  110. test_v1_build_cell(void *arg)
  111. {
  112. uint8_t payload[RELAY_PAYLOAD_SIZE], digest[DIGEST_LEN];
  113. ssize_t ret;
  114. crypto_digest_t *cell_digest = NULL;
  115. or_circuit_t *or_circ = NULL;
  116. circuit_t *circ = NULL;
  117. (void) arg;
  118. or_circ = or_circuit_new(1, NULL);
  119. circ = TO_CIRCUIT(or_circ);
  120. circ->sendme_last_digests = smartlist_new();
  121. cell_digest = crypto_digest_new();
  122. tt_assert(cell_digest);
  123. crypto_digest_add_bytes(cell_digest, "AAAAAAAAAAAAAAAAAAAA", 20);
  124. crypto_digest_get_digest(cell_digest, (char *) digest, sizeof(digest));
  125. smartlist_add(circ->sendme_last_digests, tor_memdup(digest, sizeof(digest)));
  126. /* SENDME v1 payload is 3 bytes + 20 bytes digest. See spec. */
  127. ret = build_cell_payload_v1(digest, payload);
  128. tt_int_op(ret, OP_EQ, 23);
  129. /* Validation. */
  130. /* An empty payload means SENDME version 0 thus valid. */
  131. tt_int_op(sendme_is_valid(circ, payload, 0), OP_EQ, true);
  132. /* Current phoney digest should have been popped. */
  133. tt_int_op(smartlist_len(circ->sendme_last_digests), OP_EQ, 0);
  134. /* An unparseable cell means invalid. */
  135. setup_full_capture_of_logs(LOG_INFO);
  136. tt_int_op(sendme_is_valid(circ, (const uint8_t *) "A", 1), OP_EQ, false);
  137. expect_log_msg_containing("Unparseable SENDME cell received. "
  138. "Closing circuit.");
  139. teardown_capture_of_logs();
  140. /* No cell digest recorded for this. */
  141. setup_full_capture_of_logs(LOG_INFO);
  142. tt_int_op(sendme_is_valid(circ, payload, sizeof(payload)), OP_EQ, false);
  143. expect_log_msg_containing("We received a SENDME but we have no cell digests "
  144. "to match. Closing circuit.");
  145. teardown_capture_of_logs();
  146. /* Note the wrong digest in the circuit, cell should fail validation. */
  147. circ->package_window = CIRCWINDOW_INCREMENT + 1;
  148. sendme_record_cell_digest_on_circ(circ, NULL);
  149. tt_int_op(smartlist_len(circ->sendme_last_digests), OP_EQ, 1);
  150. setup_full_capture_of_logs(LOG_INFO);
  151. tt_int_op(sendme_is_valid(circ, payload, sizeof(payload)), OP_EQ, false);
  152. /* After a validation, the last digests is always popped out. */
  153. tt_int_op(smartlist_len(circ->sendme_last_digests), OP_EQ, 0);
  154. expect_log_msg_containing("SENDME v1 cell digest do not match.");
  155. teardown_capture_of_logs();
  156. /* Record the cell digest into the circuit, cell should validate. */
  157. memcpy(or_circ->crypto.sendme_digest, digest, sizeof(digest));
  158. circ->package_window = CIRCWINDOW_INCREMENT + 1;
  159. sendme_record_cell_digest_on_circ(circ, NULL);
  160. tt_int_op(smartlist_len(circ->sendme_last_digests), OP_EQ, 1);
  161. tt_int_op(sendme_is_valid(circ, payload, sizeof(payload)), OP_EQ, true);
  162. /* After a validation, the last digests is always popped out. */
  163. tt_int_op(smartlist_len(circ->sendme_last_digests), OP_EQ, 0);
  164. done:
  165. crypto_digest_free(cell_digest);
  166. circuit_free_(circ);
  167. }
  168. static void
  169. test_cell_payload_pad(void *arg)
  170. {
  171. size_t pad_offset, payload_len, expected_offset;
  172. (void) arg;
  173. /* Offset should be 0, not enough room for padding. */
  174. payload_len = RELAY_PAYLOAD_SIZE;
  175. pad_offset = get_pad_cell_offset(payload_len);
  176. tt_int_op(pad_offset, OP_EQ, 0);
  177. tt_int_op(CELL_PAYLOAD_SIZE - pad_offset, OP_LE, CELL_PAYLOAD_SIZE);
  178. /* Still no room because we keep 4 extra bytes. */
  179. pad_offset = get_pad_cell_offset(payload_len - 4);
  180. tt_int_op(pad_offset, OP_EQ, 0);
  181. tt_int_op(CELL_PAYLOAD_SIZE - pad_offset, OP_LE, CELL_PAYLOAD_SIZE);
  182. /* We should have 1 byte of padding. Meaning, the offset should be the
  183. * CELL_PAYLOAD_SIZE minus 1 byte. */
  184. expected_offset = CELL_PAYLOAD_SIZE - 1;
  185. pad_offset = get_pad_cell_offset(payload_len - 5);
  186. tt_int_op(pad_offset, OP_EQ, expected_offset);
  187. tt_int_op(CELL_PAYLOAD_SIZE - pad_offset, OP_LE, CELL_PAYLOAD_SIZE);
  188. /* Now some arbitrary small payload length. The cell size is header + 10 +
  189. * extra 4 bytes we keep so the offset should be there. */
  190. expected_offset = RELAY_HEADER_SIZE + 10 + 4;
  191. pad_offset = get_pad_cell_offset(10);
  192. tt_int_op(pad_offset, OP_EQ, expected_offset);
  193. tt_int_op(CELL_PAYLOAD_SIZE - pad_offset, OP_LE, CELL_PAYLOAD_SIZE);
  194. /* Data length of 0. */
  195. expected_offset = RELAY_HEADER_SIZE + 4;
  196. pad_offset = get_pad_cell_offset(0);
  197. tt_int_op(pad_offset, OP_EQ, expected_offset);
  198. tt_int_op(CELL_PAYLOAD_SIZE - pad_offset, OP_LE, CELL_PAYLOAD_SIZE);
  199. done:
  200. ;
  201. }
  202. static void
  203. test_cell_version_validation(void *arg)
  204. {
  205. (void) arg;
  206. /* We currently only support up to SENDME_MAX_SUPPORTED_VERSION so we are
  207. * going to test the boundaries there. */
  208. tt_assert(cell_version_can_be_handled(SENDME_MAX_SUPPORTED_VERSION));
  209. /* Version below our supported should pass. */
  210. tt_assert(cell_version_can_be_handled(SENDME_MAX_SUPPORTED_VERSION - 1));
  211. /* Extra version from our supported should fail. */
  212. tt_assert(!cell_version_can_be_handled(SENDME_MAX_SUPPORTED_VERSION + 1));
  213. /* Simple check for version 0. */
  214. tt_assert(cell_version_can_be_handled(0));
  215. /* We MUST handle the default cell version that we emit or accept. */
  216. tt_assert(cell_version_can_be_handled(SENDME_EMIT_MIN_VERSION_DEFAULT));
  217. tt_assert(cell_version_can_be_handled(SENDME_ACCEPT_MIN_VERSION_DEFAULT));
  218. done:
  219. ;
  220. }
  221. /* check our decisions about how much stuff to put into relay cells. */
  222. static void
  223. test_package_payload_len(void *arg)
  224. {
  225. (void)arg;
  226. /* this is not a real circuit: it only has the fields needed for this
  227. * test. */
  228. circuit_t *c = tor_malloc_zero(sizeof(circuit_t));
  229. /* check initial conditions. */
  230. circuit_reset_sendme_randomness(c);
  231. tt_assert(! c->have_sent_sufficiently_random_cell);
  232. tt_int_op(c->send_randomness_after_n_cells, OP_GE, CIRCWINDOW_INCREMENT / 2);
  233. tt_int_op(c->send_randomness_after_n_cells, OP_LT, CIRCWINDOW_INCREMENT);
  234. /* We have a bunch of cells before we need to send randomness, so the first
  235. * few can be packaged full. */
  236. int initial = c->send_randomness_after_n_cells;
  237. size_t n = connection_edge_get_inbuf_bytes_to_package(10000, 0, c);
  238. tt_uint_op(RELAY_PAYLOAD_SIZE, OP_EQ, n);
  239. n = connection_edge_get_inbuf_bytes_to_package(95000, 1, c);
  240. tt_uint_op(RELAY_PAYLOAD_SIZE, OP_EQ, n);
  241. tt_int_op(c->send_randomness_after_n_cells, OP_EQ, initial - 2);
  242. /* If package_partial isn't set, we won't package a partially full cell at
  243. * all. */
  244. n = connection_edge_get_inbuf_bytes_to_package(RELAY_PAYLOAD_SIZE-1, 0, c);
  245. tt_int_op(n, OP_EQ, 0);
  246. /* no change in our state, since nothing was sent. */
  247. tt_assert(! c->have_sent_sufficiently_random_cell);
  248. tt_int_op(c->send_randomness_after_n_cells, OP_EQ, initial - 2);
  249. /* If package_partial is set and the partial cell is not going to have
  250. * _enough_ randomness, we package it, but we don't consider ourselves to
  251. * have sent a sufficiently random cell. */
  252. n = connection_edge_get_inbuf_bytes_to_package(RELAY_PAYLOAD_SIZE-1, 1, c);
  253. tt_int_op(n, OP_EQ, RELAY_PAYLOAD_SIZE-1);
  254. tt_assert(! c->have_sent_sufficiently_random_cell);
  255. tt_int_op(c->send_randomness_after_n_cells, OP_EQ, initial - 3);
  256. /* Make sure we set have_set_sufficiently_random_cell as appropriate. */
  257. n = connection_edge_get_inbuf_bytes_to_package(RELAY_PAYLOAD_SIZE-64, 1, c);
  258. tt_int_op(n, OP_EQ, RELAY_PAYLOAD_SIZE-64);
  259. tt_assert(c->have_sent_sufficiently_random_cell);
  260. tt_int_op(c->send_randomness_after_n_cells, OP_EQ, initial - 4);
  261. /* Now let's look at what happens when we get down to zero. Since we have
  262. * sent a sufficiently random cell, we will not force this one to have a gap.
  263. */
  264. c->send_randomness_after_n_cells = 0;
  265. n = connection_edge_get_inbuf_bytes_to_package(10000, 1, c);
  266. tt_int_op(n, OP_EQ, RELAY_PAYLOAD_SIZE);
  267. /* Now these will be reset. */
  268. tt_assert(! c->have_sent_sufficiently_random_cell);
  269. tt_int_op(c->send_randomness_after_n_cells, OP_GE,
  270. CIRCWINDOW_INCREMENT / 2 - 1);
  271. /* What would happen if we hadn't sent a sufficiently random cell? */
  272. c->send_randomness_after_n_cells = 0;
  273. n = connection_edge_get_inbuf_bytes_to_package(10000, 1, c);
  274. const size_t reduced_payload_size = RELAY_PAYLOAD_SIZE - 4 - 16;
  275. tt_int_op(n, OP_EQ, reduced_payload_size);
  276. /* Now these will be reset. */
  277. tt_assert(! c->have_sent_sufficiently_random_cell);
  278. tt_int_op(c->send_randomness_after_n_cells, OP_GE,
  279. CIRCWINDOW_INCREMENT / 2 - 1);
  280. /* Here is a fun case: if it's time to package a small cell, then
  281. * package_partial==0 should mean we accept that many bytes.
  282. */
  283. c->send_randomness_after_n_cells = 0;
  284. n = connection_edge_get_inbuf_bytes_to_package(reduced_payload_size, 0, c);
  285. tt_int_op(n, OP_EQ, reduced_payload_size);
  286. done:
  287. tor_free(c);
  288. }
  289. struct testcase_t sendme_tests[] = {
  290. { "v1_record_digest", test_v1_record_digest, TT_FORK,
  291. NULL, NULL },
  292. { "v1_consensus_params", test_v1_consensus_params, TT_FORK,
  293. NULL, NULL },
  294. { "v1_build_cell", test_v1_build_cell, TT_FORK,
  295. NULL, NULL },
  296. { "cell_payload_pad", test_cell_payload_pad, TT_FORK,
  297. NULL, NULL },
  298. { "cell_version_validation", test_cell_version_validation, TT_FORK,
  299. NULL, NULL },
  300. { "package_payload_len", test_package_payload_len, 0, NULL, NULL },
  301. END_OF_TESTCASES
  302. };