test_relaycell.c 39 KB

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