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