test_relaycell.c 40 KB

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