test_relaycell.c 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074
  1. /* Copyright (c) 2014-2017, The Tor Project, Inc. */
  2. /* See LICENSE for licensing information */
  3. /* Unit tests for handling different kinds of relay cell */
  4. #define RELAY_PRIVATE
  5. #define CIRCUITLIST_PRIVATE
  6. #include "or.h"
  7. #include "main.h"
  8. #include "config.h"
  9. #include "connection.h"
  10. #include "crypto.h"
  11. #include "crypto_rand.h"
  12. #include "circuitbuild.h"
  13. #include "circuitlist.h"
  14. #include "connection_edge.h"
  15. #include "log_test_helpers.h"
  16. #include "relay.h"
  17. #include "test.h"
  18. static int srm_ncalls;
  19. static entry_connection_t *srm_conn;
  20. static int srm_atype;
  21. static size_t srm_alen;
  22. static int srm_answer_is_set;
  23. static uint8_t srm_answer[512];
  24. static int srm_ttl;
  25. static time_t srm_expires;
  26. void connection_free_minimal(connection_t*);
  27. int connected_cell_format_payload(uint8_t *payload_out,
  28. const tor_addr_t *addr,
  29. uint32_t ttl);
  30. void pathbias_count_valid_cells(origin_circuit_t *circ,
  31. cell_t *cell);
  32. half_edge_t *connection_half_edge_find_stream_id(
  33. const smartlist_t *half_conns,
  34. streamid_t stream_id);
  35. void connection_half_edge_add(const edge_connection_t *conn,
  36. origin_circuit_t *circ);
  37. int mock_send_command(streamid_t stream_id, circuit_t *circ,
  38. uint8_t relay_command, const char *payload,
  39. size_t payload_len, crypt_path_t *cpath_layer,
  40. const char *filename, int lineno);
  41. /* Mock replacement for connection_ap_hannshake_socks_resolved() */
  42. static void
  43. socks_resolved_mock(entry_connection_t *conn,
  44. int answer_type,
  45. size_t answer_len,
  46. const uint8_t *answer,
  47. int ttl,
  48. time_t expires)
  49. {
  50. srm_ncalls++;
  51. srm_conn = conn;
  52. srm_atype = answer_type;
  53. srm_alen = answer_len;
  54. if (answer) {
  55. memset(srm_answer, 0, sizeof(srm_answer));
  56. memcpy(srm_answer, answer, answer_len < 512 ? answer_len : 512);
  57. srm_answer_is_set = 1;
  58. } else {
  59. srm_answer_is_set = 0;
  60. }
  61. srm_ttl = ttl;
  62. srm_expires = expires;
  63. }
  64. static int mum_ncalls;
  65. static entry_connection_t *mum_conn;
  66. static int mum_endreason;
  67. /* Mock replacement for connection_mark_unattached_ap_() */
  68. static void
  69. mark_unattached_mock(entry_connection_t *conn, int endreason,
  70. int line, const char *file)
  71. {
  72. ++mum_ncalls;
  73. mum_conn = conn;
  74. mum_endreason = endreason;
  75. (void) line;
  76. (void) file;
  77. }
  78. /* Helper: Return a newly allocated and initialized origin circuit with
  79. * purpose and flags. A default HS identifier is set to an ed25519
  80. * authentication key for introduction point. */
  81. static origin_circuit_t *
  82. helper_create_origin_circuit(int purpose, int flags)
  83. {
  84. origin_circuit_t *circ = NULL;
  85. circ = origin_circuit_init(purpose, flags);
  86. tor_assert(circ);
  87. circ->cpath = tor_malloc_zero(sizeof(crypt_path_t));
  88. circ->cpath->magic = CRYPT_PATH_MAGIC;
  89. circ->cpath->state = CPATH_STATE_OPEN;
  90. circ->cpath->package_window = circuit_initial_package_window();
  91. circ->cpath->deliver_window = CIRCWINDOW_START;
  92. circ->cpath->prev = circ->cpath;
  93. /* Create a default HS identifier. */
  94. circ->hs_ident = tor_malloc_zero(sizeof(hs_ident_circuit_t));
  95. return circ;
  96. }
  97. static void
  98. mock_connection_mark_unattached_ap_(entry_connection_t *conn, int endreason,
  99. int line, const char *file)
  100. {
  101. (void) line;
  102. (void) file;
  103. conn->edge_.end_reason = endreason;
  104. }
  105. static void
  106. mock_mark_circ_for_close(circuit_t *circ, int reason, int line,
  107. const char *file)
  108. {
  109. (void)reason; (void)line; (void)file;
  110. circ->marked_for_close = 1;
  111. return;
  112. }
  113. static void
  114. mock_mark_for_close(connection_t *conn,
  115. int line, const char *file)
  116. {
  117. (void)line;
  118. (void)file;
  119. conn->marked_for_close = 1;
  120. return;
  121. }
  122. static void
  123. mock_start_reading(connection_t *conn)
  124. {
  125. (void)conn;
  126. return;
  127. }
  128. int
  129. mock_send_command(streamid_t stream_id, circuit_t *circ,
  130. uint8_t relay_command, const char *payload,
  131. size_t payload_len, crypt_path_t *cpath_layer,
  132. const char *filename, int lineno)
  133. {
  134. (void)stream_id; (void)circ;
  135. (void)relay_command; (void)payload;
  136. (void)payload_len; (void)cpath_layer;
  137. (void)filename; (void)lineno;
  138. return 0;
  139. }
  140. static entry_connection_t *
  141. fake_entry_conn(origin_circuit_t *oncirc, streamid_t id)
  142. {
  143. edge_connection_t *edgeconn;
  144. entry_connection_t *entryconn;
  145. entryconn = entry_connection_new(CONN_TYPE_AP, AF_INET);
  146. edgeconn = ENTRY_TO_EDGE_CONN(entryconn);
  147. edgeconn->base_.state = AP_CONN_STATE_CONNECT_WAIT;
  148. edgeconn->deliver_window = STREAMWINDOW_START;
  149. edgeconn->package_window = STREAMWINDOW_START;
  150. edgeconn->stream_id = id;
  151. edgeconn->on_circuit = TO_CIRCUIT(oncirc);
  152. edgeconn->cpath_layer = oncirc->cpath;
  153. return entryconn;
  154. }
  155. #define PACK_CELL(id, cmd, body_s) do { \
  156. memset(&cell, 0, sizeof(cell)); \
  157. memset(&rh, 0, sizeof(rh)); \
  158. memcpy(cell.payload+RELAY_HEADER_SIZE, (body_s), sizeof((body_s))-1); \
  159. rh.length = sizeof((body_s))-1; \
  160. rh.command = (cmd); \
  161. rh.stream_id = (id); \
  162. relay_header_pack((uint8_t*)&cell.payload, &rh); \
  163. } while (0)
  164. #define ASSERT_COUNTED_BW() do { \
  165. tt_int_op(circ->n_delivered_read_circ_bw, OP_EQ, delivered+rh.length); \
  166. tt_int_op(circ->n_overhead_read_circ_bw, OP_EQ, \
  167. overhead+RELAY_PAYLOAD_SIZE-rh.length); \
  168. delivered = circ->n_delivered_read_circ_bw; \
  169. overhead = circ->n_overhead_read_circ_bw; \
  170. } while (0)
  171. #define ASSERT_UNCOUNTED_BW() do { \
  172. tt_int_op(circ->n_delivered_read_circ_bw, OP_EQ, delivered); \
  173. tt_int_op(circ->n_overhead_read_circ_bw, OP_EQ, overhead); \
  174. } while (0)
  175. static int
  176. subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
  177. {
  178. cell_t cell;
  179. relay_header_t rh;
  180. edge_connection_t *edgeconn;
  181. entry_connection_t *entryconn2=NULL;
  182. entry_connection_t *entryconn3=NULL;
  183. entry_connection_t *entryconn4=NULL;
  184. int delivered = circ->n_delivered_read_circ_bw;
  185. int overhead = circ->n_overhead_read_circ_bw;
  186. /* Make new entryconns */
  187. entryconn2 = fake_entry_conn(circ, init_id);
  188. entryconn2->socks_request->has_finished = 1;
  189. entryconn3 = fake_entry_conn(circ, init_id+1);
  190. entryconn3->socks_request->has_finished = 1;
  191. entryconn4 = fake_entry_conn(circ, init_id+2);
  192. entryconn4->socks_request->has_finished = 1;
  193. edgeconn = ENTRY_TO_EDGE_CONN(entryconn2);
  194. edgeconn->package_window = 23;
  195. edgeconn->base_.state = AP_CONN_STATE_OPEN;
  196. int data_cells = edgeconn->deliver_window;
  197. int sendme_cells = (STREAMWINDOW_START-edgeconn->package_window)
  198. /STREAMWINDOW_INCREMENT;
  199. ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
  200. ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
  201. connection_edge_reached_eof(edgeconn);
  202. /* Data cell not in the half-opened list */
  203. PACK_CELL(4000, RELAY_COMMAND_DATA, "Data1234");
  204. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  205. pathbias_count_valid_cells(circ, &cell);
  206. else
  207. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  208. circ->cpath);
  209. ASSERT_UNCOUNTED_BW();
  210. /* Sendme cell not in the half-opened list */
  211. PACK_CELL(4000, RELAY_COMMAND_SENDME, "Data1234");
  212. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  213. pathbias_count_valid_cells(circ, &cell);
  214. else
  215. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  216. circ->cpath);
  217. ASSERT_UNCOUNTED_BW();
  218. /* Connected cell not in the half-opened list */
  219. PACK_CELL(4000, RELAY_COMMAND_CONNECTED, "Data1234");
  220. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  221. pathbias_count_valid_cells(circ, &cell);
  222. else
  223. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  224. circ->cpath);
  225. ASSERT_UNCOUNTED_BW();
  226. /* Resolved cell not in the half-opened list */
  227. PACK_CELL(4000, RELAY_COMMAND_RESOLVED, "Data1234");
  228. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  229. pathbias_count_valid_cells(circ, &cell);
  230. else
  231. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  232. circ->cpath);
  233. ASSERT_UNCOUNTED_BW();
  234. /* Connected cell: not counted -- we were open */
  235. edgeconn = ENTRY_TO_EDGE_CONN(entryconn2);
  236. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_CONNECTED, "Data1234");
  237. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  238. pathbias_count_valid_cells(circ, &cell);
  239. else
  240. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  241. circ->cpath);
  242. ASSERT_UNCOUNTED_BW();
  243. /* DATA cells up to limit */
  244. while (data_cells > 0) {
  245. ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
  246. ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
  247. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
  248. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  249. pathbias_count_valid_cells(circ, &cell);
  250. else
  251. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  252. circ->cpath);
  253. ASSERT_COUNTED_BW();
  254. data_cells--;
  255. }
  256. ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
  257. ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
  258. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
  259. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  260. pathbias_count_valid_cells(circ, &cell);
  261. else
  262. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  263. circ->cpath);
  264. ASSERT_UNCOUNTED_BW();
  265. /* SENDME cells up to limit */
  266. while (sendme_cells > 0) {
  267. ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
  268. ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
  269. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_SENDME, "Data1234");
  270. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  271. pathbias_count_valid_cells(circ, &cell);
  272. else
  273. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  274. circ->cpath);
  275. ASSERT_COUNTED_BW();
  276. sendme_cells--;
  277. }
  278. ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
  279. ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
  280. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_SENDME, "Data1234");
  281. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  282. pathbias_count_valid_cells(circ, &cell);
  283. else
  284. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  285. circ->cpath);
  286. ASSERT_UNCOUNTED_BW();
  287. /* Only one END cell */
  288. ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
  289. ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
  290. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
  291. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  292. pathbias_count_valid_cells(circ, &cell);
  293. else
  294. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  295. circ->cpath);
  296. ASSERT_COUNTED_BW();
  297. ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
  298. ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
  299. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
  300. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  301. pathbias_count_valid_cells(circ, &cell);
  302. else
  303. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  304. circ->cpath);
  305. ASSERT_UNCOUNTED_BW();
  306. edgeconn = ENTRY_TO_EDGE_CONN(entryconn3);
  307. edgeconn->base_.state = AP_CONN_STATE_OPEN;
  308. ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
  309. ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
  310. /* sendme cell on open entryconn with full window */
  311. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_SENDME, "Data1234");
  312. int ret =
  313. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  314. circ->cpath);
  315. tt_int_op(ret, OP_EQ, -END_CIRC_REASON_TORPROTOCOL);
  316. ASSERT_UNCOUNTED_BW();
  317. /* connected cell on a after EOF */
  318. ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
  319. ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
  320. edgeconn->base_.state = AP_CONN_STATE_CONNECT_WAIT;
  321. connection_edge_reached_eof(edgeconn);
  322. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_CONNECTED, "Data1234");
  323. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  324. pathbias_count_valid_cells(circ, &cell);
  325. else
  326. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  327. circ->cpath);
  328. ASSERT_COUNTED_BW();
  329. ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
  330. ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
  331. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_CONNECTED, "Data1234");
  332. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  333. pathbias_count_valid_cells(circ, &cell);
  334. else
  335. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  336. circ->cpath);
  337. ASSERT_UNCOUNTED_BW();
  338. /* DATA and SENDME after END cell */
  339. ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
  340. ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
  341. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
  342. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  343. pathbias_count_valid_cells(circ, &cell);
  344. else
  345. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  346. circ->cpath);
  347. ASSERT_COUNTED_BW();
  348. ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
  349. ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
  350. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_SENDME, "Data1234");
  351. ret =
  352. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  353. circ->cpath);
  354. tt_int_op(ret, OP_NE, -END_CIRC_REASON_TORPROTOCOL);
  355. ASSERT_UNCOUNTED_BW();
  356. ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
  357. ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
  358. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
  359. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  360. pathbias_count_valid_cells(circ, &cell);
  361. else
  362. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  363. circ->cpath);
  364. ASSERT_UNCOUNTED_BW();
  365. /* Resolved: 1 counted, more not */
  366. edgeconn = ENTRY_TO_EDGE_CONN(entryconn4);
  367. entryconn4->socks_request->command = SOCKS_COMMAND_RESOLVE;
  368. edgeconn->base_.state = AP_CONN_STATE_RESOLVE_WAIT;
  369. edgeconn->on_circuit = TO_CIRCUIT(circ);
  370. ENTRY_TO_CONN(entryconn4)->marked_for_close = 0;
  371. ENTRY_TO_CONN(entryconn4)->outbuf_flushlen = 0;
  372. connection_edge_reached_eof(edgeconn);
  373. ENTRY_TO_CONN(entryconn4)->marked_for_close = 0;
  374. ENTRY_TO_CONN(entryconn4)->outbuf_flushlen = 0;
  375. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_RESOLVED,
  376. "\x04\x04\x12\x00\x00\x01\x00\x00\x02\x00");
  377. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  378. pathbias_count_valid_cells(circ, &cell);
  379. else
  380. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  381. circ->cpath);
  382. ASSERT_COUNTED_BW();
  383. ENTRY_TO_CONN(entryconn4)->marked_for_close = 0;
  384. ENTRY_TO_CONN(entryconn4)->outbuf_flushlen = 0;
  385. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_RESOLVED,
  386. "\x04\x04\x12\x00\x00\x01\x00\x00\x02\x00");
  387. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  388. circ->cpath);
  389. ASSERT_UNCOUNTED_BW();
  390. /* Data not counted after resolved */
  391. ENTRY_TO_CONN(entryconn4)->marked_for_close = 0;
  392. ENTRY_TO_CONN(entryconn4)->outbuf_flushlen = 0;
  393. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
  394. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  395. pathbias_count_valid_cells(circ, &cell);
  396. else
  397. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  398. circ->cpath);
  399. ASSERT_UNCOUNTED_BW();
  400. /* End not counted after resolved */
  401. ENTRY_TO_CONN(entryconn4)->marked_for_close = 0;
  402. ENTRY_TO_CONN(entryconn4)->outbuf_flushlen = 0;
  403. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
  404. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  405. pathbias_count_valid_cells(circ, &cell);
  406. else
  407. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  408. circ->cpath);
  409. ASSERT_UNCOUNTED_BW();
  410. connection_free_minimal(ENTRY_TO_CONN(entryconn2));
  411. connection_free_minimal(ENTRY_TO_CONN(entryconn3));
  412. connection_free_minimal(ENTRY_TO_CONN(entryconn4));
  413. return 1;
  414. done:
  415. connection_free_minimal(ENTRY_TO_CONN(entryconn2));
  416. connection_free_minimal(ENTRY_TO_CONN(entryconn3));
  417. connection_free_minimal(ENTRY_TO_CONN(entryconn4));
  418. return 0;
  419. }
  420. static int
  421. halfstream_insert(origin_circuit_t *circ, edge_connection_t *edgeconn,
  422. streamid_t *streams, int num, int random)
  423. {
  424. int inserted = 0;
  425. /* Insert num random elements */
  426. while (inserted < num) {
  427. streamid_t id;
  428. if (random)
  429. id = (streamid_t)crypto_rand_int(65535)+1;
  430. else
  431. id = get_unique_stream_id_by_circ(circ);
  432. edgeconn->stream_id = id;
  433. /* Ensure it isn't there */
  434. if (connection_half_edge_find_stream_id(circ->half_streams, id)) {
  435. continue;
  436. }
  437. connection_half_edge_add(edgeconn, circ);
  438. if (streams)
  439. streams[inserted] = id;
  440. inserted++;
  441. }
  442. return inserted;
  443. }
  444. static void
  445. subtest_halfstream_insertremove(int num)
  446. {
  447. origin_circuit_t *circ =
  448. helper_create_origin_circuit(CIRCUIT_PURPOSE_C_GENERAL, 0);
  449. edge_connection_t *edgeconn;
  450. entry_connection_t *entryconn;
  451. streamid_t *streams = tor_malloc_zero(num*sizeof(streamid_t));
  452. int i = 0;
  453. circ->cpath->state = CPATH_STATE_AWAITING_KEYS;
  454. circ->cpath->deliver_window = CIRCWINDOW_START;
  455. entryconn = fake_entry_conn(circ, 23);
  456. edgeconn = ENTRY_TO_EDGE_CONN(entryconn);
  457. /* Explicity test all operations on an absent stream list */
  458. tt_int_op(connection_half_edge_is_valid_data(circ->half_streams,
  459. 23), OP_EQ, 0);
  460. tt_int_op(connection_half_edge_is_valid_connected(circ->half_streams,
  461. 23), OP_EQ, 0);
  462. tt_int_op(connection_half_edge_is_valid_sendme(circ->half_streams,
  463. 23), OP_EQ, 0);
  464. tt_int_op(connection_half_edge_is_valid_resolved(circ->half_streams,
  465. 23), OP_EQ, 0);
  466. tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
  467. 23), OP_EQ, 0);
  468. /* Insert a duplicate element; verify that other elements absent;
  469. * ensure removing it once works */
  470. edgeconn->stream_id = 23;
  471. connection_half_edge_add(edgeconn, circ);
  472. connection_half_edge_add(edgeconn, circ);
  473. connection_half_edge_add(edgeconn, circ);
  474. /* Verify that other elements absent */
  475. tt_int_op(connection_half_edge_is_valid_data(circ->half_streams,
  476. 22), OP_EQ, 0);
  477. tt_int_op(connection_half_edge_is_valid_connected(circ->half_streams,
  478. 22), OP_EQ, 0);
  479. tt_int_op(connection_half_edge_is_valid_sendme(circ->half_streams,
  480. 22), OP_EQ, 0);
  481. tt_int_op(connection_half_edge_is_valid_resolved(circ->half_streams,
  482. 22), OP_EQ, 0);
  483. tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
  484. 22), OP_EQ, 0);
  485. tt_int_op(connection_half_edge_is_valid_data(circ->half_streams,
  486. 24), OP_EQ, 0);
  487. tt_int_op(connection_half_edge_is_valid_connected(circ->half_streams,
  488. 24), OP_EQ, 0);
  489. tt_int_op(connection_half_edge_is_valid_sendme(circ->half_streams,
  490. 24), OP_EQ, 0);
  491. tt_int_op(connection_half_edge_is_valid_resolved(circ->half_streams,
  492. 24), OP_EQ, 0);
  493. tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
  494. 24), OP_EQ, 0);
  495. /* Verify we only remove it once */
  496. tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
  497. 23), OP_EQ, 1);
  498. tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
  499. 23), OP_EQ, 0);
  500. halfstream_insert(circ, edgeconn, streams, num, 1);
  501. /* Remove half of them */
  502. for (i = 0; i < num/2; i++) {
  503. tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
  504. streams[i]),
  505. OP_EQ, 1);
  506. }
  507. /* Verify first half of list is gone */
  508. for (i = 0; i < num/2; i++) {
  509. tt_ptr_op(connection_half_edge_find_stream_id(circ->half_streams,
  510. streams[i]),
  511. OP_EQ, NULL);
  512. }
  513. /* Verify second half of list is present */
  514. for (; i < num; i++) {
  515. tt_ptr_op(connection_half_edge_find_stream_id(circ->half_streams,
  516. streams[i]),
  517. OP_NE, NULL);
  518. }
  519. /* Remove other half. Verify list is empty. */
  520. for (i = num/2; i < num; i++) {
  521. tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
  522. streams[i]),
  523. OP_EQ, 1);
  524. }
  525. tt_int_op(smartlist_len(circ->half_streams), OP_EQ, 0);
  526. /* Explicity test all operations on an empty stream list */
  527. tt_int_op(connection_half_edge_is_valid_data(circ->half_streams,
  528. 23), OP_EQ, 0);
  529. tt_int_op(connection_half_edge_is_valid_connected(circ->half_streams,
  530. 23), OP_EQ, 0);
  531. tt_int_op(connection_half_edge_is_valid_sendme(circ->half_streams,
  532. 23), OP_EQ, 0);
  533. tt_int_op(connection_half_edge_is_valid_resolved(circ->half_streams,
  534. 23), OP_EQ, 0);
  535. tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
  536. 23), OP_EQ, 0);
  537. /* For valgrind, leave some around then free the circ */
  538. halfstream_insert(circ, edgeconn, NULL, 10, 0);
  539. done:
  540. tor_free(streams);
  541. circuit_free_(TO_CIRCUIT(circ));
  542. connection_free_minimal(ENTRY_TO_CONN(entryconn));
  543. }
  544. static void
  545. test_halfstream_insertremove(void *arg)
  546. {
  547. (void)arg;
  548. /* Suppress the WARN message we generate in this test */
  549. setup_full_capture_of_logs(LOG_WARN);
  550. /* Test insertion and removal with a few different sizes */
  551. subtest_halfstream_insertremove(10);
  552. subtest_halfstream_insertremove(100);
  553. subtest_halfstream_insertremove(1000);
  554. }
  555. static void
  556. test_halfstream_wrap(void *arg)
  557. {
  558. origin_circuit_t *circ =
  559. helper_create_origin_circuit(CIRCUIT_PURPOSE_C_GENERAL, 0);
  560. edge_connection_t *edgeconn;
  561. entry_connection_t *entryconn;
  562. circ->cpath->state = CPATH_STATE_AWAITING_KEYS;
  563. circ->cpath->deliver_window = CIRCWINDOW_START;
  564. entryconn = fake_entry_conn(circ, 23);
  565. edgeconn = ENTRY_TO_EDGE_CONN(entryconn);
  566. (void)arg;
  567. /* Suppress the WARN message we generate in this test */
  568. setup_full_capture_of_logs(LOG_WARN);
  569. MOCK(connection_mark_for_close_internal_, mock_mark_for_close);
  570. /* Verify that get_unique_stream_id_by_circ() can wrap uint16_t */
  571. circ->next_stream_id = 65530;
  572. halfstream_insert(circ, edgeconn, NULL, 7, 0);
  573. tt_int_op(circ->next_stream_id, OP_EQ, 2);
  574. tt_int_op(smartlist_len(circ->half_streams), OP_EQ, 7);
  575. /* Insert full-1 */
  576. halfstream_insert(circ, edgeconn, NULL,
  577. 65534-smartlist_len(circ->half_streams), 0);
  578. tt_int_op(smartlist_len(circ->half_streams), OP_EQ, 65534);
  579. /* Verify that we can get_unique_stream_id_by_circ() successfully */
  580. edgeconn->stream_id = get_unique_stream_id_by_circ(circ);
  581. tt_int_op(edgeconn->stream_id, OP_NE, 0); /* 0 is failure */
  582. /* Insert an opened stream on the circ with that id */
  583. ENTRY_TO_CONN(entryconn)->marked_for_close = 0;
  584. ENTRY_TO_CONN(entryconn)->outbuf_flushlen = 0;
  585. edgeconn->base_.state = AP_CONN_STATE_CONNECT_WAIT;
  586. circ->p_streams = edgeconn;
  587. /* Verify that get_unique_stream_id_by_circ() fails */
  588. tt_int_op(get_unique_stream_id_by_circ(circ), OP_EQ, 0); /* 0 is failure */
  589. /* eof the one opened stream. Verify it is now in half-closed */
  590. tt_int_op(smartlist_len(circ->half_streams), OP_EQ, 65534);
  591. connection_edge_reached_eof(edgeconn);
  592. tt_int_op(smartlist_len(circ->half_streams), OP_EQ, 65535);
  593. /* Verify get_unique_stream_id_by_circ() fails due to full half-closed */
  594. circ->p_streams = NULL;
  595. tt_int_op(get_unique_stream_id_by_circ(circ), OP_EQ, 0); /* 0 is failure */
  596. done:
  597. circuit_free_(TO_CIRCUIT(circ));
  598. connection_free_minimal(ENTRY_TO_CONN(entryconn));
  599. UNMOCK(connection_mark_for_close_internal_);
  600. }
  601. static void
  602. test_circbw_relay(void *arg)
  603. {
  604. cell_t cell;
  605. relay_header_t rh;
  606. tor_addr_t addr;
  607. edge_connection_t *edgeconn;
  608. entry_connection_t *entryconn1=NULL;
  609. origin_circuit_t *circ;
  610. int delivered = 0;
  611. int overhead = 0;
  612. (void)arg;
  613. MOCK(connection_mark_unattached_ap_, mock_connection_mark_unattached_ap_);
  614. MOCK(connection_start_reading, mock_start_reading);
  615. MOCK(connection_mark_for_close_internal_, mock_mark_for_close);
  616. MOCK(relay_send_command_from_edge_, mock_send_command);
  617. MOCK(circuit_mark_for_close_, mock_mark_circ_for_close);
  618. circ = helper_create_origin_circuit(CIRCUIT_PURPOSE_C_GENERAL, 0);
  619. circ->cpath->state = CPATH_STATE_AWAITING_KEYS;
  620. circ->cpath->deliver_window = CIRCWINDOW_START;
  621. entryconn1 = fake_entry_conn(circ, 1);
  622. edgeconn = ENTRY_TO_EDGE_CONN(entryconn1);
  623. /* Stream id 0: Not counted */
  624. PACK_CELL(0, RELAY_COMMAND_END, "Data1234");
  625. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  626. circ->cpath);
  627. ASSERT_UNCOUNTED_BW();
  628. /* Stream id 1: Counted */
  629. PACK_CELL(1, RELAY_COMMAND_END, "Data1234");
  630. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  631. circ->cpath);
  632. ASSERT_COUNTED_BW();
  633. /* Properly formatted connect cell: counted */
  634. PACK_CELL(1, RELAY_COMMAND_CONNECTED, "Data1234");
  635. tor_addr_parse(&addr, "30.40.50.60");
  636. rh.length = connected_cell_format_payload(cell.payload+RELAY_HEADER_SIZE,
  637. &addr, 1024);
  638. relay_header_pack((uint8_t*)&cell.payload, &rh); \
  639. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  640. circ->cpath);
  641. ASSERT_COUNTED_BW();
  642. /* Properly formatted resolved cell in correct state: counted */
  643. edgeconn->base_.state = AP_CONN_STATE_RESOLVE_WAIT;
  644. entryconn1->socks_request->command = SOCKS_COMMAND_RESOLVE;
  645. edgeconn->on_circuit = TO_CIRCUIT(circ);
  646. PACK_CELL(1, RELAY_COMMAND_RESOLVED,
  647. "\x04\x04\x12\x00\x00\x01\x00\x00\x02\x00");
  648. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  649. circ->cpath);
  650. ASSERT_COUNTED_BW();
  651. edgeconn->base_.state = AP_CONN_STATE_OPEN;
  652. entryconn1->socks_request->has_finished = 1;
  653. /* Connected cell after open: not counted */
  654. PACK_CELL(1, RELAY_COMMAND_CONNECTED, "Data1234");
  655. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  656. circ->cpath);
  657. ASSERT_UNCOUNTED_BW();
  658. /* Resolved cell after open: not counted */
  659. PACK_CELL(1, RELAY_COMMAND_RESOLVED, "Data1234");
  660. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  661. circ->cpath);
  662. ASSERT_UNCOUNTED_BW();
  663. /* Drop cell: not counted */
  664. PACK_CELL(1, RELAY_COMMAND_DROP, "Data1234");
  665. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  666. circ->cpath);
  667. ASSERT_UNCOUNTED_BW();
  668. /* Data cell on stream 0: not counted */
  669. PACK_CELL(0, RELAY_COMMAND_DATA, "Data1234");
  670. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  671. circ->cpath);
  672. ASSERT_UNCOUNTED_BW();
  673. /* Data cell on open connection: counted */
  674. ENTRY_TO_CONN(entryconn1)->marked_for_close = 0;
  675. PACK_CELL(1, RELAY_COMMAND_DATA, "Data1234");
  676. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  677. circ->cpath);
  678. ASSERT_COUNTED_BW();
  679. /* Empty Data cell on open connection: not counted */
  680. ENTRY_TO_CONN(entryconn1)->marked_for_close = 0;
  681. PACK_CELL(1, RELAY_COMMAND_DATA, "");
  682. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  683. circ->cpath);
  684. ASSERT_UNCOUNTED_BW();
  685. /* Sendme on valid stream: counted */
  686. edgeconn->package_window -= STREAMWINDOW_INCREMENT;
  687. ENTRY_TO_CONN(entryconn1)->outbuf_flushlen = 0;
  688. PACK_CELL(1, RELAY_COMMAND_SENDME, "Data1234");
  689. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  690. circ->cpath);
  691. ASSERT_COUNTED_BW();
  692. /* Sendme on valid stream with full window: not counted */
  693. ENTRY_TO_CONN(entryconn1)->outbuf_flushlen = 0;
  694. PACK_CELL(1, RELAY_COMMAND_SENDME, "Data1234");
  695. edgeconn->package_window = STREAMWINDOW_START;
  696. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  697. circ->cpath);
  698. ASSERT_UNCOUNTED_BW();
  699. /* Sendme on unknown stream: not counted */
  700. ENTRY_TO_CONN(entryconn1)->outbuf_flushlen = 0;
  701. PACK_CELL(1, RELAY_COMMAND_SENDME, "Data1234");
  702. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  703. circ->cpath);
  704. ASSERT_UNCOUNTED_BW();
  705. /* Sendme on circuit with full window: not counted */
  706. PACK_CELL(0, RELAY_COMMAND_SENDME, "Data1234");
  707. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  708. circ->cpath);
  709. ASSERT_UNCOUNTED_BW();
  710. /* Sendme on circuit with non-full window: counted */
  711. PACK_CELL(0, RELAY_COMMAND_SENDME, "Data1234");
  712. circ->cpath->package_window = 900;
  713. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  714. circ->cpath);
  715. ASSERT_COUNTED_BW();
  716. /* Invalid extended cell: not counted */
  717. PACK_CELL(1, RELAY_COMMAND_EXTENDED2, "Data1234");
  718. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  719. circ->cpath);
  720. ASSERT_UNCOUNTED_BW();
  721. /* Invalid extended cell: not counted */
  722. PACK_CELL(1, RELAY_COMMAND_EXTENDED, "Data1234");
  723. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  724. circ->cpath);
  725. ASSERT_UNCOUNTED_BW();
  726. /* Invalid HS cell: not counted */
  727. PACK_CELL(1, RELAY_COMMAND_ESTABLISH_INTRO, "Data1234");
  728. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  729. circ->cpath);
  730. ASSERT_UNCOUNTED_BW();
  731. /* "Valid" HS cell in expected state: counted */
  732. TO_CIRCUIT(circ)->purpose = CIRCUIT_PURPOSE_C_ESTABLISH_REND;
  733. PACK_CELL(1, RELAY_COMMAND_RENDEZVOUS_ESTABLISHED, "Data1234");
  734. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  735. circ->cpath);
  736. ASSERT_COUNTED_BW();
  737. /* End cell on non-closed connection: counted */
  738. PACK_CELL(1, RELAY_COMMAND_END, "Data1234");
  739. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  740. circ->cpath);
  741. ASSERT_COUNTED_BW();
  742. /* End cell on connection that already got one: not counted */
  743. PACK_CELL(1, RELAY_COMMAND_END, "Data1234");
  744. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  745. circ->cpath);
  746. ASSERT_UNCOUNTED_BW();
  747. /* Simulate closed stream on entryconn, then test: */
  748. if (!subtest_circbw_halfclosed(circ, 2))
  749. goto done;
  750. circ->base_.purpose = CIRCUIT_PURPOSE_PATH_BIAS_TESTING;
  751. if (!subtest_circbw_halfclosed(circ, 6))
  752. goto done;
  753. /* Path bias: truncated */
  754. tt_int_op(circ->base_.marked_for_close, OP_EQ, 0);
  755. PACK_CELL(0, RELAY_COMMAND_TRUNCATED, "Data1234");
  756. pathbias_count_valid_cells(circ, &cell);
  757. tt_int_op(circ->base_.marked_for_close, OP_EQ, 1);
  758. done:
  759. UNMOCK(connection_start_reading);
  760. UNMOCK(connection_mark_unattached_ap_);
  761. UNMOCK(connection_mark_for_close_internal_);
  762. UNMOCK(relay_send_command_from_edge_);
  763. UNMOCK(circuit_mark_for_close_);
  764. circuit_free_(TO_CIRCUIT(circ));
  765. connection_free_minimal(ENTRY_TO_CONN(entryconn1));
  766. }
  767. /* Tests for connection_edge_process_resolved_cell().
  768. The point of ..process_resolved_cell() is to handle an incoming cell
  769. on an entry connection, and call connection_mark_unattached_ap() and/or
  770. connection_ap_handshake_socks_resolved().
  771. */
  772. static void
  773. test_relaycell_resolved(void *arg)
  774. {
  775. entry_connection_t *entryconn;
  776. edge_connection_t *edgeconn;
  777. cell_t cell;
  778. relay_header_t rh;
  779. int r;
  780. or_options_t *options = get_options_mutable();
  781. #define SET_CELL(s) do { \
  782. memset(&cell, 0, sizeof(cell)); \
  783. memset(&rh, 0, sizeof(rh)); \
  784. memcpy(cell.payload + RELAY_HEADER_SIZE, (s), sizeof((s))-1); \
  785. rh.length = sizeof((s))-1; \
  786. rh.command = RELAY_COMMAND_RESOLVED; \
  787. } while (0)
  788. #define MOCK_RESET() do { \
  789. srm_ncalls = mum_ncalls = 0; \
  790. } while (0)
  791. #define ASSERT_MARK_CALLED(reason) do { \
  792. tt_int_op(mum_ncalls, OP_EQ, 1); \
  793. tt_ptr_op(mum_conn, OP_EQ, entryconn); \
  794. tt_int_op(mum_endreason, OP_EQ, (reason)); \
  795. } while (0)
  796. #define ASSERT_RESOLVED_CALLED(atype, answer, ttl, expires) do { \
  797. tt_int_op(srm_ncalls, OP_EQ, 1); \
  798. tt_ptr_op(srm_conn, OP_EQ, entryconn); \
  799. tt_int_op(srm_atype, OP_EQ, (atype)); \
  800. if ((answer) != NULL) { \
  801. tt_int_op(srm_alen, OP_EQ, sizeof(answer)-1); \
  802. tt_int_op(srm_alen, OP_LT, 512); \
  803. tt_int_op(srm_answer_is_set, OP_EQ, 1); \
  804. tt_mem_op(srm_answer, OP_EQ, answer, sizeof(answer)-1); \
  805. } else { \
  806. tt_int_op(srm_answer_is_set, OP_EQ, 0); \
  807. } \
  808. tt_int_op(srm_ttl, OP_EQ, ttl); \
  809. tt_i64_op(srm_expires, OP_EQ, expires); \
  810. } while (0)
  811. (void)arg;
  812. MOCK(connection_mark_unattached_ap_, mark_unattached_mock);
  813. MOCK(connection_ap_handshake_socks_resolved, socks_resolved_mock);
  814. options->ClientDNSRejectInternalAddresses = 0;
  815. SET_CELL(/* IPv4: 127.0.1.2, ttl 256 */
  816. "\x04\x04\x7f\x00\x01\x02\x00\x00\x01\x00"
  817. /* IPv4: 18.0.0.1, ttl 512 */
  818. "\x04\x04\x12\x00\x00\x01\x00\x00\x02\x00"
  819. /* IPv6: 2003::3, ttl 1024 */
  820. "\x06\x10"
  821. "\x20\x02\x00\x00\x00\x00\x00\x00"
  822. "\x00\x00\x00\x00\x00\x00\x00\x03"
  823. "\x00\x00\x04\x00");
  824. entryconn = entry_connection_new(CONN_TYPE_AP, AF_INET);
  825. edgeconn = ENTRY_TO_EDGE_CONN(entryconn);
  826. /* Try with connection in non-RESOLVE_WAIT state: cell gets ignored */
  827. MOCK_RESET();
  828. r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
  829. tt_int_op(r, OP_EQ, 0);
  830. tt_int_op(srm_ncalls, OP_EQ, 0);
  831. tt_int_op(mum_ncalls, OP_EQ, 0);
  832. /* Now put it in the right state. */
  833. ENTRY_TO_CONN(entryconn)->state = AP_CONN_STATE_RESOLVE_WAIT;
  834. entryconn->socks_request->command = SOCKS_COMMAND_RESOLVE;
  835. entryconn->entry_cfg.ipv4_traffic = 1;
  836. entryconn->entry_cfg.ipv6_traffic = 1;
  837. entryconn->entry_cfg.prefer_ipv6 = 0;
  838. /* We prefer ipv4, so we should get the first ipv4 answer */
  839. MOCK_RESET();
  840. r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
  841. tt_int_op(r, OP_EQ, 0);
  842. ASSERT_MARK_CALLED(END_STREAM_REASON_DONE|
  843. END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
  844. ASSERT_RESOLVED_CALLED(RESOLVED_TYPE_IPV4, "\x7f\x00\x01\x02", 256, -1);
  845. /* But we may be discarding private answers. */
  846. MOCK_RESET();
  847. options->ClientDNSRejectInternalAddresses = 1;
  848. r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
  849. tt_int_op(r, OP_EQ, 0);
  850. ASSERT_MARK_CALLED(END_STREAM_REASON_DONE|
  851. END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
  852. ASSERT_RESOLVED_CALLED(RESOLVED_TYPE_IPV4, "\x12\x00\x00\x01", 512, -1);
  853. /* now prefer ipv6, and get the first ipv6 answer */
  854. entryconn->entry_cfg.prefer_ipv6 = 1;
  855. MOCK_RESET();
  856. r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
  857. tt_int_op(r, OP_EQ, 0);
  858. ASSERT_MARK_CALLED(END_STREAM_REASON_DONE|
  859. END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
  860. ASSERT_RESOLVED_CALLED(RESOLVED_TYPE_IPV6,
  861. "\x20\x02\x00\x00\x00\x00\x00\x00"
  862. "\x00\x00\x00\x00\x00\x00\x00\x03",
  863. 1024, -1);
  864. /* With a cell that only has IPv4, we report IPv4 even if we prefer IPv6 */
  865. MOCK_RESET();
  866. SET_CELL("\x04\x04\x12\x00\x00\x01\x00\x00\x02\x00");
  867. r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
  868. tt_int_op(r, OP_EQ, 0);
  869. ASSERT_MARK_CALLED(END_STREAM_REASON_DONE|
  870. END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
  871. ASSERT_RESOLVED_CALLED(RESOLVED_TYPE_IPV4, "\x12\x00\x00\x01", 512, -1);
  872. /* But if we don't allow IPv4, we report nothing if the cell contains only
  873. * ipv4 */
  874. MOCK_RESET();
  875. entryconn->entry_cfg.ipv4_traffic = 0;
  876. r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
  877. tt_int_op(r, OP_EQ, 0);
  878. ASSERT_MARK_CALLED(END_STREAM_REASON_DONE|
  879. END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
  880. ASSERT_RESOLVED_CALLED(RESOLVED_TYPE_ERROR, NULL, -1, -1);
  881. /* If we wanted hostnames, we report nothing, since we only had IPs. */
  882. MOCK_RESET();
  883. entryconn->entry_cfg.ipv4_traffic = 1;
  884. entryconn->socks_request->command = SOCKS_COMMAND_RESOLVE_PTR;
  885. r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
  886. tt_int_op(r, OP_EQ, 0);
  887. ASSERT_MARK_CALLED(END_STREAM_REASON_DONE|
  888. END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
  889. ASSERT_RESOLVED_CALLED(RESOLVED_TYPE_ERROR, NULL, -1, -1);
  890. /* A hostname cell is fine though. */
  891. MOCK_RESET();
  892. SET_CELL("\x00\x0fwww.example.com\x00\x01\x00\x00");
  893. r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
  894. tt_int_op(r, OP_EQ, 0);
  895. ASSERT_MARK_CALLED(END_STREAM_REASON_DONE|
  896. END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
  897. ASSERT_RESOLVED_CALLED(RESOLVED_TYPE_HOSTNAME, "www.example.com", 65536, -1);
  898. /* error on malformed cell */
  899. MOCK_RESET();
  900. entryconn->socks_request->command = SOCKS_COMMAND_RESOLVE;
  901. SET_CELL("\x04\x04\x01\x02\x03\x04"); /* no ttl */
  902. r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
  903. tt_int_op(r, OP_EQ, 0);
  904. ASSERT_MARK_CALLED(END_STREAM_REASON_TORPROTOCOL);
  905. tt_int_op(srm_ncalls, OP_EQ, 0);
  906. /* error on all addresses private */
  907. MOCK_RESET();
  908. SET_CELL(/* IPv4: 127.0.1.2, ttl 256 */
  909. "\x04\x04\x7f\x00\x01\x02\x00\x00\x01\x00"
  910. /* IPv4: 192.168.1.1, ttl 256 */
  911. "\x04\x04\xc0\xa8\x01\x01\x00\x00\x01\x00");
  912. r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
  913. tt_int_op(r, OP_EQ, 0);
  914. ASSERT_MARK_CALLED(END_STREAM_REASON_TORPROTOCOL);
  915. ASSERT_RESOLVED_CALLED(RESOLVED_TYPE_ERROR_TRANSIENT, NULL, 0, TIME_MAX);
  916. /* Legit error code */
  917. MOCK_RESET();
  918. SET_CELL("\xf0\x15" "quiet and meaningless" "\x00\x00\x0f\xff");
  919. r = connection_edge_process_resolved_cell(edgeconn, &cell, &rh);
  920. tt_int_op(r, OP_EQ, 0);
  921. ASSERT_MARK_CALLED(END_STREAM_REASON_DONE|
  922. END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
  923. ASSERT_RESOLVED_CALLED(RESOLVED_TYPE_ERROR_TRANSIENT, NULL, -1, -1);
  924. done:
  925. UNMOCK(connection_mark_unattached_ap_);
  926. UNMOCK(connection_ap_handshake_socks_resolved);
  927. }
  928. struct testcase_t relaycell_tests[] = {
  929. { "resolved", test_relaycell_resolved, TT_FORK, NULL, NULL },
  930. { "circbw", test_circbw_relay, TT_FORK, NULL, NULL },
  931. { "halfstream", test_halfstream_insertremove, TT_FORK, NULL, NULL },
  932. { "streamwrap", test_halfstream_wrap, TT_FORK, NULL, NULL },
  933. END_OF_TESTCASES
  934. };