test_relaycell.c 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075
  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 RELAY_PRIVATE
  5. #define CIRCUITLIST_PRIVATE
  6. #define CONNECTION_EDGE_PRIVATE
  7. #define CONNECTION_PRIVATE
  8. #include "core/or/or.h"
  9. #include "core/mainloop/mainloop.h"
  10. #include "app/config/config.h"
  11. #include "core/mainloop/connection.h"
  12. #include "lib/crypt_ops/crypto_cipher.h"
  13. #include "lib/crypt_ops/crypto_rand.h"
  14. #include "core/or/circuitbuild.h"
  15. #include "core/or/circuitlist.h"
  16. #include "core/or/connection_edge.h"
  17. #include "core/or/sendme.h"
  18. #include "core/or/relay.h"
  19. #include "test/test.h"
  20. #include "test/log_test_helpers.h"
  21. #include "core/or/cell_st.h"
  22. #include "core/or/crypt_path_st.h"
  23. #include "core/or/entry_connection_st.h"
  24. #include "core/or/origin_circuit_st.h"
  25. #include "core/or/socks_request_st.h"
  26. #include "core/or/half_edge_st.h"
  27. #include "feature/client/circpathbias.h"
  28. #include "core/or/connection_edge.h"
  29. static int srm_ncalls;
  30. static entry_connection_t *srm_conn;
  31. static int srm_atype;
  32. static size_t srm_alen;
  33. static int srm_answer_is_set;
  34. static uint8_t srm_answer[512];
  35. static int srm_ttl;
  36. static time_t srm_expires;
  37. /* Mock replacement for connection_ap_hannshake_socks_resolved() */
  38. static void
  39. socks_resolved_mock(entry_connection_t *conn,
  40. int answer_type,
  41. size_t answer_len,
  42. const uint8_t *answer,
  43. int ttl,
  44. time_t expires)
  45. {
  46. srm_ncalls++;
  47. srm_conn = conn;
  48. srm_atype = answer_type;
  49. srm_alen = answer_len;
  50. if (answer) {
  51. memset(srm_answer, 0, sizeof(srm_answer));
  52. memcpy(srm_answer, answer, answer_len < 512 ? answer_len : 512);
  53. srm_answer_is_set = 1;
  54. } else {
  55. srm_answer_is_set = 0;
  56. }
  57. srm_ttl = ttl;
  58. srm_expires = expires;
  59. }
  60. static int mum_ncalls;
  61. static entry_connection_t *mum_conn;
  62. static int mum_endreason;
  63. /* Mock replacement for connection_mark_unattached_ap_() */
  64. static void
  65. mark_unattached_mock(entry_connection_t *conn, int endreason,
  66. int line, const char *file)
  67. {
  68. ++mum_ncalls;
  69. mum_conn = conn;
  70. mum_endreason = endreason;
  71. (void) line;
  72. (void) file;
  73. }
  74. /* Helper: Return a newly allocated and initialized origin circuit with
  75. * purpose and flags. A default HS identifier is set to an ed25519
  76. * authentication key for introduction point. */
  77. static origin_circuit_t *
  78. helper_create_origin_circuit(int purpose, int flags)
  79. {
  80. origin_circuit_t *circ = NULL;
  81. circ = origin_circuit_init(purpose, flags);
  82. tor_assert(circ);
  83. circ->cpath = tor_malloc_zero(sizeof(crypt_path_t));
  84. circ->cpath->magic = CRYPT_PATH_MAGIC;
  85. circ->cpath->state = CPATH_STATE_OPEN;
  86. circ->cpath->package_window = circuit_initial_package_window();
  87. circ->cpath->deliver_window = CIRCWINDOW_START;
  88. circ->cpath->prev = circ->cpath;
  89. /* Create a default HS identifier. */
  90. circ->hs_ident = tor_malloc_zero(sizeof(hs_ident_circuit_t));
  91. return circ;
  92. }
  93. static void
  94. mock_connection_mark_unattached_ap_(entry_connection_t *conn, int endreason,
  95. int line, const char *file)
  96. {
  97. (void) line;
  98. (void) file;
  99. conn->edge_.end_reason = endreason;
  100. }
  101. static void
  102. mock_mark_circ_for_close(circuit_t *circ, int reason, int line,
  103. const char *file)
  104. {
  105. (void)reason; (void)line; (void)file;
  106. circ->marked_for_close = 1;
  107. return;
  108. }
  109. static void
  110. mock_mark_for_close(connection_t *conn,
  111. int line, const char *file)
  112. {
  113. (void)line;
  114. (void)file;
  115. conn->marked_for_close = 1;
  116. return;
  117. }
  118. static void
  119. mock_start_reading(connection_t *conn)
  120. {
  121. (void)conn;
  122. return;
  123. }
  124. static int
  125. mock_send_command(streamid_t stream_id, circuit_t *circ,
  126. uint8_t relay_command, const char *payload,
  127. size_t payload_len, crypt_path_t *cpath_layer,
  128. const char *filename, int lineno)
  129. {
  130. (void)stream_id; (void)circ;
  131. (void)relay_command; (void)payload;
  132. (void)payload_len; (void)cpath_layer;
  133. (void)filename; (void)lineno;
  134. return 0;
  135. }
  136. static entry_connection_t *
  137. fake_entry_conn(origin_circuit_t *oncirc, streamid_t id)
  138. {
  139. edge_connection_t *edgeconn;
  140. entry_connection_t *entryconn;
  141. entryconn = entry_connection_new(CONN_TYPE_AP, AF_INET);
  142. edgeconn = ENTRY_TO_EDGE_CONN(entryconn);
  143. edgeconn->base_.state = AP_CONN_STATE_CONNECT_WAIT;
  144. edgeconn->deliver_window = STREAMWINDOW_START;
  145. edgeconn->package_window = STREAMWINDOW_START;
  146. edgeconn->stream_id = id;
  147. edgeconn->on_circuit = TO_CIRCUIT(oncirc);
  148. edgeconn->cpath_layer = oncirc->cpath;
  149. return entryconn;
  150. }
  151. #define PACK_CELL(id, cmd, body_s) do { \
  152. memset(&cell, 0, sizeof(cell)); \
  153. memset(&rh, 0, sizeof(rh)); \
  154. memcpy(cell.payload+RELAY_HEADER_SIZE, (body_s), sizeof((body_s))-1); \
  155. rh.length = sizeof((body_s))-1; \
  156. rh.command = (cmd); \
  157. rh.stream_id = (id); \
  158. relay_header_pack((uint8_t*)&cell.payload, &rh); \
  159. } while (0)
  160. #define ASSERT_COUNTED_BW() do { \
  161. tt_int_op(circ->n_delivered_read_circ_bw, OP_EQ, delivered+rh.length); \
  162. tt_int_op(circ->n_overhead_read_circ_bw, OP_EQ, \
  163. overhead+RELAY_PAYLOAD_SIZE-rh.length); \
  164. delivered = circ->n_delivered_read_circ_bw; \
  165. overhead = circ->n_overhead_read_circ_bw; \
  166. } while (0)
  167. #define ASSERT_UNCOUNTED_BW() do { \
  168. tt_int_op(circ->n_delivered_read_circ_bw, OP_EQ, delivered); \
  169. tt_int_op(circ->n_overhead_read_circ_bw, OP_EQ, overhead); \
  170. } while (0)
  171. static int
  172. subtest_circbw_halfclosed(origin_circuit_t *circ, streamid_t init_id)
  173. {
  174. cell_t cell;
  175. relay_header_t rh;
  176. edge_connection_t *edgeconn;
  177. entry_connection_t *entryconn2=NULL;
  178. entry_connection_t *entryconn3=NULL;
  179. entry_connection_t *entryconn4=NULL;
  180. int delivered = circ->n_delivered_read_circ_bw;
  181. int overhead = circ->n_overhead_read_circ_bw;
  182. /* Make new entryconns */
  183. entryconn2 = fake_entry_conn(circ, init_id);
  184. entryconn2->socks_request->has_finished = 1;
  185. entryconn3 = fake_entry_conn(circ, init_id+1);
  186. entryconn3->socks_request->has_finished = 1;
  187. entryconn4 = fake_entry_conn(circ, init_id+2);
  188. entryconn4->socks_request->has_finished = 1;
  189. edgeconn = ENTRY_TO_EDGE_CONN(entryconn2);
  190. edgeconn->package_window = 23;
  191. edgeconn->base_.state = AP_CONN_STATE_OPEN;
  192. int data_cells = edgeconn->deliver_window;
  193. int sendme_cells = (STREAMWINDOW_START-edgeconn->package_window)
  194. /STREAMWINDOW_INCREMENT;
  195. ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
  196. ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
  197. connection_edge_reached_eof(edgeconn);
  198. /* Data cell not in the half-opened list */
  199. PACK_CELL(4000, RELAY_COMMAND_DATA, "Data1234");
  200. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  201. pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
  202. else
  203. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  204. circ->cpath);
  205. ASSERT_UNCOUNTED_BW();
  206. /* Sendme cell not in the half-opened list */
  207. PACK_CELL(4000, RELAY_COMMAND_SENDME, "Data1234");
  208. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  209. pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
  210. else
  211. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  212. circ->cpath);
  213. ASSERT_UNCOUNTED_BW();
  214. /* Connected cell not in the half-opened list */
  215. PACK_CELL(4000, RELAY_COMMAND_CONNECTED, "Data1234");
  216. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  217. pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
  218. else
  219. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  220. circ->cpath);
  221. ASSERT_UNCOUNTED_BW();
  222. /* Resolved cell not in the half-opened list */
  223. PACK_CELL(4000, RELAY_COMMAND_RESOLVED, "Data1234");
  224. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  225. pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
  226. else
  227. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  228. circ->cpath);
  229. ASSERT_UNCOUNTED_BW();
  230. /* Connected cell: not counted -- we were open */
  231. edgeconn = ENTRY_TO_EDGE_CONN(entryconn2);
  232. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_CONNECTED, "Data1234");
  233. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  234. pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
  235. else
  236. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  237. circ->cpath);
  238. ASSERT_UNCOUNTED_BW();
  239. /* DATA cells up to limit */
  240. while (data_cells > 0) {
  241. ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
  242. ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
  243. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
  244. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  245. pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
  246. else
  247. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  248. circ->cpath);
  249. ASSERT_COUNTED_BW();
  250. data_cells--;
  251. }
  252. ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
  253. ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
  254. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
  255. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  256. pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
  257. else
  258. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  259. circ->cpath);
  260. ASSERT_UNCOUNTED_BW();
  261. /* SENDME cells up to limit */
  262. while (sendme_cells > 0) {
  263. ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
  264. ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
  265. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_SENDME, "Data1234");
  266. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  267. pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
  268. else
  269. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  270. circ->cpath);
  271. ASSERT_COUNTED_BW();
  272. sendme_cells--;
  273. }
  274. ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
  275. ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
  276. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_SENDME, "Data1234");
  277. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  278. pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
  279. else
  280. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  281. circ->cpath);
  282. ASSERT_UNCOUNTED_BW();
  283. /* Only one END cell */
  284. ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
  285. ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
  286. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
  287. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  288. pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
  289. else
  290. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  291. circ->cpath);
  292. ASSERT_COUNTED_BW();
  293. ENTRY_TO_CONN(entryconn2)->marked_for_close = 0;
  294. ENTRY_TO_CONN(entryconn2)->outbuf_flushlen = 0;
  295. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
  296. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  297. pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
  298. else
  299. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  300. circ->cpath);
  301. ASSERT_UNCOUNTED_BW();
  302. edgeconn = ENTRY_TO_EDGE_CONN(entryconn3);
  303. edgeconn->base_.state = AP_CONN_STATE_OPEN;
  304. ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
  305. ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
  306. /* sendme cell on open entryconn with full window */
  307. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_SENDME, "Data1234");
  308. int ret =
  309. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  310. circ->cpath);
  311. tt_int_op(ret, OP_EQ, -END_CIRC_REASON_TORPROTOCOL);
  312. ASSERT_UNCOUNTED_BW();
  313. /* connected cell on a after EOF */
  314. ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
  315. ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
  316. edgeconn->base_.state = AP_CONN_STATE_CONNECT_WAIT;
  317. connection_edge_reached_eof(edgeconn);
  318. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_CONNECTED, "Data1234");
  319. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  320. pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
  321. else
  322. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  323. circ->cpath);
  324. ASSERT_COUNTED_BW();
  325. ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
  326. ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
  327. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_CONNECTED, "Data1234");
  328. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  329. pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
  330. else
  331. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  332. circ->cpath);
  333. ASSERT_UNCOUNTED_BW();
  334. /* DATA and SENDME after END cell */
  335. ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
  336. ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
  337. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
  338. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  339. pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
  340. else
  341. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  342. circ->cpath);
  343. ASSERT_COUNTED_BW();
  344. ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
  345. ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
  346. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_SENDME, "Data1234");
  347. ret =
  348. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  349. circ->cpath);
  350. tt_int_op(ret, OP_NE, -END_CIRC_REASON_TORPROTOCOL);
  351. ASSERT_UNCOUNTED_BW();
  352. ENTRY_TO_CONN(entryconn3)->marked_for_close = 0;
  353. ENTRY_TO_CONN(entryconn3)->outbuf_flushlen = 0;
  354. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
  355. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  356. pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
  357. else
  358. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  359. circ->cpath);
  360. ASSERT_UNCOUNTED_BW();
  361. /* Resolved: 1 counted, more not */
  362. edgeconn = ENTRY_TO_EDGE_CONN(entryconn4);
  363. entryconn4->socks_request->command = SOCKS_COMMAND_RESOLVE;
  364. edgeconn->base_.state = AP_CONN_STATE_RESOLVE_WAIT;
  365. edgeconn->on_circuit = TO_CIRCUIT(circ);
  366. ENTRY_TO_CONN(entryconn4)->marked_for_close = 0;
  367. ENTRY_TO_CONN(entryconn4)->outbuf_flushlen = 0;
  368. connection_edge_reached_eof(edgeconn);
  369. ENTRY_TO_CONN(entryconn4)->marked_for_close = 0;
  370. ENTRY_TO_CONN(entryconn4)->outbuf_flushlen = 0;
  371. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_RESOLVED,
  372. "\x04\x04\x12\x00\x00\x01\x00\x00\x02\x00");
  373. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  374. pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
  375. else
  376. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  377. circ->cpath);
  378. ASSERT_COUNTED_BW();
  379. ENTRY_TO_CONN(entryconn4)->marked_for_close = 0;
  380. ENTRY_TO_CONN(entryconn4)->outbuf_flushlen = 0;
  381. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_RESOLVED,
  382. "\x04\x04\x12\x00\x00\x01\x00\x00\x02\x00");
  383. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  384. circ->cpath);
  385. ASSERT_UNCOUNTED_BW();
  386. /* Data not counted after resolved */
  387. ENTRY_TO_CONN(entryconn4)->marked_for_close = 0;
  388. ENTRY_TO_CONN(entryconn4)->outbuf_flushlen = 0;
  389. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_DATA, "Data1234");
  390. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  391. pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
  392. else
  393. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  394. circ->cpath);
  395. ASSERT_UNCOUNTED_BW();
  396. /* End not counted after resolved */
  397. ENTRY_TO_CONN(entryconn4)->marked_for_close = 0;
  398. ENTRY_TO_CONN(entryconn4)->outbuf_flushlen = 0;
  399. PACK_CELL(edgeconn->stream_id, RELAY_COMMAND_END, "Data1234");
  400. if (circ->base_.purpose == CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
  401. pathbias_count_valid_cells(TO_CIRCUIT(circ), &cell);
  402. else
  403. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  404. circ->cpath);
  405. ASSERT_UNCOUNTED_BW();
  406. connection_free_minimal(ENTRY_TO_CONN(entryconn2));
  407. connection_free_minimal(ENTRY_TO_CONN(entryconn3));
  408. connection_free_minimal(ENTRY_TO_CONN(entryconn4));
  409. return 1;
  410. done:
  411. connection_free_minimal(ENTRY_TO_CONN(entryconn2));
  412. connection_free_minimal(ENTRY_TO_CONN(entryconn3));
  413. connection_free_minimal(ENTRY_TO_CONN(entryconn4));
  414. return 0;
  415. }
  416. static int
  417. halfstream_insert(origin_circuit_t *circ, edge_connection_t *edgeconn,
  418. streamid_t *streams, int num, int random)
  419. {
  420. int inserted = 0;
  421. /* Insert num random elements */
  422. while (inserted < num) {
  423. streamid_t id;
  424. if (random)
  425. id = (streamid_t)crypto_rand_int(65535)+1;
  426. else
  427. id = get_unique_stream_id_by_circ(circ);
  428. edgeconn->stream_id = id;
  429. /* Ensure it isn't there */
  430. if (connection_half_edge_find_stream_id(circ->half_streams, id)) {
  431. continue;
  432. }
  433. connection_half_edge_add(edgeconn, circ);
  434. if (streams)
  435. streams[inserted] = id;
  436. inserted++;
  437. }
  438. return inserted;
  439. }
  440. static void
  441. subtest_halfstream_insertremove(int num)
  442. {
  443. origin_circuit_t *circ =
  444. helper_create_origin_circuit(CIRCUIT_PURPOSE_C_GENERAL, 0);
  445. edge_connection_t *edgeconn;
  446. entry_connection_t *entryconn;
  447. streamid_t *streams = tor_malloc_zero(num*sizeof(streamid_t));
  448. int i = 0;
  449. circ->cpath->state = CPATH_STATE_AWAITING_KEYS;
  450. circ->cpath->deliver_window = CIRCWINDOW_START;
  451. entryconn = fake_entry_conn(circ, 23);
  452. edgeconn = ENTRY_TO_EDGE_CONN(entryconn);
  453. /* Explicity test all operations on an absent stream list */
  454. tt_int_op(connection_half_edge_is_valid_data(circ->half_streams,
  455. 23), OP_EQ, 0);
  456. tt_int_op(connection_half_edge_is_valid_connected(circ->half_streams,
  457. 23), OP_EQ, 0);
  458. tt_int_op(connection_half_edge_is_valid_sendme(circ->half_streams,
  459. 23), OP_EQ, 0);
  460. tt_int_op(connection_half_edge_is_valid_resolved(circ->half_streams,
  461. 23), OP_EQ, 0);
  462. tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
  463. 23), OP_EQ, 0);
  464. /* Insert a duplicate element; verify that other elements absent;
  465. * ensure removing it once works */
  466. edgeconn->stream_id = 23;
  467. connection_half_edge_add(edgeconn, circ);
  468. connection_half_edge_add(edgeconn, circ);
  469. connection_half_edge_add(edgeconn, circ);
  470. /* Verify that other elements absent */
  471. tt_int_op(connection_half_edge_is_valid_data(circ->half_streams,
  472. 22), OP_EQ, 0);
  473. tt_int_op(connection_half_edge_is_valid_connected(circ->half_streams,
  474. 22), OP_EQ, 0);
  475. tt_int_op(connection_half_edge_is_valid_sendme(circ->half_streams,
  476. 22), OP_EQ, 0);
  477. tt_int_op(connection_half_edge_is_valid_resolved(circ->half_streams,
  478. 22), OP_EQ, 0);
  479. tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
  480. 22), OP_EQ, 0);
  481. tt_int_op(connection_half_edge_is_valid_data(circ->half_streams,
  482. 24), OP_EQ, 0);
  483. tt_int_op(connection_half_edge_is_valid_connected(circ->half_streams,
  484. 24), OP_EQ, 0);
  485. tt_int_op(connection_half_edge_is_valid_sendme(circ->half_streams,
  486. 24), OP_EQ, 0);
  487. tt_int_op(connection_half_edge_is_valid_resolved(circ->half_streams,
  488. 24), OP_EQ, 0);
  489. tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
  490. 24), OP_EQ, 0);
  491. /* Verify we only remove it once */
  492. tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
  493. 23), OP_EQ, 1);
  494. tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
  495. 23), OP_EQ, 0);
  496. halfstream_insert(circ, edgeconn, streams, num, 1);
  497. /* Remove half of them */
  498. for (i = 0; i < num/2; i++) {
  499. tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
  500. streams[i]),
  501. OP_EQ, 1);
  502. }
  503. /* Verify first half of list is gone */
  504. for (i = 0; i < num/2; i++) {
  505. tt_ptr_op(connection_half_edge_find_stream_id(circ->half_streams,
  506. streams[i]),
  507. OP_EQ, NULL);
  508. }
  509. /* Verify second half of list is present */
  510. for (; i < num; i++) {
  511. tt_ptr_op(connection_half_edge_find_stream_id(circ->half_streams,
  512. streams[i]),
  513. OP_NE, NULL);
  514. }
  515. /* Remove other half. Verify list is empty. */
  516. for (i = num/2; i < num; i++) {
  517. tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
  518. streams[i]),
  519. OP_EQ, 1);
  520. }
  521. tt_int_op(smartlist_len(circ->half_streams), OP_EQ, 0);
  522. /* Explicity test all operations on an empty stream list */
  523. tt_int_op(connection_half_edge_is_valid_data(circ->half_streams,
  524. 23), OP_EQ, 0);
  525. tt_int_op(connection_half_edge_is_valid_connected(circ->half_streams,
  526. 23), OP_EQ, 0);
  527. tt_int_op(connection_half_edge_is_valid_sendme(circ->half_streams,
  528. 23), OP_EQ, 0);
  529. tt_int_op(connection_half_edge_is_valid_resolved(circ->half_streams,
  530. 23), OP_EQ, 0);
  531. tt_int_op(connection_half_edge_is_valid_end(circ->half_streams,
  532. 23), OP_EQ, 0);
  533. /* For valgrind, leave some around then free the circ */
  534. halfstream_insert(circ, edgeconn, NULL, 10, 0);
  535. done:
  536. tor_free(streams);
  537. circuit_free_(TO_CIRCUIT(circ));
  538. connection_free_minimal(ENTRY_TO_CONN(entryconn));
  539. }
  540. static void
  541. test_halfstream_insertremove(void *arg)
  542. {
  543. (void)arg;
  544. /* Suppress the WARN message we generate in this test */
  545. setup_full_capture_of_logs(LOG_WARN);
  546. /* Test insertion and removal with a few different sizes */
  547. subtest_halfstream_insertremove(10);
  548. subtest_halfstream_insertremove(100);
  549. subtest_halfstream_insertremove(1000);
  550. }
  551. static void
  552. test_halfstream_wrap(void *arg)
  553. {
  554. origin_circuit_t *circ =
  555. helper_create_origin_circuit(CIRCUIT_PURPOSE_C_GENERAL, 0);
  556. edge_connection_t *edgeconn;
  557. entry_connection_t *entryconn;
  558. circ->cpath->state = CPATH_STATE_AWAITING_KEYS;
  559. circ->cpath->deliver_window = CIRCWINDOW_START;
  560. entryconn = fake_entry_conn(circ, 23);
  561. edgeconn = ENTRY_TO_EDGE_CONN(entryconn);
  562. (void)arg;
  563. /* Suppress the WARN message we generate in this test */
  564. setup_full_capture_of_logs(LOG_WARN);
  565. MOCK(connection_mark_for_close_internal_, mock_mark_for_close);
  566. /* Verify that get_unique_stream_id_by_circ() can wrap uint16_t */
  567. circ->next_stream_id = 65530;
  568. halfstream_insert(circ, edgeconn, NULL, 7, 0);
  569. tt_int_op(circ->next_stream_id, OP_EQ, 2);
  570. tt_int_op(smartlist_len(circ->half_streams), OP_EQ, 7);
  571. /* Insert full-1 */
  572. halfstream_insert(circ, edgeconn, NULL,
  573. 65534-smartlist_len(circ->half_streams), 0);
  574. tt_int_op(smartlist_len(circ->half_streams), OP_EQ, 65534);
  575. /* Verify that we can get_unique_stream_id_by_circ() successfully */
  576. edgeconn->stream_id = get_unique_stream_id_by_circ(circ);
  577. tt_int_op(edgeconn->stream_id, OP_NE, 0); /* 0 is failure */
  578. /* Insert an opened stream on the circ with that id */
  579. ENTRY_TO_CONN(entryconn)->marked_for_close = 0;
  580. ENTRY_TO_CONN(entryconn)->outbuf_flushlen = 0;
  581. edgeconn->base_.state = AP_CONN_STATE_CONNECT_WAIT;
  582. circ->p_streams = edgeconn;
  583. /* Verify that get_unique_stream_id_by_circ() fails */
  584. tt_int_op(get_unique_stream_id_by_circ(circ), OP_EQ, 0); /* 0 is failure */
  585. /* eof the one opened stream. Verify it is now in half-closed */
  586. tt_int_op(smartlist_len(circ->half_streams), OP_EQ, 65534);
  587. connection_edge_reached_eof(edgeconn);
  588. tt_int_op(smartlist_len(circ->half_streams), OP_EQ, 65535);
  589. /* Verify get_unique_stream_id_by_circ() fails due to full half-closed */
  590. circ->p_streams = NULL;
  591. tt_int_op(get_unique_stream_id_by_circ(circ), OP_EQ, 0); /* 0 is failure */
  592. done:
  593. circuit_free_(TO_CIRCUIT(circ));
  594. connection_free_minimal(ENTRY_TO_CONN(entryconn));
  595. UNMOCK(connection_mark_for_close_internal_);
  596. }
  597. static void
  598. test_circbw_relay(void *arg)
  599. {
  600. cell_t cell;
  601. relay_header_t rh;
  602. tor_addr_t addr;
  603. edge_connection_t *edgeconn;
  604. entry_connection_t *entryconn1=NULL;
  605. origin_circuit_t *circ;
  606. int delivered = 0;
  607. int overhead = 0;
  608. (void)arg;
  609. MOCK(connection_mark_unattached_ap_, mock_connection_mark_unattached_ap_);
  610. MOCK(connection_start_reading, mock_start_reading);
  611. MOCK(connection_mark_for_close_internal_, mock_mark_for_close);
  612. MOCK(relay_send_command_from_edge_, mock_send_command);
  613. MOCK(circuit_mark_for_close_, mock_mark_circ_for_close);
  614. circ = helper_create_origin_circuit(CIRCUIT_PURPOSE_C_GENERAL, 0);
  615. circ->cpath->state = CPATH_STATE_AWAITING_KEYS;
  616. circ->cpath->deliver_window = CIRCWINDOW_START;
  617. entryconn1 = fake_entry_conn(circ, 1);
  618. edgeconn = ENTRY_TO_EDGE_CONN(entryconn1);
  619. /* Stream id 0: Not counted */
  620. PACK_CELL(0, RELAY_COMMAND_END, "Data1234");
  621. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  622. circ->cpath);
  623. ASSERT_UNCOUNTED_BW();
  624. /* Stream id 1: Counted */
  625. PACK_CELL(1, RELAY_COMMAND_END, "Data1234");
  626. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  627. circ->cpath);
  628. ASSERT_COUNTED_BW();
  629. /* Properly formatted connect cell: counted */
  630. PACK_CELL(1, RELAY_COMMAND_CONNECTED, "Data1234");
  631. tor_addr_parse(&addr, "30.40.50.60");
  632. rh.length = connected_cell_format_payload(cell.payload+RELAY_HEADER_SIZE,
  633. &addr, 1024);
  634. relay_header_pack((uint8_t*)&cell.payload, &rh); \
  635. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  636. circ->cpath);
  637. ASSERT_COUNTED_BW();
  638. /* Properly formatted resolved cell in correct state: counted */
  639. edgeconn->base_.state = AP_CONN_STATE_RESOLVE_WAIT;
  640. entryconn1->socks_request->command = SOCKS_COMMAND_RESOLVE;
  641. edgeconn->on_circuit = TO_CIRCUIT(circ);
  642. PACK_CELL(1, RELAY_COMMAND_RESOLVED,
  643. "\x04\x04\x12\x00\x00\x01\x00\x00\x02\x00");
  644. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  645. circ->cpath);
  646. ASSERT_COUNTED_BW();
  647. edgeconn->base_.state = AP_CONN_STATE_OPEN;
  648. entryconn1->socks_request->has_finished = 1;
  649. /* Connected cell after open: not counted */
  650. PACK_CELL(1, RELAY_COMMAND_CONNECTED, "Data1234");
  651. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  652. circ->cpath);
  653. ASSERT_UNCOUNTED_BW();
  654. /* Resolved cell after open: not counted */
  655. PACK_CELL(1, RELAY_COMMAND_RESOLVED, "Data1234");
  656. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  657. circ->cpath);
  658. ASSERT_UNCOUNTED_BW();
  659. /* Drop cell: not counted */
  660. PACK_CELL(1, RELAY_COMMAND_DROP, "Data1234");
  661. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  662. circ->cpath);
  663. ASSERT_UNCOUNTED_BW();
  664. /* Data cell on stream 0: not counted */
  665. PACK_CELL(0, RELAY_COMMAND_DATA, "Data1234");
  666. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  667. circ->cpath);
  668. ASSERT_UNCOUNTED_BW();
  669. /* Data cell on open connection: counted */
  670. ENTRY_TO_CONN(entryconn1)->marked_for_close = 0;
  671. PACK_CELL(1, RELAY_COMMAND_DATA, "Data1234");
  672. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  673. circ->cpath);
  674. ASSERT_COUNTED_BW();
  675. /* Empty Data cell on open connection: not counted */
  676. ENTRY_TO_CONN(entryconn1)->marked_for_close = 0;
  677. PACK_CELL(1, RELAY_COMMAND_DATA, "");
  678. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  679. circ->cpath);
  680. ASSERT_UNCOUNTED_BW();
  681. /* Sendme on valid stream: counted */
  682. edgeconn->package_window -= STREAMWINDOW_INCREMENT;
  683. ENTRY_TO_CONN(entryconn1)->outbuf_flushlen = 0;
  684. PACK_CELL(1, RELAY_COMMAND_SENDME, "Data1234");
  685. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  686. circ->cpath);
  687. ASSERT_COUNTED_BW();
  688. /* Sendme on valid stream with full window: not counted */
  689. ENTRY_TO_CONN(entryconn1)->outbuf_flushlen = 0;
  690. PACK_CELL(1, RELAY_COMMAND_SENDME, "Data1234");
  691. edgeconn->package_window = STREAMWINDOW_START;
  692. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  693. circ->cpath);
  694. ASSERT_UNCOUNTED_BW();
  695. /* Sendme on unknown stream: not counted */
  696. ENTRY_TO_CONN(entryconn1)->outbuf_flushlen = 0;
  697. PACK_CELL(1, RELAY_COMMAND_SENDME, "Data1234");
  698. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), NULL,
  699. circ->cpath);
  700. ASSERT_UNCOUNTED_BW();
  701. /* Sendme on circuit with full window: not counted */
  702. PACK_CELL(0, RELAY_COMMAND_SENDME, "Data1234");
  703. connection_edge_process_relay_cell(&cell, TO_CIRCUIT(circ), edgeconn,
  704. circ->cpath);
  705. ASSERT_UNCOUNTED_BW();
  706. /* Sendme on circuit with non-full window: counted */
  707. PACK_CELL(0, RELAY_COMMAND_SENDME, "");
  708. /* Recording a cell, the window is updated after decryption so off by one in
  709. * order to record and then we process it with the proper window. */
  710. circ->cpath->package_window = 901;
  711. sendme_record_cell_digest_on_circ(TO_CIRCUIT(circ), circ->cpath);
  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(TO_CIRCUIT(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. };